SwapBuffers does not respect WS_CLIPCHILDREN

I want to be able to use GDI with my opengl program, sortof like directX lets you do.
I set off on a bit of a quest to find out how I could make my own version of swapbuffers that respects WS_CLIPCHILDREN so that I could use opengl and windows controls together without flickering. Here is what I’ve tried so far:

  1. use PFD_DRAW_TO_BITMAP and then BitBlt to draw it to the screen. Works, but is not hardware accelerated and therefore unacceptably slow.

  2. use a pbuffer, and then BitBlt from the pbuffer dc to the window dc. Doesn’t work.

  3. use a pbuffer and then use glReadPixels to copy the buffer contents to a DIB, then BitBlt to the window. A type of tripple-buffering, I guess. Works, has hardware acceleration but is WAAYY too slow because of glReadPixels. (glReadPixels takes 850 miliseconds for a 1024x1024 pbuffer!)

I also thought of intercepting all WM_PAINT, WM_NCPAINT, WM_ERASEBKGND messages and maybe handle them in a way that doesnt cause flicking, but actually I have no idea how to do that

That’s all I’ve come up with so far. All my “solutions” just don’t have good performance and I’m out of ideas. Has anyone got any other ideas that I can try?
Thanks for any help!

Originally posted by Melekor:
I want to be able to use GDI with my opengl program, sortof like directX lets you do.
I set off on a bit of a quest to find out how I could make my own version of swapbuffers that respects WS_CLIPCHILDREN so that I could use opengl and windows controls together without flickering.

Did you set PFD_SUPPORT_GDI in your pixelformat?

PFD_SUPPORT_GDI The buffer supports GDI drawing. This flag and PFD_DOUBLEBUFFER are mutually exclusive in the current generic implementation.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/opengl/ntopnglr_73jm.asp
Note that the incompatibility the MSDN refers to, is wrt the software implementation (Microsoft’s sofware renderer), hardware implementations should work just fine.
In win32 the ICD is in charge of clipping against other GDI windows, so mixing GDI with OpenGL should just work.

Have you tried setting WS_CLIPSIBLINGS?

WS_CLIPSIBLINGS
Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window.

http://msdn.microsoft.com/library/defaul…indowstyles.asp

I also thought of intercepting all WM_PAINT, WM_NCPAINT, WM_ERASEBKGND messages and maybe handle them in a way that doesnt cause flicking, but actually I have no idea how to do that

At least you have ot intercept WM_ERASEBKGND to avoid OpenGL flickering just by its own, otherwise GDI will erase the background area before calling your WM_PAINT, resulting in flickering against the background.

An application should return nonzero in response to WM_ERASEBKGND if it processes the message and erases the background; this indicates that no further erasing is required.

http://msdn.microsoft.com/library/defaul…_erasebkgnd.asp