Multithreading and OpenGL contexts

Started by
3 comments, last by rick_appleton 17 years, 5 months ago
In my current setup, I mainly have two threads running: a rendering thread, and a resource loading thread. In trying to create functions to load meshes, I've hit a brick wall. My rendering thread owns the OpenGL-context, however, when loading a mesh I need a vertex buffer and index buffer in the resource loading thread. I assume these buffers can only be allocated by the thread owning the OpenGL-context. So my questions are:
  • Is my assumption right that only the thread owning the OpenGL-context can allocate buffers? Or can I call glGenBuffers in the resource loading thread and use the object name in the rendering thread?
  • When I have a buffer, is it the rendering thread that must call lock() and unlock() on it?
  • After calling lock() and having a pointer to the buffer data, can only the rendering thread write to that memory?
  • And finally, my current plan is to load the vertex data in a seperate array, then copy that to a vertex buffer on the rendering thread. It sounds inefficient to me, but is there any other (better) way?
Advertisement
Load the data in one thread, when the model is needed for the first time have the rendering thread "create" it. Won't take but a ns and you're done and no issues. Seems to be the easiest solution for me.
you can only execute OpenGL functions in a thread which has a valid OpenGL context. Therefore if your rendering thread has the context any GL calls in another other thread will fail.
Vorax from Javagaming.org had multithreaded OpenGL engine, you might use search to find its limitations.
I see there's still a lot of mis-knowledge about this issue, so let me clear it up a bit (I've implemented a multithreaded OpenGL resource loader and I've run into the same issues, and solved them).

Quote:you can only execute OpenGL functions in a thread which has a valid OpenGL context. Therefore if your rendering thread has the context any GL calls in another other thread will fail.

While this is sort of true it's not accurate. Each thread has it's own current context. If you do not set the context in the second thread, the calls are likely to fail. However, if you create two contexts, and set one in each of the two threads just once (you don't need to swap between them, just set them from the correct thread) you should be ok.

Once the contexts have been created, you can call wglShareLists on the second one (After sharing, you set them to be current in either thread.) to share pretty much all objects between them. This includes textures, VBO, display lists. You can do anything with them in either thread, but I think you need to take care of multi-threading issues yourself, the driver generally doesn't (so you'll have to create your own locks on them). After calling glMapBuffer either thread should be able to write to the memory as it's been mapped into program memory space (not tested this).

a few threads discussing this matter:
a thread

my last post in the following thread is pretty much the most important one:
here

This topic is closed to new replies.

Advertisement