/* $Id: pbdemo.c,v 1.1 2002/10/05 18:30:13 brianp Exp $ */ /* * This program demonstrates how to do "off-screen" rendering using * the GLX pixel buffer extension. * * Written by Brian Paul for the "OpenGL and Window System Integration" * course presented at SIGGRAPH '97. Updated on 5 October 2002. * * Usage: * pbuffers width height imgfile * Where: * width is the width, in pixels, of the image to generate. * height is the height, in pixels, of the image to generate. * imgfile is the name of the PPM image file to write. * * * This demo draws 3-D boxes with random orientation. A pbuffer with * a depth (Z) buffer is prefered but if such a pbuffer can't be created * we use a non-depth-buffered config. * * On machines such as the SGI Indigo you may have to reconfigure your * display/X server to enable pbuffers. Look in the /usr/gfx/ucode/MGRAS/vof/ * directory for display configurationswith the _pbuf suffix. Use * setmon -x to configure your X server and display for pbuffers. * * O2 systems seem to support pbuffers well. * * IR systems (at least 1RM systems) don't have single-buffered, RGBA, * Z-buffered pbuffer configs. BUT, they DO have DOUBLE-buffered, RGBA, * Z-buffered pbuffers. Note how we try four different fbconfig attribute * lists below! */ #include #include #include #include #include #include "pbutil.h" /* Some ugly global vars */ static GLXFBConfigSGIX gFBconfig = 0; static Display *gDpy = NULL; static int gScreen = 0; static GLXPbufferSGIX gPBuffer = 0; static int gWidth, gHeight; /* * Create the pbuffer and return a GLXPbufferSGIX handle. */ static GLXPbufferSGIX MakePbuffer( Display *dpy, int screen, int width, int height ) { #define NUM_FB_CONFIGS 4 char fbString[NUM_FB_CONFIGS][100] = { "Single Buffered, depth buffer", "Double Buffered, depth buffer", "Single Buffered, no depth buffer", "Double Buffered, no depth buffer" }; int fbAttribs[NUM_FB_CONFIGS][100] = { { /* Single buffered, with depth buffer */ GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX, GLX_DRAWABLE_TYPE_SGIX, GLX_PIXMAP_BIT_SGIX, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1, GLX_DOUBLEBUFFER, 0, GLX_STENCIL_SIZE, 0, None }, { /* Double buffered, with depth buffer */ GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX, GLX_DRAWABLE_TYPE_SGIX, GLX_PIXMAP_BIT_SGIX, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1, GLX_DOUBLEBUFFER, 1, GLX_STENCIL_SIZE, 0, None }, { /* Single bufferd, without depth buffer */ GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX, GLX_DRAWABLE_TYPE_SGIX, GLX_PIXMAP_BIT_SGIX, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 0, GLX_DOUBLEBUFFER, 0, GLX_STENCIL_SIZE, 0, None }, { /* Double bufferd, without depth buffer */ GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX, GLX_DRAWABLE_TYPE_SGIX, GLX_PIXMAP_BIT_SGIX, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 0, GLX_DOUBLEBUFFER, 1, GLX_STENCIL_SIZE, 0, None } }; int pbAttribs[] = { GLX_LARGEST_PBUFFER_SGIX, True, GLX_PRESERVED_CONTENTS_SGIX, False, None }; GLXFBConfigSGIX *fbConfigs; GLXPbufferSGIX pBuffer = None; int nConfigs; int i; int attempt; for (attempt=0; attempt x1) { tmp = x0; x0 = x1; x1 = tmp; } if (y0 > y1) { tmp = y0; y0 = y1; y1 = tmp; } if (z0 > z1) { tmp = z0; z0 = z1; z1 = tmp; } v[0][0] = v[1][0] = v[2][0] = v[3][0] = x0; v[4][0] = v[5][0] = v[6][0] = v[7][0] = x1; v[0][1] = v[1][1] = v[4][1] = v[5][1] = y0; v[2][1] = v[3][1] = v[6][1] = v[7][1] = y1; v[0][2] = v[3][2] = v[4][2] = v[7][2] = z0; v[1][2] = v[2][2] = v[5][2] = v[6][2] = z1; for (i = 0; i < 6; i++) { glBegin(type); glNormal3fv(&n[i][0]); glVertex3fv(&v[faces[i][0]][0]); glVertex3fv(&v[faces[i][1]][0]); glVertex3fv(&v[faces[i][2]][0]); glVertex3fv(&v[faces[i][3]][0]); glEnd(); } } /* Render a scene */ static void Render(void) { int NumBoxes = 100; int i; InitGL(); glClearColor(0.2, 0.2, 0.9, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); for (i=0;i