Creating OpenGL structures in a multithreaded program? Creating OpenGL structures in a multithreaded program? multithreading multithreading

Creating OpenGL structures in a multithreaded program?


The requirement for OpenGL is that the context created for rendering should be owned by single thread at any given point and the thread that owns context should make it current and then call any gl related function. If you do that without owning and making context current then you get segmentation faults. By default the context will be current for the main thread. So to make your program multi threaded you have two options.

  1. Create two contexts and share resources like texture objects VAOs between them.Advantage of this approach is you can refer in thread 2 to any VAO created in thread 1 and it wont crash.

    Thread_1:

    glrc1=wglCreateContext(dc);glrc2=wglCreateContext(dc);BOOL error=wglShareLists(glrc1, glrc2);if(error == FALSE){//Unable to share contexts so delete context and safe return }wglMakeCurrent(dc, glrc1);DoWork();

    Thread_2:

    wglMakeCurrent(dc, glrc2);DoWork();
  2. Other option is to make one context per thread and make it current when thread starts. Like following

    Thread_1:

    wglMakeCurrent(NULL, NULL);WaitForThread2(); OrDoSomeCPUJob();wglMakeCurrent(dc, glrc);

    Thread_2:

    wglMakeCurrent(dc, glrc);DoSome_GL_Work();wglMakeCurrent(NULL, NULL);

Hope this clears up the thing.


From what I have read OpenGL is as far away from being thread safe as a Giraffe is from being a dolphin.

Then you're misinformed. OpenGL is perfectly thread safe. You just have to keep in mind that OpenGL contexts act a bit like thread local storage. I.e. when you make a OpenGL context current, then this is localized to the thread that makes that call.

Also extended OpenGL function pointers may be specific to a OpenGL context (but not to a context binding). However OpenGL function loaders keep a thread→context cache. So when you call an extended OpenGL function (i.e. one that must be loaded at runtime) from a thread without a context bound, you'll likely end up calling an invalid function pointer and get a crash.

However despite being perfectly thread safe, OpenGL does not necessarily gain performance when being used multithreaded. OpenGL thread zygote contexts are very useful if you need to update texture and buffer object data from a worker thread, but you should be careful not to tough things that might be in use by the main rendering thread. In programs where I have to do this, the usual approach is, that the data generating thread is creating a pool of texture/buffer objects, updates the data in them and then "surrenders" ownership of the object to the render thread. Eventually the render thread does its thing with these objects and once its done it passes the ownership back to the update thread and takes the next object from its own pool that gets filled with what the data thread sends over.

What can I do do multi thread the program then?

Create zygote OpenGL contexts and configure them to share their texture and buffer objects with the other thread(s) by the mechanism of display list sharing. You can have an arbitrary number of OpenGL contexts in your program and each thread can have its very own context active (while the other threads use different contexts).