PDA

View Full Version : problem in using multiple threads in openGL



DaedalusEH
06-09-2005, 06:48 AM
Hi,
I just want to use opengl in a multithreading application so that I can render say object1 in thread 0 and object2 in thread 1 in the same viewport/window. I tried using contexts but for some reason, the second thread was not rendering on screen. Or in some cases when I was running the code in QT environment i was getting a black screen.
The procedure that I followed was the following :

<-------C++ code------------------->
<initialising opengl context>
//empty context if not first
<...>
for(int i = 0; i < <threads_active>; i++)
context.push_back( wglCreateContext(wglGetCurrentDC()) ); //vector<HGLRC> context;

<...>
<in rendering function >

wglMakeCurrent(wglGetCurrentDC(),m_context[<thread_id>]);
<opengl rendering code ...>

<----------------C++ code-------------->
Does anyone knows what I am doing wrong? what should I do? are there any similar examples in the NET... or a book describing such a situation?

Thanks

DaedalusEH
06-09-2005, 08:23 AM
I am assumming in the post above that by calling the the context creation function twice (initialisation) will create two contexts with a different ID but with the same exactly opengl features, so that I can use them in 2 seperate threads , is that right ?.

zeckensack
06-10-2005, 05:13 AM
You should not attempt to use multiple GL contexts on the same window. A GL context is bound to a device context (or *nix equivalent) in some ways. While it is possible to remove a GL context from a device context, and reattach it later, this has a tendency to break with different contexts.
And anyway, trying to have two GL contexts attached to the same DC at the same time will never work at all. Just ask yourself what should happen if the two contexts are asked to swap buffers, or clear buffers. There's no sensible way to make this work, so it isn't allowed.

You could solve your issue by using separate child windows with one GL context for each.

Bonus info (possibly related):
A GL context can only be current to one thread at a time. You cannot "steal" a context from another thread, and you cannot "share" a context with another thread (you can share some objects, such as textures, display lists and VBOs though). Any attempt to do either of these things will be denied by wglMakeCurrent.

DaedalusEH
06-13-2005, 03:38 AM
So if I want to have n objects on the screen shared by 2 threads, would I have to have n child windows in the parent window, or just two child windows shared by the objects in each thread? Thanks for the reply .

T101
06-13-2005, 04:13 AM
But why would you even try this?
Since you say you want them in the same viewport, it's not going to speed up rendering, because it still has to go through one pipeline.

And even if the results were correct, you'd probably introduce a lot of state changes, which would slow down rendering instead of speeding it up.

DaedalusEH
06-14-2005, 12:05 AM
It is one pipeline, but what if the graphics card can process the data faster than the processor? (Processor being the bottleneck). You will still get a speed up in a decent graphics card. Even if the the graphics card is the bottleneck, it wont harm you, you will just wont get the speedup (or if the memory pipeline is not "fat" enough, to send that data).
The only problem right now is that I havent been able to do it, except when I am rendering the same viewport twice in different windows, which is not what I am looking for.
Thanks for the reply.

Overmind
06-14-2005, 12:15 AM
If the processor is the bottleneck, move some calculations to another thread, but keep the OpenGL commands in one thread. The alternative is that you synchronise your threads so that the context is only current in one of the threads, but that's going to be much harder. Either way you need to synchronise the threads manually.

There is no way to get two contexts for a single window (except pbuffers, but that's another story).

Of course I'm assuming your on a multiprozessor system, otherwise this won't help ;)