PDA

View Full Version : Windows 7 and the need for contex deactivation



Toolmaker
09-09-2009, 04:34 AM
I'm currently working on making our OpenGL application Windows 7 compatible and getting rid of lots of legacy code, such us the use of Immediate Mode. While this all goes well, I'm currently unsure about the very need for calling wglMakeCurrent(NULL, NULL).

My colleague discovered that rendering on Windows 7(with DWM enabled) works fine as soon as we add a call to wglMakeCurrent(NULL, NULL) at the end of the render cycle. But this clashes at the moment a bit with how our code loads bitmaps and models during it's runtime. When we're loading a model and a redraw is forced by moving the progress window, this will result in a deactivation of the context, and thus failure of the creation of a vertex buffer(We work with rather large models, and require multiple VBOs to be created) and then a crash or hang.

Do we actually require the call to MakeCurrent(NULL, NULL) or is there something else we're missing? Everything does work fine under Vista after we removed the GDI calls.

Thanks

dukey
09-09-2009, 05:15 AM
how many threads are you trying to render from ?
If you just have 1 thread, and 1 GL window, u probably never need makeCurrent(NULL)

If you are trying to render from multiple threads
you should makeCurrent(NULL) before you switch thread
then use makeCurrent and set the context with the second thread

BionicBytes
09-09-2009, 10:46 AM
My application was written for single threading and i'm trying to altered it for use with multiple threads. The 'main' thread currently does everything but I want to sporn a new thread to render everything I need to an offscreen FBO. Only after the FBO is completely finished with, would I then composite the FBO texture onto the main GL window.
In this case, do I have to worry about wglShareLists or wglMakecurrent (nil) ?

Please advise, as I'm completely new to multi-threading!

dukey
09-10-2009, 10:11 AM
I think you can only render from 1 thread at a time in opengl. My advice is, just use one thread.

sammie381
09-10-2009, 02:15 PM
You don't have to explicitly call wglMakeCurrent( NULL, NULL ); when switching OpenGL threads.

I would use something like this at the start of your rendering code:


if( wglGetCurrentContext() != m_hRC) {
wglMakeCurrent( m_pDC->GetSafeHdc(), m_hRC );
}

BionicBytes
09-11-2009, 01:55 AM
Sammie381: what does m_pDC->GetSafeHdc do?


Does it create a handle to a device context?
eg. h_DC := GetDC(h_wnd);

So does each thread require it's own device context so we can share the rendering context between them?

sammie381
09-11-2009, 02:44 PM
Sorry, that's MFC code (a hDC). Let me correct myself. That code is for drawing between multiple windows under a single thread.
I don't think it is for multiple threads, at least in your case. You wouldn't want to interrupt your worker thread like that.

And I would think you would have to create a window for any OpenGL thread, even if it doesn't render anything to it.
Just make it invisible.

This Microsoft example mentions suspending other threads:
http://support.microsoft.com/kb/128122

You can switch the OpenGL context between threads, but you can't have a context active in two threads at once.
So, if you want your worker thread to finish without interruption, you will have to suspend all OpenGL activities in your main thread,
or just have some global flag that prevents you from making any gl calls.

And, although I have never tested this, but if you use wglShareLists(), anything you create in the worker thread,
FBOs, VBOs, etc.. should be available when you switch back to the main thread. That's the whole point, right?