glxpixmap.c revision 32001f49
132001f49Smrg
232001f49Smrg
332001f49Smrg/*
432001f49Smrg * A demonstration of using the GLXPixmap functions.  This program is in
532001f49Smrg * the public domain.
632001f49Smrg *
732001f49Smrg * Brian Paul
832001f49Smrg */
932001f49Smrg
1032001f49Smrg
1132001f49Smrg#include <GL/gl.h>
1232001f49Smrg#define GLX_GLXEXT_PROTOTYPES
1332001f49Smrg#include <GL/glx.h>
1432001f49Smrg#include <stdio.h>
1532001f49Smrg#include <stdlib.h>
1632001f49Smrg#include <string.h>
1732001f49Smrg
1832001f49Smrg
1932001f49Smrgstatic GLXContext ctx;
2032001f49Smrgstatic XVisualInfo *visinfo;
2132001f49Smrgstatic GC gc;
2232001f49Smrg
2332001f49Smrg
2432001f49Smrg
2532001f49Smrgstatic Window make_rgb_window( Display *dpy,
2632001f49Smrg				  unsigned int width, unsigned int height )
2732001f49Smrg{
2832001f49Smrg   const int sbAttrib[] = { GLX_RGBA,
2932001f49Smrg                            GLX_RED_SIZE, 1,
3032001f49Smrg                            GLX_GREEN_SIZE, 1,
3132001f49Smrg                            GLX_BLUE_SIZE, 1,
3232001f49Smrg                            None };
3332001f49Smrg   const int dbAttrib[] = { GLX_RGBA,
3432001f49Smrg                            GLX_RED_SIZE, 1,
3532001f49Smrg                            GLX_GREEN_SIZE, 1,
3632001f49Smrg                            GLX_BLUE_SIZE, 1,
3732001f49Smrg                            GLX_DOUBLEBUFFER,
3832001f49Smrg                            None };
3932001f49Smrg   int scrnum;
4032001f49Smrg   XSetWindowAttributes attr;
4132001f49Smrg   unsigned long mask;
4232001f49Smrg   Window root;
4332001f49Smrg   Window win;
4432001f49Smrg
4532001f49Smrg   scrnum = DefaultScreen( dpy );
4632001f49Smrg   root = RootWindow( dpy, scrnum );
4732001f49Smrg
4832001f49Smrg   visinfo = glXChooseVisual( dpy, scrnum, (int *) sbAttrib );
4932001f49Smrg   if (!visinfo) {
5032001f49Smrg      visinfo = glXChooseVisual( dpy, scrnum, (int *) dbAttrib );
5132001f49Smrg      if (!visinfo) {
5232001f49Smrg         printf("Error: couldn't get an RGB visual\n");
5332001f49Smrg         exit(1);
5432001f49Smrg      }
5532001f49Smrg   }
5632001f49Smrg
5732001f49Smrg   /* window attributes */
5832001f49Smrg   attr.background_pixel = 0;
5932001f49Smrg   attr.border_pixel = 0;
6032001f49Smrg   /* TODO: share root colormap if possible */
6132001f49Smrg   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
6232001f49Smrg   attr.event_mask = StructureNotifyMask | ExposureMask;
6332001f49Smrg   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
6432001f49Smrg
6532001f49Smrg   win = XCreateWindow( dpy, root, 0, 0, width, height,
6632001f49Smrg		        0, visinfo->depth, InputOutput,
6732001f49Smrg		        visinfo->visual, mask, &attr );
6832001f49Smrg
6932001f49Smrg   /* make an X GC so we can do XCopyArea later */
7032001f49Smrg   gc = XCreateGC( dpy, win, 0, NULL );
7132001f49Smrg
7232001f49Smrg   /* need indirect context */
7332001f49Smrg   ctx = glXCreateContext( dpy, visinfo, NULL, False );
7432001f49Smrg   if (!ctx) {
7532001f49Smrg      printf("Error: glXCreateContext failed\n");
7632001f49Smrg      exit(-1);
7732001f49Smrg   }
7832001f49Smrg
7932001f49Smrg   printf("Direct rendering: %s\n", glXIsDirect(dpy, ctx) ? "Yes" : "No");
8032001f49Smrg
8132001f49Smrg   return win;
8232001f49Smrg}
8332001f49Smrg
8432001f49Smrg
8532001f49Smrgstatic GLXPixmap make_pixmap( Display *dpy, Window win,
8632001f49Smrg			       unsigned int width, unsigned int height,
8732001f49Smrg                               Pixmap *pixmap)
8832001f49Smrg{
8932001f49Smrg   Pixmap pm;
9032001f49Smrg   GLXPixmap glxpm;
9132001f49Smrg   XWindowAttributes attr;
9232001f49Smrg
9332001f49Smrg   pm = XCreatePixmap( dpy, win, width, height, visinfo->depth );
9432001f49Smrg   if (!pm) {
9532001f49Smrg      printf("Error: XCreatePixmap failed\n");
9632001f49Smrg      exit(-1);
9732001f49Smrg   }
9832001f49Smrg
9932001f49Smrg   XGetWindowAttributes( dpy, win, &attr );
10032001f49Smrg
10132001f49Smrg   /*
10232001f49Smrg    * IMPORTANT:
10332001f49Smrg    *   Use the glXCreateGLXPixmapMESA funtion when using Mesa because
10432001f49Smrg    *   Mesa needs to know the colormap associated with a pixmap in order
10532001f49Smrg    *   to render correctly.  This is because Mesa allows RGB rendering
10632001f49Smrg    *   into any kind of visual, not just TrueColor or DirectColor.
10732001f49Smrg    */
10832001f49Smrg#ifdef GLX_MESA_pixmap_colormap
10932001f49Smrg   if (strstr(glXQueryExtensionsString(dpy, 0), "GLX_MESA_pixmap_colormap")) {
11032001f49Smrg      /* stand-alone Mesa, specify the colormap */
11132001f49Smrg      PFNGLXCREATEGLXPIXMAPMESAPROC glXCreateGLXPixmapMESA_func =
11232001f49Smrg         (PFNGLXCREATEGLXPIXMAPMESAPROC)
11332001f49Smrg         glXGetProcAddressARB((GLubyte *) "glXCreateGLXPixmapMESA");
11432001f49Smrg      glxpm = glXCreateGLXPixmapMESA_func( dpy, visinfo, pm, attr.colormap );
11532001f49Smrg   }
11632001f49Smrg   else {
11732001f49Smrg      glxpm = glXCreateGLXPixmap( dpy, visinfo, pm );
11832001f49Smrg   }
11932001f49Smrg#else
12032001f49Smrg   /* This will work with Mesa too if the visual is TrueColor or DirectColor */
12132001f49Smrg   glxpm = glXCreateGLXPixmap( dpy, visinfo, pm );
12232001f49Smrg#endif
12332001f49Smrg
12432001f49Smrg   if (!glxpm) {
12532001f49Smrg      printf("Error: GLXCreateGLXPixmap failed\n");
12632001f49Smrg      exit(-1);
12732001f49Smrg   }
12832001f49Smrg
12932001f49Smrg   *pixmap = pm;
13032001f49Smrg
13132001f49Smrg   return glxpm;
13232001f49Smrg}
13332001f49Smrg
13432001f49Smrg
13532001f49Smrg
13632001f49Smrgstatic void event_loop( Display *dpy, GLXPixmap pm )
13732001f49Smrg{
13832001f49Smrg   XEvent event;
13932001f49Smrg
14032001f49Smrg   while (1) {
14132001f49Smrg      XNextEvent( dpy, &event );
14232001f49Smrg
14332001f49Smrg      switch (event.type) {
14432001f49Smrg	 case Expose:
14532001f49Smrg	    printf("Redraw\n");
14632001f49Smrg	    /* copy the image from GLXPixmap to window */
14732001f49Smrg	    XCopyArea( dpy, pm, event.xany.window,  /* src, dest */
14832001f49Smrg		       gc, 0, 0, 300, 300,          /* gc, src pos, size */
14932001f49Smrg		       0, 0 );                      /* dest pos */
15032001f49Smrg	    break;
15132001f49Smrg	 case ConfigureNotify:
15232001f49Smrg	    /* nothing */
15332001f49Smrg	    break;
15432001f49Smrg      }
15532001f49Smrg   }
15632001f49Smrg}
15732001f49Smrg
15832001f49Smrg
15932001f49Smrg
16032001f49Smrgint main( int argc, char *argv[] )
16132001f49Smrg{
16232001f49Smrg   Display *dpy;
16332001f49Smrg   Window win;
16432001f49Smrg   Pixmap pm;
16532001f49Smrg   GLXPixmap glxpm;
16632001f49Smrg
16732001f49Smrg   dpy = XOpenDisplay(NULL);
16832001f49Smrg
16932001f49Smrg   win = make_rgb_window( dpy, 300, 300 );
17032001f49Smrg   glxpm = make_pixmap( dpy, win, 300, 300, &pm );
17132001f49Smrg
17232001f49Smrg   glXMakeCurrent( dpy, glxpm, ctx );
17332001f49Smrg   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
17432001f49Smrg
17532001f49Smrg   /* Render an image into the pixmap */
17632001f49Smrg   glShadeModel( GL_FLAT );
17732001f49Smrg   glClearColor( 0.5, 0.5, 0.5, 1.0 );
17832001f49Smrg   glClear( GL_COLOR_BUFFER_BIT );
17932001f49Smrg   glViewport( 0, 0, 300, 300 );
18032001f49Smrg   glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 );
18132001f49Smrg   glColor3f( 0.0, 1.0, 1.0 );
18232001f49Smrg   glRectf( -0.75, -0.75, 0.75, 0.75 );
18332001f49Smrg   glFlush();
18432001f49Smrg   glXWaitGL();
18532001f49Smrg
18632001f49Smrg   XMapWindow( dpy, win );
18732001f49Smrg
18832001f49Smrg   event_loop( dpy, pm );
18932001f49Smrg   return 0;
19032001f49Smrg}
191