OpenGL on separate Threads

I’m having trouble implementing OpenGL on a separate thread. I’m able to draw just fine, but my main application thread freezes up until the GL thread terminates. I’m using Visual C++ 2005 with a managed thread and thread delegate. If I replace the OpenGL code with non-GL code, it runs just fine.
any ideas? Thanks, Rennie.

A rendering context can be current only within one single thread. With other words, you can’t make a RC current in one thread and issue rendering commadns for it in another one.

Thanks, Zengar. I have things set up to issue all GL related in the new thread. My problem is that the main application freezes up when the thread is running, which doesn’t happen with CPU-only related commands. Are you aware of problems with managed code threads and OpenGL? Should I use Win API unmanaged code for thead action?

“managed”? Is it even possible to know in what thread, or even context, such code runs in?

I have code with one visualization thread using OpenGL (it’s CPU-native code, what you call “unmanaged”), and one “main window/app” thread handling windows messages and stuff. The few things to look out for is:

  • If you suspect threading problems, wrap your GL-using code and assert that current ThreadId is the one you expect.

  • Keep the two threads (the one handling the window, and the one handling OpenGL) at the same priority, at least for the duration of SwapBuffers (I ended up writing code to switch GL-thread priority before and after SwapBuffers due too… let’s just say some IHV’s are possibly better at designing hardware than software :slight_smile: ).

  • You can often actually increase overall performance, while seriously reducing power consumption, by adding Sleep(n) (n >= 1) in the correct place. Just before SwapBuffers is one such place.

++luck;

With multi-threading OpenGL, it’s often the case that attempting to make a context current, that is current in another thread, will block until that other thread makes the context not current.

Thus, you can attempt to wglMakeCurrent(NULL, NULL) in your GL thread after calling wglSwapBuffers(), calling Thread.Yield(), and then wglMakeCurrent() the context again. This should make the main thread have a chance to do what it needs with the context.

Similarly, if the main thread does anything with the context, it should make sure to make no context current before returning from a message proc, to let the thread re-take the context.

Well, from what you describe, I belive that you still have a mistake somewhere in your code that leads to mixing of GL commands in different threads. How is your context created? Do you use Tao with GLUT or something else?

FYI: http://www.opengl.org/sdk/tools/GLIntercept/ has a option in the gliconfig.ini file to check for these threading issues:

Set ThreadChecking = True;

(or use the FullDebug Profile)

Wow, you guys really know your stuff! I been downloading simple tutorials on GL multithreading. I notice that they create the window in the main thread (or use the application main window) and pass the Window Handle and HDC to the GL thread, which creates the GL rendering context. As I have it, I’m creating a second child window in the GL thread. Could this be the problem? What code do you put in the main thread and what do you do in the GL thread for basic GL initialization and happy co-existence? Thanks to you gurus!

Well, your best bet is to use the main thread as the GL thread and create additional threads for other tasks: this way nothing can go wrong :slight_smile:

It is likely. Does the second thread have a message queue handler (the GetMessage/DispatchMessage loop)? Without that loop other threads & programs which attempt to communicate (for example because of the parent->child relation) with the window created by that thread will be blocked.

On Vista there is also problem with having 3d accelerated windows created by different threads within single window hierarchy.