[ Next Article | Previous Article | Book Contents | Library Home | Legal | Search ]
OpenGL 1.2 for AIX: Reference Manual

How to Render into an X Drawable

Procedure

To render into an X drawable:

Notes:
  1. Decide which version of GLX can be used.

    The glXQueryVersion and glXQueryServerString subroutines can be used to see if the GLX 1.3 subroutines are available to be used or not.

  2. If GLX 1.3 subroutines can be used:
    • Choose a FBConfig that defines the required OpenGL buffers.

      The glXChooseFBConfig subroutine can be used to simplify selection of a compatible FBConfig. If more control of the selection process is required, use the glXGetFBConfigs and glXGetFBConfigAttrib subroutines to select among the available FBConfigs.

    • Use the selected FBConfig to create a GLX context, a GLX drawable and an X drawable.

      GLX contexts are created with the glXCreateNewContext subroutine. GLX drawables are created using either the glXCreateWindow, glXCreatePixmap or glXCreatePbuffer subroutines. The glXCreateWindow subroutines requires an X window to be associated with the GLX window drawable. Therefore, the glXGetVisualFromFBConfig subroutine can be used to get the XVisualInfo structure for the X visual that is associated with the selected FBConfig and the XCreateWindow subroutine can be used to create the X window.

    • Bind the context and the drawable together using the glXMakeContextCurrent subroutine.

      This context/drawable pair becomes the current context and current read and write drawable, and it is used by all OpenGL commands until the glXMakeContextCurrent or glXMakeCurrent subroutine is called with different arguments.

  3. If GLX 1.3 subroutines can not be used:
    • Choose a visual that defines the required OpenGL buffers.

      The glXChooseVisual subroutine can be used to simplify selection of a compatible visual. If more control of the selection process is required, use the XGetVisualInfo and glXGetConfig subroutines to select among the available visuals.

    • Use the selected visual to create both a GLX context and an X drawable.

      GLX contexts are created with the glXCreateContext subroutine; drawables are created with either the XCreateWindow or glXCreateGLXPixmap subroutines.

    • Bind the context and the drawable together using the glXMakeCurrent subroutine.

      This context/drawable pair becomes the current context and current drawable, and it is used by all OpenGL commands until the glXMakeCurrent subroutine is called with different arguments.

Example

Following is an example of the minimum code required to create a red, green, blue, alpha (RGBA) format, OpenGL-compatible X window. In this example, the X window is cleared to yellow. Note that although the code is valid, no error checking is included. Under normal conditions, all return values should be tested.

#include <GL/glx.h>
#include <GL/gl.h>
#include <string.h>
 
static int AttributeList[] = { GLX_RGBA, None };
 
static Bool WaitForNotify(Display *d, XEvent *e, char *arg) {
   return (e->type == MapNotify) && (e->xmap.window == (Window)arg);
}
 
void setup_glx12(Display *dpy) {
   XVisualInfo *vi;
   Colormap cmap;
   XSetWindowAttributes swa;
   Window win;
   GLXContext cx;
   XEvent event;
 
   /* Get an appropriate visual */
   vi = glXChooseVisual(dpy, DefaultScreen(dpy), AttributeList);
 
   /* Create a GLX context */
   cx = glXCreateContext(dpy, vi, 0, GL_FALSE);
 
   /* Create a colormap */
   cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),vi->visual, AllocNone);
 
   /* Create a window */
   swa.colormap = cmap;
   swa.border_pixel = 0;
   swa.event_mask = StructureNotifyMask;
   win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 100, 100, 0, vi->depth, InputOutput,
                       vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
   XMapWindow(dpy, win);
   XIfEvent(dpy, &event, WaitForNotify, (Char*)win);
 
   /* Connect the context to the window */
   glXMakeCurrent(dpy, win, cx);
}
 
void setup_glx13(Display *dpy) {
   GLXFBConfig *fbc;
   XVisualInfo *vi;
   Colormap cmap;
   XSetWindowAttributes swa;
   Window win;
   GLXContext cx;
   GLXWindow gwin;
   XEvent event;
   int nelements;
 
   /* Find a FBConfig that uses RGBA.  Note that no attribute list is */
   /* needed since GLX_RGBA_BIT is a default attribute.               */
   fbc = glXChooseFBConfig(dpy, DefaultScreen(dpy), 0, &nelements);
   vi = glXGetVisualFromFBConfig(dpy, fbc[0]);
 
   /* Create a GLX context using the first FBConfig in the list. */
   cx = glXCreateNewContext(dpy, fbc[0], GLX_RGBA_TYPE, 0, GL_FALSE);
 
   /* Create a colormap */
   cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),vi->visual, AllocNone);
 
   /* Create a window */
   swa.colormap = cmap;
   swa.border_pixel = 0;
   swa.event_mask = StructureNotifyMask;
   win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 100, 100, 0, vi->depth, InputOutput,
                       vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
   XMapWindow(dpy, win);
   XIfEvent(dpy, &event, WaitForNotify, (Char*)win);
 
   /* Create a GLX window using the same FBConfig that we used for the */
   /* the GLX context.                                                 */
   gwin = glXCreateWindow(dpy, fbc[0], win, 0);
 
   /* Connect the context to the window for read and write */
   glXMakeContextCurrent(dpy, gwin, gwin, cx);
}
 
int main(int argc, char **argv) {
   Display *dpy;
   GLXContext cx;
   XEvent event;
   int major, minor;
   char *string_data;
 
   /* get a connection */
   dpy = XOpenDisplay(0);
 
   /*  */
   if (glXQueryVersion(dpy, &major, &minor)) {
     if (major == 1) {
       if (minor < 3) setup_glx12(dpy);
       else {
         string_data = glXGetServerString(dpy, DefaultScreen(dpy), GLX_VERSION);
         if (strchr(string_data,"1.3")) setup_glx13(dpy);
         else setup_glx12(dpy);
       }
       /* clear the buffer */
       glClearColor(1,1,0,1);
       glClear(GL_COLOR_BUFFER_BIT);
       glFlush();
 
       /* wait a while */
       sleep(10);
     }
   }
}

Special Considerations

When creating an X window, keep the following in mind:

Notes:
  1. A color map must be created and passed to the XCreateWindow subroutine.
  2. A GLX context must be created and attached to one or more X drawable or GLX drawable before OpenGL commands are processed. OpenGL commands issued while no context/drawable pair is current are ignored.
  3. Exposure events indicate that all buffers associated with the specified window may be damaged and should be repainted. Although some visual buffers on certain systems may never require repainting (the depth buffer, for example), this is not the rule. Do not create code based on the assumption that these buffers cannot be damaged.
  4. GLX subroutines (at the GLX 1.2 level and earlier) manipulate XVisualInfo structures, not pointers to visuals or visual IDs. XVisualInfo structures contain visual, visual ID, screen, and depth parameters, as well as other X-specific information. GLX 1.3 subroutines use GLXFBConfig structures instead of the XVisualInfo structures.

Related Information

OpenGL in the AIXwindows (GLX) Environment.

OpenGL Overview.


[ Next Article | Previous Article | Book Contents | Library Home | Legal | Search ]