#include #include #include #include #include #include #include static Display *pDisplay = NULL; static int nScreen = 0; static Pixmap pix; static GLXPixmap glpix; static GLXContext glxctx = NULL; static int bVerbose = 0; int create( XVisualInfo *pVI, int nWid, int nHgt ) { /* Create an OpenGL context */ glxctx = glXCreateContext( pDisplay, pVI, NULL, False ); if( ! glxctx ) { fprintf( stderr, "Unable to create a GL context.\n"); return 0; } if( bVerbose ) fprintf( stderr, "Created a GLX context.\n" ); pix = XCreatePixmap( pDisplay, RootWindow(pDisplay, nScreen), nWid, nHgt, pVI->depth); if(!pix) { fprintf( stderr, "Unable to create a pixmap.\n"); return 0; } if( bVerbose ) fprintf( stderr, "Created an X pixmap.\n" ); glpix = glXCreateGLXPixmap( pDisplay, pVI, pix ); if(!glpix) { fprintf( stderr, "Unable to create a GLX pixmap.\n"); return 0; } if( bVerbose ) fprintf( stderr, "Created a GLX pixmap.\n" ); if( ! glXMakeCurrent(pDisplay, glpix, glxctx) ) { if( glxctx != glXGetCurrentContext() ) { fprintf( stderr, "Unable to make GLX pixmap context current.\n"); return 0; } else if( bVerbose ) fprintf( stderr, "Made GLX pixmap context current but got error.\n" ); } else if( bVerbose ) fprintf( stderr, "Made GLX pixmap context current.\n" ); return 1; } void cleanup() { /* Release everything */ glXMakeCurrent( pDisplay, None, NULL ); if( bVerbose ) fprintf( stderr, "Released GLX context.\n" ); glXDestroyGLXPixmap( pDisplay, glpix ); if( bVerbose ) fprintf( stderr, "Destroyed GLX pixmap.\n" ); XFreePixmap( pDisplay, pix ); if( bVerbose ) fprintf( stderr, "Destroyed X pixmap.\n" ); glXDestroyContext( pDisplay, glxctx ); if( bVerbose ) fprintf( stderr, "Destroyed GLX context.\n" ); } int main(int argc, char *argv[]) { int i; XVisualInfo *pVI = NULL; char *dpy = NULL; int bSynch = 0; for(i=1; i < argc; i++) { int nArgLen = strlen(argv[i]); if(!strncmp(argv[i],"-display",nArgLen)) { if( ++i < argc ) { dpy = argv[i]; } } else if(!strncmp(argv[i],"-verbose",nArgLen)) bVerbose = 1; else if(!strncmp(argv[i],"-synchronize",nArgLen)) bSynch = 1; else fprintf( stderr, "Unknown option ignored: %s.\n", argv[i] ); } int anAttribs[] = { GLX_DOUBLEBUFFER, GLX_LEVEL, 0, GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 12, 0, }; /* fprintf(stderr,"unsigned int %d\n" "unsigned long %d\n" "Window %d\n" "pixmap %d\n" "GLXPixmap %d\n" "GLXContext %d\n", sizeof(unsigned int), sizeof(unsigned long), sizeof(Window), sizeof(Pixmap), sizeof(GLXPixmap), sizeof(GLXContext) ); fflush(stderr); assert( sizeof(Pixmap) == sizeof(unsigned long) ); assert( sizeof(GLXPixmap) == sizeof(unsigned long) ); assert( sizeof(GLXContext) == sizeof(unsigned long) ); */ /* Open display */ pDisplay = XOpenDisplay(dpy); if( ! pDisplay ) { fprintf( stderr, "Could not connect to %s.\n", XDisplayName(dpy) ); exit(1); } if( bSynch ) XSynchronize(pDisplay,True); if( bVerbose ) fprintf( stderr, "Connected to display: %s\n", XDisplayName(dpy) ); if( False == glXQueryExtension(pDisplay, NULL, NULL) ) { fprintf( stderr, "OpenGL not supported by X server.\n"); exit(1); } if( bVerbose ) fprintf( stderr, "GLX is supported.\n" ); nScreen = DefaultScreen( pDisplay ); if( bVerbose ) fprintf( stderr, "Screen is %d.\n", nScreen ); /* Find a single-buffered visual */ pVI = glXChooseVisual( pDisplay, nScreen, &anAttribs[1] ); if( ! pVI ) { pVI = glXChooseVisual( pDisplay, nScreen, anAttribs ); if( pVI && bVerbose ) fprintf( stderr, "Found a double-buffered visual.\n", nScreen ); } else if( bVerbose ) fprintf( stderr, "Found a single-buffered visual.\n", nScreen ); if( ! pVI ) { fprintf( stderr, "Could not find a GL visual.\n"); exit(1); } if(!((pVI->class==DirectColor) || (pVI->class==TrueColor))) { fprintf( stderr, "Wanted a DirectColor or TrueColor visual.\n"); exit(1); } /* Create an OpenGL context */ if( ! create(pVI, 100, 100) ) exit(1); /* Try writing to the pixmap */ glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glFinish(); GLfloat afDim[2]; glGetFloatv(GL_MAX_VIEWPORT_DIMS,afDim); #ifdef DO_READ glReadBuffer(GL_FRONT); GLubyte *data = (GLubyte *)malloc((4000*4000*4)*sizeof(GLubyte)); if( ! data ) fprintf( stderr, "Could not allocate memory.\n"); else #endif { int ii; for(ii=0; ii<50; ii++) { cleanup(); if( ! create(pVI, afDim[0], afDim[1]) ) exit(1); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glFinish(); #ifdef DO_READ glReadPixels(0,0,3999,3999, GL_RGBA, GL_UNSIGNED_BYTE, data); glFinish(); #endif } } XSync( pDisplay, False ); cleanup(); return 0; }