Search code examples
c++winapiopengl

how can I create OpenGL context using Windows memory dc (c++)


In my Windows MFC application, in its View class I created an OpenGL context using View's DC:

HANDLE * hdc = GetDC()->m_hdc;
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
1, // Version of this structure
PFD_DRAW_TO_WINDOW | // Draw to window (not bitmap)
PFD_SUPPORT_OPENGL | // Support OpenGL calls
PFD_DOUBLEBUFFER, // Double -buffered mode
PFD_TYPE_RGBA, // RGBA Color mode
24, // Want 24bit color
0,0,0,0,0,0, // Not used to select mode
0,0, // Not used to select mode
0,0,0,0,0, // Not used to select mode
32, // Size of depth buffer
0, // Not used to select mode
0, // Not used to select mode
PFD_MAIN_PLANE, // Draw in main plane
0, // Not used to select mode
0,0,0 }; // Not used to select mode

// Choose a pixel format that best matches that described in pfd
nPixelFormat = ChoosePixelFormat(hdC, &pfd);
// Set the pixel format for the device context
assert(SetPixelFormat(hdC, nPixelFormat, &pfd));

HGLRC m_hrc = wglCreateContext(hdc);
assert(m_hrc);
wglMakeCurrent(m_hdc,m_hrc);

All the code above works all right, and I can do OpenGL drawings as expected.

But , What I need now is to change the DC to memory dc instead of window DC . To be exact, how can I use the 'hmemDC' bellow to create an OpenGL context like the way I did above with window DC:

CRect rct;
GetClientRect(&rct);
HDC hmemDC = CreateCompatibleDC(pDC->m_hDC);
HBITMAP hBmp = CreateCompatibleBitmap(pDC->m_hDC,rct.Width(),rct.Height());

with the same pixel format constructed above, I came across the "Invalid pixel format" error in calling wglCreateContext() , can not success in getting the correct OpenGL context.

I googled a lot , and tryed to change some of the values of pixel format, the result was the same.

Is it possible to create OpenGL context with Windows Memory DC? and if it is how should I do it?

Edit: This is why I need a bitmap ( or Memory DC ): I created a 2d map rendering library which uses OpenGL. The client want to use this library to render background map, and draw its own symbols on top of it . But, they prefer to use Windows GDI other than OpenGL to draw their symbols. So I thought if I can provide them with a bitmap or a Mmeory DC, they could to what they want. Any better solutions? Am I in the right direction? Or it is a total bad idea to provide such a 2d library in OpenGL backend.


Solution

  • This can't be done in a useful way.

    You can in principle render to a bitmap by using the PFD_DRAW_TO_BITMAP flag instead of PFD_DRAW_TO_WINDOW in the PIXELFORMATDESCRIPTOR.

    However, doing so will disable all hardware accelerated rendering. This will fall back to Microsoft's default OpenGL 1.1 implementation.

    If you want such acceleration and/or modern GL, you either need a window or some offscreen buffer like a pbuffer, which is available via the WGL_ARB_pbuffer extension. However, in modern GL, you are probably better off creating a window which is just never shown, and using a Framebuffer Object as the offscreen render target.

    In either case, you will have to copy the data back to the CPU, if you need it as some bitmap there.