How to save a rendering to file
Several people have asked how to save an OpenGL rendering to file. Aside from
ALT-PRINTSCREEN, one quick and dirty way is simply to BitBlt the glCtl hDC to a Picturebox
and save it, but this can result in unwanted artifacts appearing in the image
such as drop-down menus or other windows which may overlay the gl window.
There are 2 ways to properly save a rendering:
1. Read the pixels from the frame buffer and covert them to a bitmap.
2. Render to an off-screen memory device context and save this dc as a bitmap.
1. Read the pixels from the frame buffer.
glReadPixels transfers the contents of a frame buffer to an array you define.
You must define a 4 byte alignment for Windows bitmaps, and then define the
origin and size of the pixels you wish to read.
glPixelStorei GL_UNPACK_ALIGNMENT, 4 ' Force 4-byte alignment
glPixelStorei GL_UNPACK_SKIP_ROWS, Y
glPixelStorei GL_UNPACK_SKIP_PIXELS, X
If X > 0 Or Y > 0 Then
glPixelStorei GL_UNPACK_ROW_LENGTH, viewport(2) 'selection
Else
glPixelStorei GL_UNPACK_ROW_LENGTH, 0 'full image
End If
Then you call gl to get the pixels:
glReadPixels X, Y, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels(0)
After swapping the R and B bytes, you create a standard Windows bitmap. The result
looks something like this:
2. Render to memory DC
The second method creates a second gl rendering context using a memory dc
in place of the Form or UserControl dc. The second rc must be set up exactly like
the first (the gCtl rc, or the rc of the Form you are rendering to). After the
second rc is created, you issue the same drawing commands as usual, then
write the dc bitmap to file. The only real problem is getting the state of the
second rc set the same as the first. The results are pretty much the same either way:
Other pixel operations
The sample allows the user to draw a selection rectangle and copy the subimage
within the rectangle. The pixels are stored in a buffer and can be 'pasted' to the
frame buffer using glDrawPixels.
The sample also illustrates the use of glCopyPixels and glZoom.
More information
OpenGL VI: Rendering on DIBs with PFD_DRAW_TO_BITMAP by Dale Rogerson
Download ReadPixels
ReadPixels.zip (~11K)
Please send suggestions, bug reports, and such to: