0
votes

I am trying to make 4 OpenGL viewports inside a CSplitterWnd, but am having some problems.

At first, I had flickering and drawing issues until I added the flag PFD_SUPPORT_GDI into the pixel format, which made everything work nicely together. But when I use PFD_SUPPORT_GDI, I am only able to get a 1.1 OpenGL context.

Is it possible to use PFD_SUPPORT_GDI with a version of OpenGL higher than 1.1 so that I can use VBOs? or is there another way to get OpenGL to work properly without PFD_SUPPORT_GDI?

The biggest problem with not having PFD_SUPPORT_GDI is that the splitter window separator wipes the viewport contents away when you drag over it..which does not happen while using the PFD_SUPPORT_GDI flag.

3

3 Answers

3
votes

PFD_SUPPORT_GDI means, you want to be able to draw using GDI calls, which will force you into using the software renderer.

Most of the time flicker issues, especially with MFC are due to not properly set/choosen WNDCLASS(EX) parameters. Most importantly CS_OWNDC flag should be set and the background brush should be NULL. Also you should overwrite the OnEraseBackground handler and implement a OnPaint handler, that reports a validated rect.

2
votes

PFD_SUPPORT_GDI means that you can do GDI drawing to the window. This forces a software OpenGL implementation, because you cannot use GDI drawing (which is software) with hardware-based OpenGL drawing.

So no, you cannot have both hardware OpenGL (or D3D) acceleration and GDI support for the same window. If you're having issues with what happens to the contents of such windows, that is something you should resolve in some other way. Perhaps you could simply redraw the view when its size is changed or something.

0
votes

I decided the best way to do this was to use a frame buffer. Handling OnEraseBackground() helped with the flicker, but the MFC still just doesn't want to play nice with OpenGL, so I had to go with a GDI solution.

Each viewport first gets drawn to it's own frame buffer, and then blitted to the appropriate window.

void FrameBuffer::Blit(HDC hDC, int width, int height)
{
    glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, blitBuffer);
    SetDIBitsToDevice(hDC, 0, 0, width, height, 0, 0, 0, height, blitBuffer, &blitInfo, DIB_RGB_COLORS);    
}

This solution doesn't seem to be making any visible impact on performance.