Win 32 off screen rendering code

Hallo everybody.

I need to render an object offscreen (this will be part of a MEX file callable from matlab). Searching around the discussion forum I learned that when working with win32 it is necessary to define a “DIB context” (I don’t want to use pbuffers, since I would like to maintain at least the portability between machines with differnet video cards). Then I have to “tell” win32 to render the scene to this context. Unfortunately I have not been able to find any “ready-to-go” pieces of code. Since I am not familiar at all with windows programming is there anybody that can pass me some code so that I can structure my function as

// initalization of the DIB context
[ your code, pleaaaaase!!! ]

// enable state of open GL
glEnable(bla bla)

// my routines to render the scene
[ … ]

// read out the rendered image
glReadBuffer(GL_FRONT_LEFT);
glReadPixels(0, 0, camera->w, camera->h,
GL_RGB, GL_UNSIGNED_BYTE, (GLuint *)mxGetData(Iout));

Thanks a lot!
Marco

Look here .

Thanks shinpaughp

Unfortunately the paper you suggested me seems pretty intimidating (I have no experience with windows coding…), and the pieces of code are mostly C++ whereas I need to write C code only. I wonder if someone has some something simpler written in plain C.

Thanks,
Marco

It might be in C++, but you should be able to just extract most of it directly, with some minor translation/interpretation.

That’s the only sample I know of. And, I don’t think too many people are up right now, or not out partying on a Friday night.

Best bet if you don’t want to decipher the C++ is search google.com

Originally posted by Marco Zuliani:
[b]Thanks shinpaughp

Unfortunately the paper you suggested me seems pretty intimidating (I have no experience with windows coding…), and the pieces of code are mostly C++ whereas I need to write C code only. I wonder if someone has some something simpler written in plain C.

Thanks,
Marco[/b]

Yes, that old help page is obfuscated, and even uses 256-color mode. Here’s quick info and code examples on rendering offscreen with full color on Win2k/XP:

To be able to use OpenGL commands on a Windows image, you need to create the image as a DIB as follows:


hDc = GetDC( NULL );
memset( &g_BitmapInfo, 0, sizeof(BITMAPINFO) );
g_BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
g_BitmapInfo.bmiHeader.biWidth = g_cxImage;
g_BitmapInfo.bmiHeader.biHeight = g_cyImage;
g_BitmapInfo.bmiHeader.biPlanes = 1;
g_BitmapInfo.bmiHeader.biBitCount = 24;
g_BitmapInfo.bmiHeader.biCompression = BI_RGB;
g_hBitmapImage = CreateDIBSection( hDc, &g_BitmapInfo, DIB_RGB_COLORS,
(void **)(&g_pBitmapBits), NULL, 0 );
ReleaseDC( NULL, hDc );


Variables with the “g_” prefix are global, defined in the program’s main thread. See the compiler help for proper types. The code above creates the DIB. Now we’re ready to draw on it with a memory device context. First create the memory device context and select the DIB into it:


hDc = CreateCompatibleDC( NULL );
hBitmapPrev = (HBITMAP)SelectObject( hDc, g_hBitmapImage );


Next, set up the pixel format. This code snippet shows important format descriptor settings:


pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cRedBits = 8;
pfd.cGreenBits = 8;
pfd.cBlueBits = 8;
pfd.cDepthBits = 16;


After using ChoosePixelFormat() and SetPixelFormat() you’re ready to render:


hRenderContext = wglCreateContext( hDc );
wglMakeCurrent( hDc, hRenderContext );

// OpenGL commands go here . . .

wglMakeCurrent( hDc, NULL );
wglDeleteContext( hRenderContext );

SelectObject( hDc, hBitmapPrev ); // Unselect the DIB from hDc
DeleteDC( hDc ); // Delete the Memory Device Context


Implement your OpenGL commands at the comment placeholder.

You can now use the DIB as a regular Windows bitmap.

For example, you can BitBlt it to the screen in a WM_PAINT handler as follows:


hdcMem = CreateCompatibleDC( hDc );
hBitmapPrev = (HBITMAP)SelectObject( hdcMem, g_hBitmapImage );
BitBlt( hDc, 0, 0, g_cxImage, g_cyImage,
hdcMem, 0, 0, SRCCOPY );
SelectObject( hdcMem, hBitmapPrev );
DeleteDC( hdcMem );


Finally, before your program ends, destroy the DIB:


DeleteObject( g_hBitmapImage );


Carlos Portela

Carlos, the precious pieces of code that you send me address and (hopefully) will solve exactly my problem. I need to use OpenGl inside MEX files (externals DLLs which can be called from Matlab). I’ll try your code as soon as I’ll have some time and I will post the results on this forum.

Thanks again!
Marco