这是一个很棒的功能,因为它允许我执行并行渲染线程。
从多个线程并行访问 GPU 是严重的性能杀手。不要这样做。 GPU 将在内部并行化任何渲染。你所做的任何其他事情,都是把木头扔进它的轮子里。
如果您想加快资源上传速度,请研究缓冲区对象和异步访问。但请避免同时在单独的线程中执行多个 OpenGL 上下文。
但由于我使用的是 CreateContextAttribs,因此我提供了请求特定 OpenGL 实现的可能性。因此,可能会发生某些上下文正在实现版本 3.2+,而另一个上下文正在实现版本 2.1。
实际上效果很好,但我怀疑这种操作方式隐藏了一些副作用。使用具有不同版本的上下文时可能出现的问题列表是什么?
这其实是一个非常好的问题。还有规格回答得很清楚:
1) Can different GL context versions share data?
PROPOSED: Yes, with restrictions as defined by the supported feature
sets. For example, program and shader objects cannot be shared with
OpenGL 1.x contexts, which do not support them.
NOTE: When the new object model is introduced, sharing must be
established at creation time, since the object handle namespace is
also shared. wglShareLists would therefore fail if either context
parameter to it were to be a context supporting the new object
model.
除此之外,我查询每个上下文版本实现的扩展,因为我认为不同的版本可以支持不同的扩展,这是对的吗?
事实上,查询每个上下文支持的扩展集是正确的做法。
那么函数指针呢?我必须为不同版本的每个上下文重新查询它们(实际上,指针会根据版本而变化)?
在 Windows 上,扩展函数指针与上下文相关联。做到这一点的明智方法是有一些
typedef struct OpenGLExtFunctions_S {
GLvoid (*glFoobarEXT)(GLenum, ...);
/* OpenGL function pointers */
} OpenGLExtFunctions;
/* currentContextFunction must be thread loacal since
contexts are active in one thread only */
__declspec(thread) OpenGLExtFunctions *currentContextFunctions;
#define glFoobarEXT (currentContextFunctions->glFoobarEXT);
#define ...
并包裹wglMakeCurrent
and wglMakeContextCurrent
使用一些辅助函数来设置currentContextFunctions
指向当前上下文之一的指针。像 GLEW 这样的扩展包装库会为您完成所有这些繁重的工作,因此您不必费心自己做这些工作。
在 X11/GLX 上,事情要简单得多:返回的函数指针glXGetProcAddress
所有上下文必须相同,因此无需切换它们。