使用C和Win32,我想知道如何实现用于加载资源(纹理和VBO)的辅助OpenGL线程.
从我发现的,这应该用wglShareLists()来完成,但我不确定如何设置辅助线程:
我是否需要新的设备上下文或仅需要新的渲染上下文?
我需要调用哪些wgl函数?
您不需要新的上下文,因为您可以重用第一个上下文的相同设备上下文.顺便说一句,您可以指定另一个设备上下文,但根据您的平台,您应该注意它(在Windows上,设备上下文必须具有相同的像素格式),否则您可能无法在两个上下文之间共享对象
在主线程中创建两个上下文,第二个与第一个共享.然后,在主线程上使第一个为当前,而在辅助线程上使另一个为当前.请注意,您可以与任何渲染上下文共享:所有共享上下文按名称"查看"相同的对象,实际上它们共享一个对象名称空间.两个不同的对象名称空间(即两个非共享上下文)可以定义相同的对象(即纹理对象名称为1),但同一名称实际上指向不同的对象,具体取决于当前上下文.
由辅助线程创建的对象可以同时且一致地显示.但是,并非所有对象都可以跨上下文共享.请记住,有时会发生驱动程序支持意外对象的情况,有时会发生驱动程序无法正确支持预期对象的情况.
OpenGL正在成为面向对象的语言.您可以看到创建对象的特定模式:
(请注意,使用Gen例程创建的对象仅在绑定时才存在)
对象类可以是
我建议使用"运行时"测试,如下所示:
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));
}
Run Code Online (Sandbox Code Playgroud)
另一个建议是在CPU密集型的二级线程操作上运行,而不是直接影响绘图系统窗口缓冲区.一个很好的例子是着色器编译,因为编译在CPU端运行; 还要记住,驱动程序可能会异步操作,并且OpenGL实现可能会管理不同的操作.