Win32 multiple OpenGL windows, one window fails
#1 Members - Reputation: 145
Posted 19 June 2012 - 10:09 AM
wglMakeCurrent(hdc, hglrc);
My problem is that, after switching the rendering toolkit from GDI to OpenGL, one window fails as the window is black and nothing is drawn inside the window. The failing window is unpredictable and can be the main window, or one of the auxiliary windows. This problem does not occur when GDI is not used. The only work when switching the rendering toolkit is to generate OpenGL display lists for the graphics objects (switching from GDI to OpenGL), or delete OpenGL display lists for the graphics objects (switching from OpenGL to GDI).
I've spent a couple of days trying to fix this issue but failed so far. Could someone kindly give me some hints, or give some possible reasons why nothing but a black background is drawn in the window. Thanks in advance.
#2 Members - Reputation: 3708
Posted 19 June 2012 - 10:29 AM
wglMakeCurrent sets the current target render context and only one context per thread can be active at any given time, The last activated OpenGL Window is most likely the one that is working for you.
The voices in my head may not be real, but they have some good ideas!
#3 Members - Reputation: 145
Posted 19 June 2012 - 11:34 AM
Thank you for your quick response Simon. I am sure I called wglMakeCurrent on WM_PAINT and WM_ACTIVATE. Note that the issue only occurs after switching from GDI to OpenGL, I suspect the device context or GL rendering context is corrupted. I also wonder what are the possible causes leading to a black GL window.You should call wglMakeCurrent whenever you're switching the target window for your rendering, (either on WM_PAINT or twice each frame depending on how your rendering is done)
wglMakeCurrent sets the current target render context and only one context per thread can be active at any given time, The last activated OpenGL Window is most likely the one that is working for you.
#4 Members - Reputation: 3708
Posted 19 June 2012 - 11:51 AM
Thank you for your quick response Simon. I am sure I called wglMakeCurrent on WM_PAINT and WM_ACTIVATE. Note that the issue only occurs after switching from GDI to OpenGL, I suspect the device context or GL rendering context is corrupted. I also wonder what are the possible causes leading to a black GL window.
You should call wglMakeCurrent whenever you're switching the target window for your rendering, (either on WM_PAINT or twice each frame depending on how your rendering is done)
wglMakeCurrent sets the current target render context and only one context per thread can be active at any given time, The last activated OpenGL Window is most likely the one that is working for you.
Are you doing all your rendering from WM_PAINT aswell then ?
The voices in my head may not be real, but they have some good ideas!
#6 Members - Reputation: 145
Posted 20 June 2012 - 09:03 AM
Edited by leonard2012, 20 June 2012 - 09:06 AM.
#7 Moderators - Reputation: 3966
Posted 20 June 2012 - 09:11 AM
In order for a new window to become 'current' the old window must first release its claim to being current (iirc you call wglMakeCurrent with null parameters); only then can the second window make itself current.
So, given two windows A & B the correct sequence is;
A::makeCurrent
A::do opengl operations
A::makeCurrent(null, null)
B::makeCurrent
B::do OpenGL operations
B::makeCurrent(null, null)
Make sure this is happening as its the most likely source of the problem.
#8 Members - Reputation: 145
Posted 20 June 2012 - 10:27 AM
I've gained some more insight into this issue though still fail to solve it. The latest debugging make me believe that some GDI functions might make the device context no longer supported by the rendering context. The MSDN on wglMakeCurrent function says:
The hdc parameter must refer to a drawing surface supported by OpenGL. It need not be the same hdc that was passed to wglCreateContext when hglrc was created, but it must be on the same device and have the same pixel format. GDI transformation and clipping in hdc are not supported by the rendering context. The current rendering context uses the hdc device context until the rendering context is no longer current.
This may match the error message of wglMakeCurrent (error code 2004, which means "the requested transformation operation is not supported").
I also found this issue has nothing to do with the auxiliary windows. When no auxiliary windows are created, the current rendering context (RC) remains the same (the RC of main window) even if wglMakeCurrent fails. So the rendering is sill OK. When auxiliary windows are created and shown, the current RC is changed to one of the RCs of auxiliary windows. So I end up with a black main window.
Edited by leonard2012, 20 June 2012 - 10:47 AM.
#9 Members - Reputation: 3708
Posted 21 June 2012 - 02:55 PM
Thank you for your help phantom.
I've gained some more insight into this issue though still fail to solve it. The latest debugging make me believe that some GDI functions might make the device context no longer supported by the rendering context. The MSDN on wglMakeCurrent function says:
The hdc parameter must refer to a drawing surface supported by OpenGL. It need not be the same hdc that was passed to wglCreateContext when hglrc was created, but it must be on the same device and have the same pixel format. GDI transformation and clipping in hdc are not supported by the rendering context. The current rendering context uses the hdc device context until the rendering context is no longer current.
This may match the error message of wglMakeCurrent (error code 2004, which means "the requested transformation operation is not supported").
I also found this issue has nothing to do with the auxiliary windows. When no auxiliary windows are created, the current rendering context (RC) remains the same (the RC of main window) even if wglMakeCurrent fails. So the rendering is sill OK. When auxiliary windows are created and shown, the current RC is changed to one of the RCs of auxiliary windows. So I end up with a black main window.
You could try using ChoosePixelFormat on the dc/rc when switching renderer http://msdn.microsoft.com/en-us/library/windows/desktop/dd318284%28v=vs.85%29.aspx to set an appropriate pixelformat, if that still doesn't work you could always destroy the window and create a new one.
The voices in my head may not be real, but they have some good ideas!






