OpenGL:用于加载资源的辅助线程? [英] OpenGL: secondary thread for loading resources?

查看:22
本文介绍了OpenGL:用于加载资源的辅助线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Working with C and Win32, I would like to know how to implement a secondary OpenGL thread for loading resources(textures and VBOs).

据我所知,这应该用 wglShareLists() 来完成,但我不确定如何设置辅助线程:

From what I found, this should be done with wglShareLists(), but I am unsure about how to set up the secondary thread:

我需要一个新的设备上下文还是只需要一个新的渲染上下文?

Do I need a new device context or only a new rendering context?

我需要调用哪些 wgl 函数?

What wgl functions do I need to call?

推荐答案

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

You don't need a new context because you can reuse the same device context of the first one. Btw, you can specify another device context, but depending on your platform you should take care about it (on Windows, device contextes must have the same pixel format), otherwise you could fail to share objects between two contextes

在主线程中创建两个上下文,第二个与第一个共享.然后,使第一个在主线程上成为当前,同时在次要线程上使另一个成为当前.请注意,您可以与任何渲染上下文共享:所有共享上下文都通过名称看到"同一个对象,实际上它们共享一个对象名称空间.两个不同的对象命名空间(即两个非共享上下文)可以定义同一个对象(即纹理对象名称为 1),但根据当前上下文,相同的名称实际上指向不同的对象.

Create both context in the main thread, the second one sharing with the first one. Then, make the first one current on the main thread, while making the other one current on the secondary thread. Note that you can share with any render context: all sharing contextes "see" the same object by its name, indeed they share an object name space. Two different object name spaces (i.e. two non-sharing contextes) can have defined the same object (i.e. texture object name is 1), but the same name actually points to different object depending on the current context.

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

Objects created by the secondary thread are visible concurrently and consistently. However, not all objects can be shared across contextes. Keep in mind that sometimes it happens that the driver supports unexpected objects, and other times it happens that driver doesn't support correctly an expected object.

OpenGL 正在成为一种面向对象的语言.您可以看到创建对象的某种模式:

OpenGL is becoming an object oriented language. You can see a certain pattern for creating objects:

  • 生成名称(GenTexturesGenBuffers)
  • 定义对象(BindTextureBindBuffer)
  • 对象存在(IsTextureIsShaderIsFramebuffer)
  • 删除名称(和对象)

(注意用Gen例程创建的对象只有在绑定时才存在)

(Note that an object created with Gen routines exists only when they are bound)

对象类可以是

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

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

I would suggest to use a "runtime" test, like the following:

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 实现可能会流水线化不同的操作.

Another suggestion would be to run on secondary thread operations that are CPU intensive, and not directly affecting drawing system windows buffers. A good example would be a shader compilation, since the compilation runs on CPU side; keep also in mind that the driver could async your operations, and that OpenGL implementations may pipeline different operations..

这篇关于OpenGL:用于加载资源的辅助线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆