/* * A demonstration of using the GLXPixmap functions. This program is in * the public domain. * Brian Paul */ /* modified with traces/etc for TransGaming by * David Hammerton * david@transgaming.com * 16 May, 2003 * * Modified by jpc 2006 * not using Shm */ #include #include #include #include #include #include #include static GC gc; static int with_shm=0; typedef struct { GLXContext ctx; XVisualInfo *visinfo; Display *dpy; Window win; Pixmap pm; GLXPixmap glxpm; XShmSegmentInfo *shmseginfo; void *vidmem; int width, height; } vidData; static void make_rgb_window( vidData *ourData ) { int attrib[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; int scrnum; XSetWindowAttributes attr; unsigned long mask; Window root; Window win; scrnum = DefaultScreen( ourData->dpy ); root = RootWindow( ourData->dpy, scrnum ); ourData->visinfo = glXChooseVisual( ourData->dpy, scrnum, attrib ); if (!ourData->visinfo) { printf("Error: couldn't get an RGB, Double-buffered visual\n"); exit(1); } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; /* TODO: share root colormap if possible */ attr.colormap = XCreateColormap( ourData->dpy, root, ourData->visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; ourData->win = XCreateWindow( ourData->dpy, root, 0, 0, ourData->width, ourData->height, 0, ourData->visinfo->depth, InputOutput, ourData->visinfo->visual, mask, &attr ); /* make an X GC so we can do XCopyArea later */ gc = XCreateGC( ourData->dpy, ourData->win, 0, NULL ); ourData->ctx = glXCreateContext( ourData->dpy,ourData->visinfo, NULL, False ); } static void make_pixmap( vidData *ourData) { int i; GLXPixmap glxpm; Pixmap testpm; XWindowAttributes attr; for ( i = 0 ; i < 1000 ; i++) { /* ourData->ctx = glXCreateContext( ourData->dpy,ourData->visinfo, NULL, False ); */ ourData->pm = XCreatePixmap( ourData->dpy, ourData->win, ourData->width, ourData->height, ourData->visinfo->depth ); XGetWindowAttributes( ourData->dpy, ourData->win, &attr ); fprintf(stderr, "XPixmap created: %i\n", ourData->pm); XSync(ourData->dpy, 0); fprintf(stderr, "synced\n"); #if 0 /* GLX_MESA_pixmap_colormap */ /* does not work */ ourData->glxpm = glXCreateGLXPixmapMESA( ourData->dpy, ourData->visinfo, ourData->pm, attr.colormap ); fprintf(stderr, "GLXPixmap created with Mesa: %i\n", ourData->glxpm); #else /* This will work with Mesa too if the visual is TrueColor or DirectColor */ ourData->glxpm = glXCreateGLXPixmap( ourData->dpy, ourData->visinfo, ourData->pm ); fprintf(stderr, "GLXPixmap created without Mesa: %i\n", ourData->glxpm); #endif XSync(ourData->dpy, 0); fprintf(stderr, "synced\n"); glXMakeCurrent( ourData->dpy, ourData->glxpm, ourData->ctx ); /* XXXXXXXX */ fprintf(stderr, "make current \n"); XSync(ourData->dpy, 0); fprintf(stderr, "make current \n"); /* glXDestroyContext(ourData->dpy,ourData->ctx); */ glXMakeCurrent( ourData->dpy, None, NULL); glXDestroyPixmap(ourData->dpy,ourData->glxpm); XFreePixmap(ourData->dpy,ourData->pm); XSync(ourData->dpy, 0); XSync(ourData->dpy, 0); fprintf(stderr, "synced\n"); } ourData->pm = XCreatePixmap( ourData->dpy, ourData->win, ourData->width, ourData->height, ourData->visinfo->depth ); ourData->glxpm = glXCreateGLXPixmap( ourData->dpy, ourData->visinfo, ourData->pm ); } static void event_loop( vidData *ourData ) { XEvent event; while (1) { XNextEvent( ourData->dpy, &event ); switch (event.type) { case Expose: fprintf(stderr, "Redraw (src: %i (%08x), dest: %i (%08x))\n", ourData->pm, ourData->pm, event.xany.window, event.xany.window); /* copy the image from GLXPixmap to window */ XCopyArea( ourData->dpy, ourData->pm, event.xany.window, /* src, dest */ gc, 0, 0, 300, 300, /* gc, src pos, size */ 0, 0 ); /* dest pos */ fprintf(stderr, "done\n"); XSync(ourData->dpy, 0); fprintf(stderr, "synced\n"); break; case ConfigureNotify: /* nothing */ break; } } } int main( int argc, char *argv[] ) { int i; vidData ourData; ourData.width = ourData.height = 300; ourData.dpy = XOpenDisplay(NULL); make_rgb_window( &ourData ); make_pixmap( &ourData ); fprintf(stderr, "display: %p, pixmap (glx): %i, context: %i\n", ourData.dpy, ourData.pm, ourData.ctx); XSync(ourData.dpy, 0); fprintf(stderr, "synced\n"); glXMakeCurrent( ourData.dpy, ourData.glxpm, ourData.ctx ); fprintf(stderr, "make current\n"); XSync(ourData.dpy, 0); fprintf(stderr, "synced\n"); /* Render an image into the pixmap */ glShadeModel( GL_FLAT ); glClearColor( 0.5, 0.5, 0.5, 1.0 ); glClear( GL_COLOR_BUFFER_BIT ); glViewport( 0, 0, 300, 300 ); glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 ); glColor3f( 0.0, 1.0, 1.0 ); glRectf( -0.75, -0.75, 0.75, 0.75 ); glColor3f( 1.0, 0.0, 0.0 ); glBegin(GL_LINES); glVertex2f ( -0.5, -0.5 ); glVertex2f ( 0.5, 0.5 ); glEnd(); glFlush(); fprintf(stderr, "drawn\n"); XSync(ourData.dpy, 0); fprintf(stderr, "synced\n"); if ( with_shm ) for (i = 0; i < 300 * 50; i++) { ((char *)ourData.shmseginfo->shmaddr)[i] = i; } /* when a redraw is needed we'll just copy the pixmap image to the window */ fprintf(stderr, "window: %i\n", ourData.win); XMapWindow( ourData.dpy, ourData.win ); fprintf(stderr, "mapped\n"); XSync(ourData.dpy, 0); fprintf(stderr, "synced\n"); event_loop( &ourData ); return 0; }