使用OpenTK/在单个窗口中使用多个OpenGL上下文的多个IGraphicsContext
我想做的是: 主要目标:一起使用SkiaSharep和OpenTK。渲染2D和3D 问题是:SkiaSharep弄乱了OpenGL的状态,所以如果不保存和恢复一些状态,我就不能在3D中使用它 旧的解决方案(OpenGL<4):我使用了GL.PushClientAttrib(ClientAttribMask.ClientAllAttribBits);+一些附加值(已保存/恢复) 现在我读到,这不是最好的解决方案所必需的,OpenGL4不再有GL.PushClientAttrib。通常的方法似乎是使用单独的OpenGL上下文 我们已经看到: 我没有使用GLControl,因为我没有使用WinForms。所以这并不是很有帮助。我尝试的是:使用OpenTK/在单个窗口中使用多个OpenGL上下文的多个IGraphicsContext,opengl,opentk,openglcontext,Opengl,Opentk,Openglcontext,我想做的是: 主要目标:一起使用SkiaSharep和OpenTK。渲染2D和3D 问题是:SkiaSharep弄乱了OpenGL的状态,所以如果不保存和恢复一些状态,我就不能在3D中使用它 旧的解决方案(OpenGL
internal class Program
{
public static void Main(string[] args)
{
new Program().Run();
}
private readonly GameWindow _gameWindow;
private IGraphicsContext _context2;
private GlObject _glObject;
private int _programId;
private GlObject _glObject2;
private int _programId2;
public Program()
{
_gameWindow = new GameWindow(800,600,
GraphicsMode.Default, "", GameWindowFlags.Default,
DisplayDevice.Default,
4, 2, GraphicsContextFlags.ForwardCompatible);
_gameWindow.Resize += OnResize;
_gameWindow.RenderFrame += OnRender;
_gameWindow.Load += OnLoad;
}
public void Run()
{
_gameWindow.Run();
}
private void OnLoad(object sender, EventArgs e)
{
_programId = ShaderFactory.CreateShaderProgram();
_glObject = new GlObject(new[]
{
new Vertex(new Vector4(-0.25f, 0.25f, 0.5f, 1f), Color4.Black),
new Vertex(new Vector4(0.0f, -0.25f, 0.5f, 1f), Color4.Black),
new Vertex(new Vector4(0.25f, 0.25f, 0.5f, 1f), Color4.Black),
});
_context2 = new GraphicsContext(GraphicsMode.Default, _gameWindow.WindowInfo, 4, 2,
GraphicsContextFlags.Default);
_context2.MakeCurrent(_gameWindow.WindowInfo);
_programId2 = ShaderFactory.CreateShaderProgram();
_glObject2 = new GlObject(new[]
{
new Vertex(new Vector4(-0.25f, 0.25f, 0.5f, 1f), Color4.Yellow),
new Vertex(new Vector4(0.0f, -0.25f, 0.5f, 1f), Color4.Yellow),
new Vertex(new Vector4(0.25f, 0.25f, 0.5f, 1f), Color4.Yellow),
});
_gameWindow.MakeCurrent();
}
private void OnRender(object sender, FrameEventArgs e)
{
_gameWindow.Context.MakeCurrent(_gameWindow.WindowInfo);
GL.Viewport(0, 0, _gameWindow.Width, _gameWindow.Height);
GL.ClearColor(0.3f,0.1f,0.1f,1);
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.UseProgram(_programId);
_glObject.Render();
GL.Flush();
_gameWindow.SwapBuffers();
// i tried different combinations here
// as i read GL.Clear will always clear the whole window
_context2.MakeCurrent(_gameWindow.WindowInfo);
GL.Viewport(10,10,100,100);
//GL.ClearColor(0f, 0.8f, 0.1f, 1);
//GL.Clear(ClearBufferMask.ColorBufferBit);
GL.UseProgram(_programId2);
_glObject2.Render();
GL.Flush();
_context2.SwapBuffers();
}
private void OnResize(object sender, EventArgs e)
{
var clientRect = _gameWindow.ClientRectangle;
GL.Viewport(0, 0, clientRect.Width, clientRect.Height);
}
}
顶点着色器:
#version 450 core
layout (location = 0) in vec4 position;
layout (location = 1) in vec4 color;
out vec4 vs_color;
void main(void)
{
gl_Position = position;
vs_color = color;
}
片段着色器:
#version 450 core
in vec4 vs_color;
out vec4 color;
void main(void)
{
color = vs_color;
}
当我同时使用两种上下文时,可以使用单个上下文,但发生的情况是:第一个上下文被渲染,但闪烁。根本看不到第二个三角形(据我所知,它应该在屏幕左下角可见)
您可以通过回答以下一个或多个问题来帮助我:
在尝试了更多的组合后,诀窍是:
仅对渲染中最后使用的上下文调用SwapBuffers(即使使用3个上下文)。然后将不会发生闪烁,并且渲染似乎工作正常。国家似乎彼此独立。我不明白为什么需要两个上下文。仅针对每个
对象。Render()
设置(如果更改)程序、缓冲区和视口。然后,在所有渲染之后,调用SwapBuffers()
,正如我在前面的问题中所写的:SkiaSharp会弄乱上下文的状态。我不确定是什么设置,但将其与普通GL调用结合使用将不起作用。