Tutorial: OpenGL 3.0 Context Creation (GLX): Difference between revisions
Jump to navigation
Jump to search
Dark Photon (talk | contribs) |
Dark Photon (talk | contribs) |
||
Line 222: | Line 222: | ||
> gl3 | > gl3 | ||
Getting matching framebuffer configs | Getting matching framebuffer configs | ||
Found 3 matching FB configs. | Found 3 matching FB configs. |
Revision as of 02:02, 13 July 2009
Overview
This tutorial illustrates (with a working program) how to create an OpenGL 3.0 context using the new glXCreateContextAttribsARB()
API. In the event that this API is unsupported or fails, we fall back and create a standard (old-style) GL 2.1 context.
The Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define GL_GLEXT_PROTOTYPES 1 #define GLX_GLXEXT_PROTOTYPES 1 #include <X11/Xlib.h> #include <X11/Xutil.h> #include <GL/gl.h> #include <GL/glx.h> #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); int main (int argc, char ** argv) { Display *display = XOpenDisplay(0); if ( !display ) { printf( "Failed to open X display\n" ); exit(1); } // // Query/print GLX version // int major, minor; // // if ( !glXQueryVersion( display, &major, &minor ) ) // { // printf( "glXQueryVersion failed\n" ); // exit(1); // } // printf( "GLX version = %d.%d\n", major, minor ); // // if ( major < 1 || major == 1 && minor < 3 ) // { // printf( "GLX version is too old; must be > 1.3\n" ); // exit(1); // } // // Print GLX extensions // const char *extensions = glXQueryExtensionsString( display, // DefaultScreen( display ) ); // printf( "%s\n", extensions ); // Get a matching FB config static int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, GLX_RENDER_TYPE , GLX_RGBA_BIT, GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, GLX_RED_SIZE , 8, GLX_GREEN_SIZE , 8, GLX_BLUE_SIZE , 8, GLX_ALPHA_SIZE , 8, GLX_DEPTH_SIZE , 24, GLX_STENCIL_SIZE , 8, GLX_DOUBLEBUFFER , True, //GLX_SAMPLE_BUFFERS , 1, //GLX_SAMPLES , 4, None }; printf( "Getting matching framebuffer configs\n" ); int fbcount; GLXFBConfig *fbc = glXChooseFBConfig( display, DefaultScreen( display ), visual_attribs, &fbcount ); if ( !fbc ) { printf( "Failed to retrieve a framebuffer config\n" ); exit(1); } printf( "Found %d matching FB configs.\n", fbcount ); // Pick the FB config/visual with the most samples per pixel printf( "Getting XVisualInfos\n" ); int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999; for ( int i = 0; i < fbcount; i++ ) { XVisualInfo *vi = glXGetVisualFromFBConfig( display, fbc[i] ); if ( vi ) { int samp_buf, samples; glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf ); glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLES , &samples ); printf( " Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d," " SAMPLES = %d\n", i, vi -> visualid, samp_buf, samples ); if ( best_fbc < 0 || samp_buf && samples > best_num_samp ) best_fbc = i, best_num_samp = samples; if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp ) worst_fbc = i, worst_num_samp = samples; } XFree( vi ); } // Get a visual int fbc_id = best_fbc; //int fbc_id = worst_fbc; XVisualInfo *vi = glXGetVisualFromFBConfig( display, fbc[ fbc_id ] ); printf( "Chosen visual ID = 0x%x\n", vi->visualid ); printf( "Creating colormap\n" ); XSetWindowAttributes swa; swa.colormap = XCreateColormap( display, RootWindow( display, vi->screen ), vi->visual, AllocNone ); swa.background_pixmap = None ; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; printf( "Creating window\n" ); Window win = XCreateWindow( display, RootWindow( display, vi->screen ), 0, 0, 100, 100, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa ); if ( !win ) { printf( "Failed to create window.\n" ); exit(1); } XStoreName( display, win, "GL 3.0 Window"); printf( "Mapping window\n" ); XMapWindow( display, win ); // See if GL driver supports glXCreateContextAttribsARB() // Create an old-style GLX context first, to get the correct function ptr. glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; GLXContext ctx_old = glXCreateContext( display, vi, 0, True ); glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress( (const GLubyte *) "glXCreateContextAttribsARB" ); GLXContext ctx = 0; // If it doesn't, just use the old-style 2.x GLX context if ( !glXCreateContextAttribsARB ) { printf( "glXCreateContextAttribsARB() not found" " ... using old-style GLX context\n" ); ctx = ctx_old; } // If it "does", try to get a GL 3.0 context! else { glXMakeCurrent( display, 0, 0 ); glXDestroyContext( display, ctx_old ); static int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, None }; printf( "Creating context\n" ); ctx = glXCreateContextAttribsARB( display, fbc[ fbc_id ], 0, True, context_attribs ); if ( ctx ) printf( "Created GL 3.0 context\n" ); else { // Couldn't create GL 3.0 context. Fall back to old-style 2.x context. printf( "Failed to create GL 3.0 context" " ... using old-style GLX context\n" ); ctx = glXCreateContext( display, vi, 0, True ); } } XFree( fbc ); // Verifying that context is a direct context printf( "Verifying that context is direct\n" ); if ( ! glXIsDirect ( display, ctx ) ) { printf( "Indirect GLX rendering context obtained" ); exit(1); } printf( "Making context current\n" ); glXMakeCurrent( display, win, ctx ); glClearColor ( 0, 0.5, 1, 1 ); glClear ( GL_COLOR_BUFFER_BIT ); glXSwapBuffers ( display, win ); sleep( 1 ); glClearColor ( 1, 0.5, 0, 1 ); glClear ( GL_COLOR_BUFFER_BIT ); glXSwapBuffers ( display, win ); sleep( 1 ); ctx = glXGetCurrentContext( ); glXMakeCurrent( display, 0, 0 ); glXDestroyContext( display, ctx ); }
Compilation
g++ -o gl3 gl3.cxx -lGL
Execution
> gl3 Getting matching framebuffer configs Found 3 matching FB configs. Getting XVisualInfos Matching fbconfig 0, visual ID 0x23: SAMPLE_BUFFERS = 0, SAMPLES = 0 Matching fbconfig 1, visual ID 0x37: SAMPLE_BUFFERS = 1, SAMPLES = 2 Matching fbconfig 2, visual ID 0x39: SAMPLE_BUFFERS = 1, SAMPLES = 4 Chosen visual ID = 0x39 Creating colormap Creating window Mapping window Creating context Created GL 3.0 context Verifying that context is direct Making context current