8.3. LinuxLinux uses GLX, the OpenGL extension to the X Window System, to provide platform-specific support for OpenGL. For documentation on GLX, see OpenGL Graphics with the X Window System (Version 1.3), edited by Paula Womack and Jon Leech, available from the official OpenGL Web site, http://www.opengl.org. Note, however, that most Linux systems use Mesa, which provides GLX version 1.4 support.[1]
To run an OpenGL program on a Linux system, the X Windows server must support the GLX extension. If you purchase a Linux system with an OpenGL graphics card, the system manufacturer preconfigures X to load GLX. Run the glxinfo client to confirm that your X server supports GLX. GLX allows OpenGL clients to render onscreen using GLXWindows. It also allows two forms of offscreen rendering: GLXPixmaps and GLXPbuffers. Collectively, GLXWindows, GLXPixmaps, and GLXPbuffers are known as GLXDrawables. Typically, GLXPixmaps don't use hardware acceleration. For hardware-accelerated offscreen rendering, use GLXPbuffers. This section focuses primarily on rendering to a window, though most of the concepts also apply to offscreen rendering. For more information on offscreen rendering, refer to OpenGL Graphics with the X Window System. 8.3.1. Creating ContextsTo create a rendering context that renders to a window, perform the following steps:
To obtain a GLXFBConfig, call glXChooseFBConfig().
Use glXChooseFBConfig() to obtain available GLXFBConfigs that meet or exceed your application requirements for rendering buffer characteristics. The following code, for example, obtains a list of GLXFBConfigs for use with double-buffered RGBA rendering to a window. The GLXFBConfigs will have at least 24 color buffer bits and at least 24 depth buffer bits. const int attributes[] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DOUBLEBUFFER, True, GLX_BUFFER_SIZE, 24, GLX_DEPTH_SIZE, 24, None }; int nElements; GLXFBConfig* fbConfigs = glXChooseFBConfig( dpy, screen, attributes, &nElements ); GLXFBConfig is an opaque data type. To examine all attributes of a GLXFBConfig, use glXGetFBConfigAttrib(). For more information, see OpenGL Graphics with the X Window System. Use XFree() to free the GLXFBConfig array returned by glXChooseFBConfig(). After identifying a GLXFBConfig that meets your application's requirements, create a rendering context with a call to glXCreateNewContext().
glXCreateNewContext() returns NULL if it fails for any reason. GLX has the concept of an address space, which determines whether OpenGL objects can be shared between rendering contexts. For more information, see OpenGL Graphics with the X Window System. If the GLXFBConfig supports rendering to a window (that is, its GLX_DRAWABLE_TYPE attribute has the GLX_WINDOW_BIT set), the GLXFBConfig has an associated X visual. Obtain the XVisualInfo struct from the GLXFBConfig with a call to glXGetVisualFromFBConfig().
Applications that render to windows use fields from the returned XVisualInfo struct to create a color map and window. To render to a window, your application needs to create a standard X Window (for example, XCreateWindow()) with the visual info from the GLXFBConfig and then create a GLXWindow. To create a GLXWindow, call glXCreateWindow().
glXCreateWindow() returns the XID of a new GLXWindow or NULL if it fails for any reason. Call glXDestroyWindow() to destroy a GLXWindow. 8.3.2. Using ContextsBefore you can render to a window, you need to bind the rendering context to the GLXWindow. To do this, call glXMakeContextCurrent().
After a successful call to glXMakeContextCurrent(), subsequent OpenGL state commands affect state stored in ctx, rendering commands ultimately appear in draw, and read commands (such as glReadPixels()) obtain pixel data from read. In GLX, a thread can have only one context current at a time. If the calling thread already has a current context, calling glXMakeContextCurrent() flushes the previous context and makes it noncurrent. To make ctx noncurrent without binding a new context to draw and read, issue the following command: glXMakeContextCurrent( dpy, None, None, NULL ); 8.3.3. Swapping BuffersIf your context is double buffered (that is, if the GLX_DOUBLEBUFFER attribute of the GLXFBConfig is true), you must swap buffers after rendering a frame to display the contents of the back buffer. To swap buffers, call glXSwapBuffers().
If draw is current to a rendering context, glXSwapBuffers() implicitly flushes any buffered commands in that rendering context. Typically, GLX implementations synchronize buffer swaps to the monitor vertical retrace. GLX doesn't specify vertical retrace synchronization, however. As a result, this behavior may vary from one implementation to the next. 8.3.4. Deleting ContextsWhen your application no longer has a use for a rendering context, destroy the rendering context with a call to glXDestroyContext().
glXDestroyContext() doesn't destroy the rendering context if it's still current. For this reason, applications typically make the context noncurrent and then destroy it, as in the following code: glXMakeContextCurrent( dpy, None, None, NULL ); glXDestroyContext( dpy, ctx ); |