PDA

View Full Version : Win 32 off screen rendering code



Marco Zuliani
04-18-2003, 07:31 PM
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

shinpaughp
04-18-2003, 07:37 PM
Look here (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnopen/html/msdn_gl6.asp) .

Marco Zuliani
04-18-2003, 07:57 PM
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

shinpaughp
04-18-2003, 08:12 PM
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

Carlos Portela
04-29-2003, 07:38 PM
Originally posted by Marco Zuliani:
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

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

Marco Zuliani
05-01-2003, 09:16 AM
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