| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 | 
							- 
 - /*
 -  * 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.
 -  *
 -  * Updated on 31 January 2004 to use native GLX by
 -  * Andrew P. Lentvorski, Jr. <bsder@allcaps.org>
 -  *
 -  * Usage:
 -  *   glxpbdemo 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.
 -  *
 -  * 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 configurations with the _pbuf suffix.  Use
 -  * setmon -x <vof> to configure your X server and display for pbuffers.
 -  *
 -  * O2 systems seem to support pbuffers well.
 -  *
 -  */
 - 
 - #include <string.h>
 - #include <stdio.h>
 - #include <stdlib.h>
 - #include <X11/Xlib.h>
 - #include <GL/glx.h>
 - 
 - /* Some ugly global vars */
 - static GLXFBConfig gFBconfig = 0;
 - static Display *gDpy = NULL;
 - static int gScreen = 0;
 - static GLXPbuffer gPBuffer = 0;
 - static int gWidth, gHeight;
 - 
 - 
 - /*
 -  * Test for appropriate version of GLX to run this program
 -  * Input:  dpy - the X display
 -  *         screen - screen number
 -  * Return:  0 = GLX not available.
 -  *          1 = GLX available.
 -  */
 - static int
 - RuntimeQueryGLXVersion(Display *dpy, int screen)
 - {
 - #if defined(GLX_VERSION_1_3) || defined(GLX_VERSION_1_4)
 -    char *glxversion;
 -  
 -    glxversion = (char *) glXGetClientString(dpy, GLX_VERSION);
 -    if (!(strstr(glxversion, "1.3") || strstr(glxversion, "1.4")))
 -       return 0;
 - 
 -    glxversion = (char *) glXQueryServerString(dpy, screen, GLX_VERSION);
 -    if (!(strstr(glxversion, "1.3") || strstr(glxversion, "1.4")))
 -       return 0;
 - 
 -    return 1;
 - #else
 -    return 0;
 - #endif
 - }
 - 
 - 
 - 
 - /*
 -  * Create the pbuffer and return a GLXPbuffer handle.
 -  */
 - static GLXPbuffer
 - MakePbuffer( Display *dpy, int screen, int width, int height )
 - {
 -    GLXFBConfig *fbConfigs;
 -    GLXFBConfig chosenFBConfig;
 -    GLXPbuffer pBuffer = None;
 - 
 -    int nConfigs;
 -    int fbconfigid;
 - 
 -    int fbAttribs[] = {
 -       GLX_RENDER_TYPE, GLX_RGBA_BIT,
 -       GLX_DEPTH_SIZE, 1,
 -       GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT | GLX_PBUFFER_BIT,
 -       None
 -    };
 - 
 -    int pbAttribs[] = {
 -       GLX_PBUFFER_WIDTH, 0,
 -       GLX_PBUFFER_HEIGHT, 0,
 -       GLX_LARGEST_PBUFFER, False,
 -       GLX_PRESERVED_CONTENTS, False,
 -       None
 -    };
 - 
 -    pbAttribs[1] = width;
 -    pbAttribs[3] = height;
 - 
 -    fbConfigs = glXChooseFBConfig(dpy, screen, fbAttribs, &nConfigs);
 - 
 -    if (0 == nConfigs || !fbConfigs) {
 -       printf("Error: glxChooseFBConfig failed\n");
 -       XCloseDisplay(dpy);
 -       return 0;
 -    }
 - 
 -    chosenFBConfig = fbConfigs[0];
 - 
 -    glXGetFBConfigAttrib(dpy, chosenFBConfig, GLX_FBCONFIG_ID, &fbconfigid);
 -    printf("Chose 0x%x as fbconfigid\n", fbconfigid);
 - 
 -    /* Create the pbuffer using first fbConfig in the list that works. */
 -    pBuffer = glXCreatePbuffer(dpy, chosenFBConfig, pbAttribs);
 - 
 -    if (pBuffer) {
 -       gFBconfig = chosenFBConfig;
 -       gWidth = width;
 -       gHeight = height;
 -    }
 - 
 -    XFree(fbConfigs);
 - 
 -    return pBuffer;
 - }
 - 
 - 
 - 
 - /*
 -  * Do all the X / GLX setup stuff.
 -  */
 - static int
 - Setup(int width, int height)
 - {
 - #if defined(GLX_VERSION_1_3) || defined(GLX_VERSION_1_4)
 -    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 GLX is available */
 -    if (!RuntimeQueryGLXVersion(gDpy, gScreen)) {
 -      printf("Error: GLX 1.3 or 1.4 not available\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;
 -    }
 - 
 -    /* Create GLX context */
 -    glCtx = glXCreateNewContext(gDpy, gFBconfig, GLX_RGBA_TYPE, NULL, True);
 -    if (glCtx) {
 -       if (!glXIsDirect(gDpy, glCtx)) {
 -          printf("Warning: using indirect GLXContext\n");
 -       }
 -    }
 -    else {
 -       printf("Error: Couldn't create GLXContext\n");
 -       XCloseDisplay(gDpy);
 -       return 0;
 -    }
 - 
 -    /* Bind context to pbuffer */
 -    if (!glXMakeCurrent(gDpy, gPBuffer, glCtx)) {
 -       printf("Error: glXMakeCurrent failed\n");
 -       XCloseDisplay(gDpy);
 -       return 0;
 -    }
 - 
 -    return 1;  /* Success!! */
 - #else
 -    printf("Error: GLX version 1.3 or 1.4 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;
 -       }
 - 
 -       printf("Setup completed\n");
 -       Render();
 -       printf("Render completed.\n");
 -       WriteFile(fileName);
 -       printf("File write completed.\n");
 - 
 -       glXDestroyPbuffer( gDpy, gPBuffer );
 -    }
 -    return 0;
 - }
 
 
  |