OpenGL:用于加载资源的辅助线程?

时间:2011-11-14 01:21:18

标签: c winapi opengl

使用C和Win32,我想知道如何实现用于加载资源(纹理和VBO)的辅助OpenGL线程。

从我发现的,这应该用wglShareLists()完成,但我不确定如何设置辅助线程:

我是否需要新设备上下文或仅需要新的渲染上下文?

我需要调用哪些wgl函数?

3 个答案:

答案 0 :(得分:7)

您不需要新的上下文,因为您可以重用第一个上下文的相同设备上下文。顺便说一句,您可以指定另一个设备上下文,但根据您的平台,您应该注意它(在Windows上,设备上下文必须具有相同的像素格式),否则您可能无法在两个上下文之间共享对象

在主线程中创建两个上下文,第二个与第一个共享。然后,在主线程上使第一个为当前,而在辅助线程上使另一个为当前。 请注意,您可以与任何渲染上下文共享:所有共享上下文按名称“查看”相同的对象,实际上它们共享对象名称空间。两个不同的对象名称空间(即两个非共享上下文)可以定义相同的对象(即纹理对象名称为1),但同一名称实际上指向不同的对象,具体取决于当前上下文。

辅助线程创建的对象可以同时且一致地显示。但是,并非所有对象都可以跨上下文共享。请记住,有时会发生驱动程序支持意外对象的情况,有时会发生驱动程序无法正确支持预期对象的情况。

OpenGL正在成为面向对象的语言。您可以看到创建对象的特定模式:

  • 生成名称( GenTextures GenBuffers
  • 定义对象( BindTexture BindBuffer
  • 对象存在( IsTexture IsShader IsFramebuffer
  • 删除名称(和对象)

(请注意,使用 Gen 例程创建的对象仅在绑定时才存在)

对象类可以是

  • 显示列表
  • 纹理对象
  • 缓冲对象
  • 着色器对象和程序对象
  • Renderbuffer对象
  • 帧缓冲对象
  • 查询对象
  • 同步对象
  • 转换反馈对象

我建议使用“运行时”测试,如下所示:

private bool TestSharingObject(RenderContext rContextShare)
{
    uint texture = 0;

    // rContextShader is a context sharing with this RenderCOntext

    this.MakeCurrent(true);

    if (Caps.TextureObject.Supported == true) {
        // Generate texture name
        Gl.GenTextures(1, out texture);
        // Ensure existing texture object
        Gl.BindTexture(Gl.TEXTURE_2D, texture);
        Gl.BindTexture(Gl.TEXTURE_2D, 0);
        // Self test
        if (Gl.IsTexture(texture) == false)
            throw new NotSupportedException();
    }

    // Make current sharing context
    rContextShare.MakeCurrent(true);

    return ((texture != 0) && (Gl.IsTexture(texture) == true));
}

另一个建议是在CPU密集型的辅助线程操作上运行,而不是直接影响绘图系统窗口缓冲区。一个很好的例子是着色器编译,因为编译在CPU端运行;还要记住,驱动程序可以异步操作,OpenGL实现可以管理不同的操作..

答案 1 :(得分:1)

然后在辅助线程中加载资源,然后将它们的所有权传递回主要用于GL调用。

在GL上下文之间共享“列表”应该工作。在主线程上执行所有GL调用 工作:)

答案 2 :(得分:0)

它工作!,只有当wglShareLists由所有工作线程的主线程完成时。 使用消息映射,传递渲染上下文的引用并使主线程创建渲染上下文,仅使用主线程的wglShareLists。然后使用主线程创建的呈现上下文在工作线程上调用wglMakeCurrent。在渲染上下文上执行任何gl操作之前,必须调用wglShareLists。这是由于对参数hglrc2的要求(OpenGL渲染上下文与hglrc1共享显示列表),在调用wglShareLists时它不应包含任何现有的显示列表。