It is a great feature, since it allow me to execute parallel rendering threads.
Accessing the GPU from multiple threads in parallel is a serious performance killer. Don't do it. The GPU will parallelize any rendering internally. Anything else you do, is throwing logs into its wheels.
If you want to speed up asset uploads, look into buffer objects and asynchronous access. But stay away from doing multiple OpenGL contexts in separate threads at the same time.
But since I'm using CreateContextAttribs, I offer the possibility to request a specific OpenGL implementation. So, it can happen the some context is implementing version 3.2+ while the other is implementing version 2.1.
Actually works quite fine, but I suspect that this modus operandi hides some side effect. What would be a list of problems which can occour while using contextes having different versions?
This is actually a very good question. And the specification answers it clearly:
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.
Beyond this, I query the implemented extentions for each context version, since I suppose that different versions can support different extension, is this right?
Indeed querying the set of supported extensions for each context is the right thing to do.
And what about function pointers? I have to requery them for each context with different version (indeed, pointers changes depending on versions)?
On Windows extension function pointers are tied to the context. The sane way to do this is having some
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 ...
And wrap wglMakeCurrent
and wglMakeContextCurrent
with some helper function that sets the currentContextFunctions
pointer to the one of the context being made current. Extension wrapper libraries like GLEW do all this grunt work for you, so you don't have to bother doing it yourself.
On X11/GLX things are much simpler: The function pointers returned by glXGetProcAddress
must be the same for all contexts, so no need to switch them.