diff options
| -rw-r--r-- | progs/xdemos/pbdemo.c | 477 | ||||
| -rw-r--r-- | progs/xdemos/pbinfo.c | 133 | ||||
| -rw-r--r-- | progs/xdemos/pbutil.c | 230 | ||||
| -rw-r--r-- | progs/xdemos/pbutil.h | 38 | 
4 files changed, 878 insertions, 0 deletions
| diff --git a/progs/xdemos/pbdemo.c b/progs/xdemos/pbdemo.c new file mode 100644 index 0000000000..611e7e594f --- /dev/null +++ b/progs/xdemos/pbdemo.c @@ -0,0 +1,477 @@ +/* $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 <vof> 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 <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <X11/Xlib.h> +#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<NUM_FB_CONFIGS; attempt++) { + +      /* Get list of possible frame buffer configurations */ +      fbConfigs = glXChooseFBConfigSGIX(dpy, screen, fbAttribs[attempt], &nConfigs); +      if (nConfigs==0 || !fbConfigs) { +         printf("Error: glxChooseFBConfigSGIX failed\n"); +         XCloseDisplay(dpy); +         return 0; +      } + +#ifdef DEBUG +      for (i=0;i<nConfigs;i++) { +         printf("Config %d\n", i); +         PrintFBConfigInfo(dpy, fbConfigs[i], 0); +      } +#endif + +      /* Create the pbuffer using first fbConfig in the list that works. */ +      for (i=0;i<nConfigs;i++) { +         pBuffer = CreatePbuffer(dpy, fbConfigs[i], width, height, pbAttribs); +         if (pBuffer) { +            gFBconfig = fbConfigs[i]; +            gWidth = width; +            gHeight = height; +            break; +         } +      } + +      if (pBuffer!=None) { +         break; +      } +   } + +   if (pBuffer) { +      printf("Using: %s\n", fbString[attempt]); +   } + +   XFree(fbConfigs); + +   return pBuffer; +#undef NUM_FB_CONFIGS +} + + + +/* + * Do all the X / GLX setup stuff. + */ +static int +Setup(int width, int height) +{ +#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer) +   XVisualInfo *visInfo; +   GLXContext glCtx; + +   /* Open the X display */ +   gDpy = XOpenDisplay(NULL); +   if (!gDpy) { +      printf("Error: couldn't open default X display.\n"); +      return 0; +   } + +   /* Get default screen */ +   gScreen = DefaultScreen(gDpy); + +   /* Test that pbuffers are available */ +   if (!QueryPbuffers(gDpy, gScreen)) { +      printf("Error: pbuffers not available on this screen\n"); +      XCloseDisplay(gDpy); +      return 0; +   } + +   /* Create Pbuffer */ +   gPBuffer = MakePbuffer( gDpy, gScreen, width, height ); +   if (gPBuffer==None) { +      printf("Error: couldn't create pbuffer\n"); +      XCloseDisplay(gDpy); +      return 0; +   } + +   /* Get corresponding XVisualInfo */ +   visInfo = glXGetVisualFromFBConfigSGIX(gDpy, gFBconfig); +   if (!visInfo) { +      printf("Error: can't get XVisualInfo from FBconfig\n"); +      XCloseDisplay(gDpy); +      return 0; +   } + +   /* Create GLX context */ +   glCtx = glXCreateContext(gDpy, visInfo, NULL, True); +   if (!glCtx) { +      /* try indirect */ +      glCtx = glXCreateContext(gDpy, visInfo, NULL, False); +      if (!glCtx) { +         printf("Error: Couldn't create GLXContext\n"); +         XFree(visInfo); +         XCloseDisplay(gDpy); +         return 0; +      } +      else { +         printf("Warning: using indirect GLXContext\n"); +      } +   } + +   /* Bind context to pbuffer */ +   if (!glXMakeCurrent(gDpy, gPBuffer, glCtx)) { +      printf("Error: glXMakeCurrent failed\n"); +      XFree(visInfo); +      XCloseDisplay(gDpy); +      return 0; +   } + +   return 1;  /* Success!! */ +#else +   printf("Error: GLX_SGIX_fbconfig and/or GLX_SGIX_pbuffer extensions not" +                  " available at compile-time.\n"); +   return 0; +#endif +} + + + +/* One-time GL setup */ +static void +InitGL(void) +{ +   static GLfloat pos[4] = {0.0, 0.0, 10.0, 0.0}; +   glEnable(GL_LIGHTING); +   glEnable(GL_LIGHT0); +   glLightfv(GL_LIGHT0, GL_POSITION, pos); +   glEnable(GL_NORMALIZE); +   glEnable(GL_DEPTH_TEST); +   glEnable(GL_CULL_FACE); + +   glViewport(0, 0, gWidth, gHeight); +   glMatrixMode( GL_PROJECTION ); +   glLoadIdentity(); +   glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 ); +   glMatrixMode( GL_MODELVIEW ); +   glLoadIdentity(); +   glTranslatef( 0.0, 0.0, -15.0 ); + +} + + +/* Return random float in [0,1] */ +static float +Random(void) +{ +   int i = rand(); +   return (float) (i % 1000) / 1000.0; +} + + +static void +RandomColor(void) +{ +   GLfloat c[4]; +   c[0] = Random(); +   c[1] = Random(); +   c[2] = Random(); +   c[3] = 1.0; +   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, c); +} + + +/* This function borrowed from Mark Kilgard's GLUT */ +static void +drawBox(GLfloat x0, GLfloat x1, GLfloat y0, GLfloat y1, +  GLfloat z0, GLfloat z1, GLenum type) +{ +  static GLfloat n[6][3] = +  { +    {-1.0, 0.0, 0.0}, +    {0.0, 1.0, 0.0}, +    {1.0, 0.0, 0.0}, +    {0.0, -1.0, 0.0}, +    {0.0, 0.0, 1.0}, +    {0.0, 0.0, -1.0} +  }; +  static GLint faces[6][4] = +  { +    {0, 1, 2, 3}, +    {3, 2, 6, 7}, +    {7, 6, 5, 4}, +    {4, 5, 1, 0}, +    {5, 6, 2, 1}, +    {7, 4, 0, 3} +  }; +  GLfloat v[8][3], tmp; +  GLint i; + +  if (x0 > 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<NumBoxes;i++) { +      float tx = -2.0 + 4.0 * Random(); +      float ty = -2.0 + 4.0 * Random(); +      float tz =  4.0 - 16.0 * Random(); +      float sx = 0.1 + Random() * 0.4; +      float sy = 0.1 + Random() * 0.4; +      float sz = 0.1 + Random() * 0.4; +      float rx = Random(); +      float ry = Random(); +      float rz = Random(); +      float ra = Random() * 360.0; +      glPushMatrix(); +      glTranslatef(tx, ty, tz); +      glRotatef(ra, rx, ry, rz); +      glScalef(sx, sy, sz); +      RandomColor(); +      drawBox(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, GL_POLYGON); +      glPopMatrix(); +   } + +   glFinish(); +} + + + +static void +WriteFile(const char *filename) +{ +   FILE *f; +   GLubyte *image; +   int i; + +   image = malloc(gWidth * gHeight * 3 * sizeof(GLubyte)); +   if (!image) { +      printf("Error: couldn't allocate image buffer\n"); +      return; +   } + +   glPixelStorei(GL_PACK_ALIGNMENT, 1); +   glReadPixels(0, 0, gWidth, gHeight, GL_RGB, GL_UNSIGNED_BYTE, image); + +   f = fopen(filename, "w"); +   if (!f) { +      printf("Couldn't open image file: %s\n", filename); +      return; +   } +   fprintf(f,"P6\n"); +   fprintf(f,"# ppm-file created by %s\n", "trdemo2"); +   fprintf(f,"%i %i\n", gWidth, gHeight); +   fprintf(f,"255\n"); +   fclose(f); +   f = fopen(filename, "ab");  /* now append binary data */ +   if (!f) { +      printf("Couldn't append to image file: %s\n", filename); +      return; +   } + +   for (i=0;i<gHeight;i++) { +      GLubyte *rowPtr; +      /* Remember, OpenGL images are bottom to top.  Have to reverse. */ +      rowPtr = image + (gHeight-1-i) * gWidth*3; +      fwrite(rowPtr, 1, gWidth*3, f); +   } + +   fclose(f); +   free(image); + +   printf("Wrote %d by %d image file: %s\n", gWidth, gHeight, filename); +} + + + +/* + * Print message describing command line parameters. + */ +static void +Usage(const char *appName) +{ +   printf("Usage:\n"); +   printf("  %s width height imgfile\n", appName); +   printf("Where imgfile is a ppm file\n"); +} + + + +int +main(int argc, char *argv[]) +{ +   if (argc!=4) { +      Usage(argv[0]); +   } +   else { +      int width = atoi(argv[1]); +      int height = atoi(argv[2]); +      char *fileName = argv[3]; +      if (width<=0) { +         printf("Error: width parameter must be at least 1.\n"); +         return 1; +      } +      if (height<=0) { +         printf("Error: height parameter must be at least 1.\n"); +         return 1; +      } +      if (!Setup(width, height)) { +         return 1; +      } +      Render(); +      WriteFile(fileName); +      glXDestroyGLXPbufferSGIX( gDpy, gPBuffer ); +   } +   return 0; +} + diff --git a/progs/xdemos/pbinfo.c b/progs/xdemos/pbinfo.c new file mode 100644 index 0000000000..e4e52810f7 --- /dev/null +++ b/progs/xdemos/pbinfo.c @@ -0,0 +1,133 @@ +/* $Id: pbinfo.c,v 1.1 2002/10/05 18:30:13 brianp Exp $ */ + +/* + * Print list of fbconfigs and test each to see if a pbuffer can be created + * for that config. + * + * Brian Paul + * April 1997 + * Updated on 5 October 2002. + */ + + +#include <X11/Xlib.h> +#include <stdio.h> +#include <string.h> +#include "pbutil.h" + + + + +static void +PrintConfigs(Display *dpy, int screen, Bool horizFormat) +{ +   GLXFBConfigSGIX *fbConfigs; +   int nConfigs; +   int i; +   /* Note: you may want to tweek the attribute list to select a different +    * set of fbconfigs. +    */ +   int fbAttribs[] = { +                      GLX_RENDER_TYPE_SGIX, 0, +		      GLX_DRAWABLE_TYPE_SGIX, 0, +#if 0 +                      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, +#endif +		      None}; + + +   /* Get list of possible frame buffer configurations */ +#if 0 +   /* SGIX method */ +   fbConfigs = glXChooseFBConfigSGIX(dpy, screen, fbAttribs, &nConfigs); +#else +   /* GLX 1.3 method */ +   fbConfigs = glXGetFBConfigs(dpy, screen, &nConfigs); +#endif + +   if (nConfigs==0 || !fbConfigs) { +      printf("Error: glxChooseFBConfigSGIX failed\n"); +      return; +   } + +   printf("Number of fbconfigs: %d\n", nConfigs); + +   if (horizFormat) { +      printf("  ID  VisualType  Depth Lvl RGB CI DB Stereo  R  G  B  A"); +      printf("   Z  S  AR AG AB AA  MSbufs MSnum  Pbuffer\n"); +   } + +   /* Print config info */ +   for (i=0;i<nConfigs;i++) { +      PrintFBConfigInfo(dpy, fbConfigs[i], horizFormat); +   } + +   /* free the list */ +   XFree(fbConfigs); +} + + + +static void +PrintUsage(void) +{ +   printf("Options:\n"); +   printf("  -display <display-name>  specify X display name\n"); +   printf("  -t                       print in tabular format\n"); +   printf("  -v                       print in verbose format\n"); +   printf("  -help                    print this information\n"); +} + + +int +main(int argc, char *argv[]) +{ +   Display *dpy; +   int scrn; +   char *dpyName = NULL; +   Bool horizFormat = True; +   int i; + +   for (i=1; i<argc; i++) { +      if (strcmp(argv[i],"-display")==0) { +	 if (i+1<argc) { +	    dpyName = argv[i+1]; +	    i++; +	 } +      } +      else if (strcmp(argv[i],"-t")==0) { +	 /* tabular format */ +	 horizFormat = True; +      } +      else if (strcmp(argv[i],"-v")==0) { +	 /* verbose format */ +	 horizFormat = False; +      } +      else if (strcmp(argv[i],"-help")==0) { +	 PrintUsage(); +	 return 0; +      } +      else { +	 printf("Unknown option: %s\n", argv[i]); +      } +   } + +   dpy = XOpenDisplay(dpyName); + +   if (!dpy) { +      printf("Error: couldn't open display %s\n", dpyName ? dpyName : ":0"); +      return 1; +   } + +   scrn = DefaultScreen(dpy); +   PrintConfigs(dpy, scrn, horizFormat); +   XCloseDisplay(dpy); +   return 0; +} diff --git a/progs/xdemos/pbutil.c b/progs/xdemos/pbutil.c new file mode 100644 index 0000000000..4451a6d1a5 --- /dev/null +++ b/progs/xdemos/pbutil.c @@ -0,0 +1,230 @@ +/* $Id: pbutil.c,v 1.1 2002/10/05 18:30:13 brianp Exp $ */ + +/* + * OpenGL pbuffers utility functions. + * + * Brian Paul + * April 1997 + * Updated on 5 October 2002 + */ + + +#include <stdio.h> +#include <string.h> +#include "pbutil.h" + + + +/* + * Test if we pixel buffers are available for a particular X screen. + * Input:  dpy - the X display + *         screen - screen number + * Return:  0 = pixel buffers not available. + *          1 = pixel buffers are available. + */ +int +QueryPbuffers(Display *dpy, int screen) +{ +#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer) +   char *extensions; + +   extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS); +   if (!strstr(extensions,"GLX_SGIX_fbconfig")) { +      return 0; +   } +   if (!strstr(extensions,"GLX_SGIX_pbuffer")) { +      return 0; +   } +   return 1; +#else +   return 0; +#endif +} + + + +#ifdef GLX_SGIX_fbconfig + + +/* + * Print parameters for a GLXFBConfig to stdout. + * Input:  dpy - the X display + *         fbConfig - the fbconfig handle + *         horizFormat - if true, print in horizontal format + */ +void +PrintFBConfigInfo(Display *dpy, GLXFBConfigSGIX fbConfig, Bool horizFormat) +{ +   int pbAttribs[] = {GLX_LARGEST_PBUFFER_SGIX, True, +		      GLX_PRESERVED_CONTENTS_SGIX, False, +		      None}; +   GLXPbufferSGIX pBuffer; +   int width=2, height=2; +   int bufferSize, level, doubleBuffer, stereo, auxBuffers; +   int redSize, greenSize, blueSize, alphaSize; +   int depthSize, stencilSize; +   int accumRedSize, accumBlueSize, accumGreenSize, accumAlphaSize; +   int sampleBuffers, samples; +   int drawableType, renderType, xRenderable, xVisual, id; +   int maxWidth, maxHeight, maxPixels; +   int optWidth, optHeight; + +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_BUFFER_SIZE, &bufferSize); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_LEVEL, &level); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_DOUBLEBUFFER, &doubleBuffer); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_STEREO, &stereo); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_AUX_BUFFERS, &auxBuffers); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_RED_SIZE, &redSize); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_GREEN_SIZE, &greenSize); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_BLUE_SIZE, &blueSize); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_ALPHA_SIZE, &alphaSize); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_DEPTH_SIZE, &depthSize); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_STENCIL_SIZE, &stencilSize); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_ACCUM_RED_SIZE, &accumRedSize); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_ACCUM_GREEN_SIZE, &accumGreenSize); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_ACCUM_BLUE_SIZE, &accumBlueSize); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_ACCUM_ALPHA_SIZE, &accumAlphaSize); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_SAMPLE_BUFFERS_SGIS, &sampleBuffers); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_SAMPLES_SGIS, &samples); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_DRAWABLE_TYPE_SGIX, &drawableType); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_RENDER_TYPE_SGIX, &renderType); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_X_RENDERABLE_SGIX, &xRenderable); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_X_VISUAL_TYPE_EXT, &xVisual); +   if (!xRenderable || !(drawableType & GLX_WINDOW_BIT_SGIX)) +      xVisual = -1; +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_FBCONFIG_ID_SGIX, &id); + +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_MAX_PBUFFER_WIDTH_SGIX, +			    &maxWidth); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_MAX_PBUFFER_HEIGHT_SGIX, +			    &maxHeight); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_MAX_PBUFFER_PIXELS_SGIX, +			    &maxPixels); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_OPTIMAL_PBUFFER_WIDTH_SGIX, +			    &optWidth); +   glXGetFBConfigAttribSGIX(dpy, fbConfig, GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX, +			    &optHeight); + +   pBuffer = CreatePbuffer(dpy, fbConfig, width, height, pbAttribs); + +   if (horizFormat) { +      printf("0x%03x ", id); +      if (xVisual==GLX_STATIC_GRAY)        printf("StaticGray  "); +      else if (xVisual==GLX_GRAY_SCALE)    printf("GrayScale   "); +      else if (xVisual==GLX_STATIC_COLOR)  printf("StaticColor "); +      else if (xVisual==GLX_PSEUDO_COLOR)  printf("PseudoColor "); +      else if (xVisual==GLX_TRUE_COLOR)    printf("TrueColor   "); +      else if (xVisual==GLX_DIRECT_COLOR)  printf("DirectColor "); +      else                            printf("  -none-    "); +      printf(" %3d %3d   %s   %s  %s   %2s   ", bufferSize, level, +	     (renderType & GLX_RGBA_BIT_SGIX) ? "y" : "n", +	     (renderType & GLX_COLOR_INDEX_BIT_SGIX) ? "y" : "n", +	     doubleBuffer ? "y" : "n", +	     stereo ? "y" : "n"); +      printf("%2d %2d %2d %2d  ", redSize, greenSize, blueSize, alphaSize); +      printf("%2d %2d  ", depthSize, stencilSize); +      printf("%2d %2d %2d %2d", accumRedSize, accumGreenSize, accumBlueSize, +	     accumAlphaSize); +      printf("    %2d    %2d", sampleBuffers, samples); +      printf("       %s", pBuffer ? "y" : "n"); +      printf("\n"); +   } +   else { +      printf("Id 0x%x\n", id); +      printf("  Buffer Size: %d\n", bufferSize); +      printf("  Level: %d\n", level); +      printf("  Double Buffer: %s\n", doubleBuffer ? "yes" : "no"); +      printf("  Stereo: %s\n", stereo ? "yes" : "no"); +      printf("  Aux Buffers: %d\n", auxBuffers); +      printf("  Red Size: %d\n", redSize); +      printf("  Green Size: %d\n", greenSize); +      printf("  Blue Size: %d\n", blueSize); +      printf("  Alpha Size: %d\n", alphaSize); +      printf("  Depth Size: %d\n", depthSize); +      printf("  Stencil Size: %d\n", stencilSize); +      printf("  Accum Red Size: %d\n", accumRedSize); +      printf("  Accum Green Size: %d\n", accumGreenSize); +      printf("  Accum Blue Size: %d\n", accumBlueSize); +      printf("  Accum Alpha Size: %d\n", accumAlphaSize); +      printf("  Sample Buffers: %d\n", sampleBuffers); +      printf("  Samples/Pixel: %d\n", samples); +      printf("  Drawable Types: "); +      if (drawableType & GLX_WINDOW_BIT_SGIX)  printf("Window "); +      if (drawableType & GLX_PIXMAP_BIT_SGIX)  printf("Pixmap "); +      if (drawableType & GLX_PBUFFER_BIT_SGIX)  printf("PBuffer"); +      printf("\n"); +      printf("  Render Types: "); +      if (renderType & GLX_RGBA_BIT_SGIX)  printf("RGBA "); +      if (renderType & GLX_COLOR_INDEX_BIT_SGIX)  printf("CI "); +      printf("\n"); +      printf("  X Renderable: %s\n", xRenderable ? "yes" : "no"); +      /* +      printf("  Max width: %d\n", maxWidth); +      printf("  Max height: %d\n", maxHeight); +      printf("  Max pixels: %d\n", maxPixels); +      printf("  Optimum width: %d\n", optWidth); +      printf("  Optimum height: %d\n", optHeight); +      */ +      printf("  Pbuffer: %s\n", pBuffer ? "yes" : "no"); +   } + +   if (pBuffer) { +      glXDestroyGLXPbufferSGIX(dpy, pBuffer); +   } +} + + + +/* This is only used by CreatePbuffer() */ +static int XErrorFlag = 0; +static int HandleXError( Display *dpy, XErrorEvent *event ) +{ +    XErrorFlag = 1; +    return 0; +} + + +/* + * Create a pixel buffer.  We loop over the list of fbconfigs trying to create + * a pixel buffer.  We return the first pixel buffer which we successfully + * create.  This function hides the ugliness of dealing with BadAlloc X + * protocol errors. + * + * Input:  dpy - the X display + *         fbConfig - an FBConfig as returned by glXChooseFBConfigSGIX(). + *         width, height - size of pixel buffer to request, in pixels. + *         pbAttribs - list of pixel buffer attributes as used by + *                     glXCreateGLXPbufferSGIX(). + * Return:  a pixel buffer or None. + */ +GLXPbufferSGIX +CreatePbuffer( Display *dpy, GLXFBConfigSGIX fbConfig, +	       int width, int height, int *pbAttribs ) +{ +   int (*oldHandler)( Display *, XErrorEvent * ); +   GLXPbufferSGIX pBuffer = None; + +   /* Catch X protocol errors with our own error handler */ +   oldHandler = XSetErrorHandler( HandleXError ); + +   XErrorFlag = 0; +   pBuffer = glXCreateGLXPbufferSGIX(dpy, fbConfig, width, height, pbAttribs); + +   /* Restore original X error handler */ +   (void) XSetErrorHandler( oldHandler ); + +   /* Return pbuffer (may be None) */ +   if (!XErrorFlag && pBuffer!=None) { +      /*printf("config %d worked!\n", i);*/ +      return pBuffer; +   } +   else { +      return None; +   } +} + + + +#endif  /*GLX_SGIX_fbconfig*/ + + diff --git a/progs/xdemos/pbutil.h b/progs/xdemos/pbutil.h new file mode 100644 index 0000000000..9230b47c31 --- /dev/null +++ b/progs/xdemos/pbutil.h @@ -0,0 +1,38 @@ +/* $Id: pbutil.h,v 1.1 2002/10/05 18:30:13 brianp Exp $ */ + +/* + * OpenGL pbuffers utility functions. + * + * Brian Paul + * April 1997 + */ + + +#ifndef PBUTIL_H +#define PBUTIL_H + + +#define GLX_GLXEXT_PROTOTYPES +#include <GL/glx.h> + + +extern int +QueryPbuffers(Display *dpy, int screen); + + +#ifdef GLX_SGIX_fbconfig + + +extern void +PrintFBConfigInfo(Display *dpy, GLXFBConfigSGIX fbConfig, Bool horizFormat); + + +extern GLXPbufferSGIX +CreatePbuffer( Display *dpy, GLXFBConfigSGIX fbConfig, +	       int width, int height, int *pbAttribs ); + + +#endif  /*GLX_SGIX_fbconfig*/ + + +#endif  /*PBUTIL_H*/ | 
