OpenGL multi-threading problems.

Started by
5 comments, last by blueshogun96 13 years, 3 months ago
Right now, I'm dealing with a fairly complex threading model for my application and I can't get OpenGL to work across multiple threads to save my life. Before I go any further, I should take a moment to explain how my threading structure works and why it's absolutely necessary.

My applocation requires 3 threads which are executed from a .dll and not the .exe file itself. Thread #1 is started when the .dll is loaded and handles all of the Win32 event handling as well as window creation within it. Then there are two more threads that have to be running and they are created within thread #1. The first thread does not require OpenGL to be initialized, but the remainig two threads do. Thread #2 handles rendering and drawing while thread #3 handles updates to the screen (calls SwapBuffers when necessary).

Now, before I go any further, I'd better explain why this is necessary to begin with. A normal game does not require this type of functionality and I wouldn't recommend it either, but what I'm doing is writing an x86 VM (Virtual Machine) that uses OpenGL for graphics rendering. The method I'm using for this VM is direct code execution and some basic MMU hacking for the hardware read/writes and privileged code. How I do that is beyond the scope of this thread, but I should still explain why the other threads are necessary. Thread #2 in detail executes the code, catches exceptions and emulates them manually and if gfx hardware triggers rendering, do that. Thread #3 acts as my VBlank emulation routine. When VBlank is done, then refresh the screen. I honestly couldn't think of a better way to organize the whole thing, and it doesn't seem like it's going to be any simpler than this.

So, my question is, how do I get OpenGL working in the two threads that were spawned from another thread? The context switching code appears to work fine in other situation, but on this one, it never works no matter what I do. I really hope I won't be forced to use Direct3D instead. This sucks. Any ideas? Thanks.
Advertisement
How do you do it now, and what exactly isn't working?
Does the window stay black, or does it crash?
The documentation for SwapBuffers says With multithread applications, flush the drawing commands in any other threads drawing to the same window before calling SwapBuffers.
Are you synchronizing the swap between the two threads, or do you want the swapping thread to just show whatever is in the back-buffer right now, even if the other thread is busy drawing to it?
Initialization doesn't work. I can't create a new RC (rendering context) or set a rendering context if I do manage to get a valid one.
What error code do you get from GetLastError, both from wglCreateContext and wglMakeCurrent (if those are the functions that fail)?
Maybe this can help :

http://www.equalizergraphics.com/documentation/parallelOpenGLFAQ.html

In short, it says you can't manage one rendering context from multiple threads in openGL. I believe ths is what you're trying to do.
Sure you can manage.
You just need to call wglMakeCurrent(rc, glrc), then do your gl calls and at the end of your render function, wglMakeCurrent(NULL, NULL).
You also need to check on the other thread. Is the other thread using the context?

It will drag down performance.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
I haven't checked GetLastError yet. I'm away from my computer, so I'll get back to you with that.

Quote:Original post by V-man
Sure you can manage.
You just need to call wglMakeCurrent(rc, glrc), then do your gl calls and at the end of your render function, wglMakeCurrent(NULL, NULL).
You also need to check on the other thread. Is the other thread using the context?

It will drag down performance.


The problem is creating and/or setting the context to begin with. That's what's killing me.

So does this mean I'll have to switch to Direct3D?

This topic is closed to new replies.

Advertisement