Some uses of off-screen rendering include:
Generaly, off-screen rendering is not a core part of OpenGL; it's provided by an OpenGL window system interface such as GLX or WGL. Some systems have more than one facility for off-screen rendering, each with its own advantages and disadvantages.
The following sections describe the off-screen rendering facilities for WGL, GLX and Mesa with an emphasis on portablity and performance trade-offs.
Pros:
CreateDIBSection.
A pixel format with the PFD_DRAW_TO_BITMAP, PFD_SUPPORT_OPENGL,
PFD_SUPPORT_GDI flags must be chosen.
After creating a WGL context and binding it, OpenGL rendering can
proceed.
Pros:
XOpenDisplay to open an X display connection.
glXChooseVisual.
XCreatePixmap specifying the
depth of the X visual.
glXCreateGLXPixmap.
GLXPixmap handle returned by glXCreateGLXPixmap
may be passed to glXMakeCurrent to bind an OpenGL rendering
context to the GLX pixmap.
Rendering into the GLX pixmap may then begin.
The contents of a GLX pixmap may be read back with glReadPixels
or XGetImage.
Pros:
With that in mind let us consider pbuffers in more detail.
The pbuffers extension name is GLX_SGIX_pbuffers.
Prerequisite to the pbuffers extension is the exerimental fbconfig extension
(GLX_SGIX_fbconfig).
The fbconfig extension was introduced for several reasons:
Pbuffer applications must test for both the GLX_SGIX_pbuffers and GLX_SGIX_fbconfig extensions. See the Using OpenGL Extensions document for details on extension testing. If either extension is not available the application should fall back to using GLX pixmaps.
The basic steps for creating a pbuffer are:
XOpenDisplay to open an X display connection.
GLXFBConfigSGIX handle by calling
glXChooseFBConfigSGIX
glXCreateGLXPbuffer
glXChooseFBConfigSGIX returns a sorted list of fbconfigs which
match your attribute list.
However, some or all of the fbconfigs may not be usable for making a
pbuffer.
glXCreateGLXPbuffer call may fail, generating an X
protocol error.
You must set up an X error handler to catch this error so your
program doesn't exit abnormally.
As an example, suppose you need a single-buffered RGB pbuffer with a depth
buffer.
glXChooseFBConfigSGIX may return a list of several fbconfig
candidates.
However, there may not be enough memory available in the frame buffer
for some or any of those fbconfigs.
There may be enough memory for the color buffer but not the depth
buffer, for example.
Or, it may not be possible to allocate a single buffered pbuffer; only
double buffered pbuffers may exist.
The best approach is a nested loop:
let fbAttribs = list of fbconfig attribute lists
foreach fbAttrib in fbAttribs do
let fbConfigs = list returned by glXChooseFBConfigSGIX(fbAttrib)
foreach fbConfig in fbConfigs do
let pBuffer = glXCreateGLXPbufferSGIX(fbConfig)
if pBuffer then
SUCCESS!
endif
endfor
endfor
The course notes CD-ROM includes sample pbuffer code in the pbuffer.trz
file.
The pbdemo.c program illustrates this approach.
See the MakePbuffer function.
The pbutil.c file contains several pbuffer utility functions.
The CreatePbuffer handles the X protocol error problem.
The pbinfo.c program is similar to glxinfo. It prints a list of fbconfigs available on your system and whether or not a pbuffer of that config can be created.
On SGI Impact systems, for example, if you look in the
/usr/gfx/ucode/MGRAS/vof/ directory you will find a list
of video output formats supported by the Impact architecture.
Look for ones with the _pbuf suffix.
Use the setmon -x utility to configure your X server
to use a pbuffer-enabled video format.
glDrawBuffer and
glReadBuffer functions.
Up to four auxiliary buffers named GL_AUX0, GL_AUX1, GL_AUX2,
and GL_AUX3 are available.
The actual number of auxiliary buffers available can be queried with
glGetIntegerv(GL_AUX_BUFFERS, numBuffers).
Pros:
Pros:
OpenGL and/or window systems limit the size of rendered imagery in several ways:
glViewport's width and height parameters are silently
clamped to an implementation-dependant limit.
These limits can be queried via glGetIntegerv with
the argument GL_MAX_VIEWPORT_DIMS.
Typical limits are 2048 by 2048 pixels.
Here is a modified excerpt of the trdemo1.c example program which demonstrates how to use the tr (tile rendering) library:
static void Display(void)
{
GLubyte *image;
TRcontext *tr;
/* allocate final image buffer */
image = malloc(WindowWidth * WindowHeight * 4 * sizeof(GLubyte));
if (!image) {
printf("Malloc failed!\n");
return;
}
/* Setup tiled rendering. Each tile is TILESIZE x TILESIZE pixels. */
tr = trNew();
trTileSize(tr, TILESIZE, TILESIZE);
trImageSize(tr, WindowWidth, WindowHeight);
trImageBuffer(tr, GL_RGBA, GL_UNSIGNED_BYTE, image);
if (Perspective)
trFrustum(tr, -1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
else
trOrtho(tr, -3.0, 3.0, -3.0, 3.0, -3.0, 3.0);
/* Draw tiles */
do {
trBeginTile(tr);
DrawScene();
} while (trEndTile(tr));
trDelete(tr);
/* 'image' buffer now contains the final image.
* You could now print it, write it to a file, etc.
*/
}
The basic steps are:
trNew.
trTileSize to specify the tile size.
trImageSize to specify the final image size.
trImageBuffer to specify where the final image is to
be stored.
trFrustum
or trOrtho.
trBeginTile and trEndTile functions
inside a loop which surrounds your scene drawing function until
trEndTile returns zero.
trDelete.
There is one caveat to this utility library: glRasterPos,
glDrawPixels and glBitmap may be troublesome.
The problem is that if glRasterPos specifies a coordinate
which falls outside the current viewport, the current raster position
becomes invalid.
If the current raster position is invalid subsequent calls to
glDrawPixels or glBitmap will have no consequence.
The solution to this problem is the trRasterPos3f function.
It works just like glRasterPos3f but doesn't suffer from
the invalid raster position problem.
See the trdemo1.c program for example usage.
The trdemo2.c example demonstrates how to generate very large image files without allocating a full-size image buffer.