使用OpenTK/在单个窗口中使用多个OpenGL上下文的多个IGraphicsContext

使用OpenTK/在单个窗口中使用多个OpenGL上下文的多个IGraphicsContext,opengl,opentk,openglcontext,Opengl,Opentk,Openglcontext,我想做的是: 主要目标:一起使用SkiaSharep和OpenTK。渲染2D和3D 问题是:SkiaSharep弄乱了OpenGL的状态,所以如果不保存和恢复一些状态,我就不能在3D中使用它 旧的解决方案(OpenGL

我想做的是:

主要目标:一起使用SkiaSharep和OpenTK。渲染2D和3D

问题是:SkiaSharep弄乱了OpenGL的状态,所以如果不保存和恢复一些状态,我就不能在3D中使用它

旧的解决方案(OpenGL<4):我使用了GL.PushClientAttrib(ClientAttribMask.ClientAllAttribBits);+一些附加值(已保存/恢复)

现在我读到,这不是最好的解决方案所必需的,OpenGL4不再有GL.PushClientAttrib。通常的方法似乎是使用单独的OpenGL上下文

我们已经看到:

我没有使用GLControl,因为我没有使用WinForms。所以这并不是很有帮助。我尝试的是:

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;
}
当我同时使用两种上下文时,可以使用单个上下文,但发生的情况是:第一个上下文被渲染,但闪烁。根本看不到第二个三角形(据我所知,它应该在屏幕左下角可见)

您可以通过回答以下一个或多个问题来帮助我:

  • 是否有其他方法恢复原始上下文
  • 有没有另一种方法可以在屏幕的某一部分上使用硬件加速进行渲染,理想情况下可以为特定区域指定OpenGL状态
  • 如何获得以上解决方案以我想要的方式工作(没有闪烁,但窗口较小部分内的屏幕较小)

  • 在尝试了更多的组合后,诀窍是:


    仅对渲染中最后使用的上下文调用SwapBuffers(即使使用3个上下文)。然后将不会发生闪烁,并且渲染似乎工作正常。国家似乎彼此独立。

    我不明白为什么需要两个上下文。仅针对每个
    对象。Render()
    设置(如果更改)程序、缓冲区和视口。然后,在所有渲染之后,调用
    SwapBuffers()
    ,正如我在前面的问题中所写的:SkiaSharp会弄乱上下文的状态。我不确定是什么设置,但将其与普通GL调用结合使用将不起作用。