PDA

View Full Version : OpenGL control persists on screen after closing the WinForm in C++/CLI application



Devdept2
08-31-2012, 08:10 AM
I have a C++/CLI WinForm MDI application, with a main MDI WinForm container that opens some child Forms that contain my OpenGL .Net control.

On some NVidia cards (Quadro 600, Quadro 1000M, Geforce GT 240M) it happens that when a child Form is closed, the OpenGL area quite often persists on screen and resizing the container or moving it does not make it go away.
Creating a new Child form makes it go away, though.

How can this be possible?
The Dispose() of my OpenGL control (which takes care of disposing the rendeing context and all my other graphics resources) is correctly called when the Child form is closed.

I created a similar application using C# instead of C++/CLI and it doesn't have this problem.
Also, as I mentioned, the problem happens only on some NVidia cards (Quadro FX 350M is fine, for instance, and all the ATI cards I tested are fine too).

Any idea?

Devdept2
09-04-2012, 04:57 AM
Does anybody have an idea of the reason or how to fix it?

V-man
09-04-2012, 05:38 AM
Sounds like the driver is not aware that the MDI window and the context have been destroyed. Destroy your GL context when you get the WM_CLOSE message, not WM_DESTROY.
http://www.opengl.org/wiki/Platform_specifics:_Windows#When_do_I_destroy_the_ GL_context.3F

Devdept2
09-06-2012, 12:52 AM
Hi, I tried deleting my OpenGL control (which causes the destruction of the graphics context) in the OnClosing() method of the child form, as suggested by that page, but the problem is still there :(

Coconut
09-06-2012, 05:56 AM
Do you create your owned DC or window explicitly? You want to delete those too.

remdul
09-06-2012, 06:29 AM
From your description it seems the frame buffer contents is left in the client area (aka 'garbage')? Did you try refreshing/redrawing the window client area after GL destruction?

If none of that works, I guess as workaround you could pass the desired window background color to glClearColor() and call call glClear() before you destroy the GL context.

V-man
09-06-2012, 09:46 AM
Do you create your owned DC or window explicitly? You want to delete those too.

True. You need to create your own DC for the MDI window and have it hanging around until the window is closed.
Also, http://www.opengl.org/wiki/Platform_specifics:_Windows#What_should_I_do_befor e_the_window_is_created.3F

Devdept2
09-07-2012, 01:11 AM
I do not create the DC explicitly, I get it from the control:


wnd = control.Handle;
hdc = Windows.GetDC(wnd);
...
hrc = wglCreateContext(hdc);


Then I Delete the graphics context and release the DC in the Dispose:


public void Dispose()
{
// make this not current wglMakeCurrent(hDC, null);
wglMakeCurrent(hdc, IntPtr.Zero);

if (hrc != IntPtr.Zero)
wglDeleteContext(hrc);

if (hdc != IntPtr.Zero)
Windows.ReleaseDC(wnd, hdc);

hrc = IntPtr.Zero;
hdc = IntPtr.Zero;
}



Also, it doesn't seem to be just garbage, because if I resize the container form so as to cut out my "ghost" viewport, the "ghost" remains and even goes outside the boundaries of the control!Only creating a new child form makes it go away.
And this only happens with some NVidia cards, with ATI cards it's fine.