diff options
Diffstat (limited to 'test/native/glExtensionsListGL3.c')
-rw-r--r-- | test/native/glExtensionsListGL3.c | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/test/native/glExtensionsListGL3.c b/test/native/glExtensionsListGL3.c new file mode 100644 index 000000000..c531577e8 --- /dev/null +++ b/test/native/glExtensionsListGL3.c @@ -0,0 +1,300 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <GL/gl.h> +#include <GL/glext.h> +#include <GL/glx.h> +#include <GL/glxext.h> + +typedef int bool; +#define true 1; +#define false 0; + +// Helper to check for extension string presence. Adapted from: +// http://www.opengl.org/resources/features/OGLextensions/ +static bool isExtensionSupported(const char *extList, const char *extension) +{ + + const char *start; + const char *where, *terminator; + + /* Extension names should not have spaces. */ + where = strchr(extension, ' '); + if ( where || *extension == '\0' ) + return false; + + /* It takes a bit of care to be fool-proof about parsing the + OpenGL extensions string. Don't be fooled by sub-strings, + etc. */ + for ( start = extList; ; ) { + where = strstr( start, extension ); + + if ( !where ) + break; + + terminator = where + strlen( extension ); + + if ( where == start || *(where - 1) == ' ' ) + if ( *terminator == ' ' || *terminator == '\0' ) + return true; + + start = terminator; + } + + return false; +} + +static bool ctxErrorOccurred = false; +static int ctxErrorHandler( Display *dpy, XErrorEvent *ev ) +{ + ctxErrorOccurred = true; + return 0; +} + +void dumpGLExtension() { + PFNGLGETSTRINGIPROC glGetStringi = 0; + int i, n; + + fprintf(stderr, "GL_VENDOR: %s\n", glGetString(GL_VENDOR)); + + glGetIntegerv(GL_NUM_EXTENSIONS, &n); + fprintf(stderr, "GL_NUM_EXTENSIONS: %d\n", n); + + glGetStringi = (PFNGLGETSTRINGIPROC)glXGetProcAddressARB("glGetStringi"); + if(NULL==glGetStringi) { + return; + } + + for (i=0; i<n; i++) { + const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, i); + fprintf(stderr, "GL_EXTENSION %d/%d: %s\n", (i+1), n, extension); + } + +} + +int main (int argc, char ** argv) +{ + Display *display = XOpenDisplay(0); + + if ( !display ) + { + printf( "Failed to open X display\n" ); + exit(1); + } + + // 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 + }; + + int glx_major, glx_minor; + + // FBConfigs were added in GLX version 1.3. + if ( !glXQueryVersion( display, &glx_major, &glx_minor ) || + ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) ) + { + printf( "Invalid GLX version" ); + exit(1); + } + + 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; + + int i; + for ( 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", + (int)i, (int)( 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 ); + } + + GLXFBConfig bestFbc = fbc[ best_fbc ]; + + // Be sure to free the FBConfig list allocated by glXChooseFBConfig() + XFree( fbc ); + + // Get a visual + XVisualInfo *vi = glXGetVisualFromFBConfig( display, bestFbc ); + printf( "Chosen visual ID = 0x%x\n", (int) vi->visualid ); + + printf( "Creating colormap\n" ); + XSetWindowAttributes swa; + Colormap cmap; + swa.colormap = cmap = 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); + } + + // Done with the visual info data + XFree( vi ); + + XStoreName( display, win, "GL 3.0 Window" ); + + printf( "Mapping window\n" ); + XMapWindow( display, win ); + + // Get the default screen's GLX extension list + const char *glxExts = glXQueryExtensionsString( display, + DefaultScreen( display ) ); + + // NOTE: It is not necessary to create or make current to a context before + // calling glXGetProcAddressARB + PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = 0; + glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) + glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); + + GLXContext ctx = 0; + + // Install an X error handler so the application won't exit if GL 3.0 + // context allocation fails. + // + // Note this error handler is global. All display connections in all threads + // of a process use the same error handler, so be sure to guard against other + // threads issuing X commands while this code is running. + ctxErrorOccurred = false; + int (*oldHandler)(Display*, XErrorEvent*) = + XSetErrorHandler(&ctxErrorHandler); + + // Check for the GLX_ARB_create_context extension string and the function. + // If either is not present, use GLX 1.3 context creation method. + if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) || + !glXCreateContextAttribsARB ) + { + printf( "glXCreateContextAttribsARB() not found" + " ... using old-style GLX context\n" ); + ctx = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True ); + } + + // If it does, try to get a GL 3.0 context! + else + { + int context_attribs[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 0, + GLX_RENDER_TYPE , GLX_RGBA_TYPE, + GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + None + }; + + printf( "Creating context\n" ); + ctx = glXCreateContextAttribsARB( display, bestFbc, 0, + True, context_attribs ); + + // Sync to ensure any errors generated are processed. + XSync( display, False ); + if ( !ctxErrorOccurred && ctx ) { + printf( "Created GL 3.0 context\n" ); + } else + { + // Couldn't create GL 3.0 context. Fall back to old-style 2.x context. + // When a context version below 3.0 is requested, implementations will + // return the newest context version compatible with OpenGL versions less + // than version 3.0. + // GLX_CONTEXT_MAJOR_VERSION_ARB = 1 + context_attribs[1] = 1; + // GLX_CONTEXT_MINOR_VERSION_ARB = 0 + context_attribs[3] = 0; + + ctxErrorOccurred = false; + + printf( "Failed to create GL 3.0 context" + " ... using old-style GLX context\n" ); + ctx = glXCreateContextAttribsARB( display, bestFbc, 0, + True, context_attribs ); + } + } + + // Sync to ensure any errors generated are processed. + XSync( display, False ); + + // Restore the original error handler + XSetErrorHandler( oldHandler ); + + if ( ctxErrorOccurred || !ctx ) + { + printf( "Failed to create an OpenGL context\n" ); + exit(1); + } + + // Verifying that context is a direct context + if ( ! glXIsDirect ( display, ctx ) ) + { + printf( "Indirect GLX rendering context obtained\n" ); + } + else + { + printf( "Direct GLX rendering context obtained\n" ); + } + + printf( "Making context current\n" ); + glXMakeCurrent( display, win, ctx ); + + dumpGLExtension(); + + glXMakeCurrent( display, 0, 0 ); + glXDestroyContext( display, ctx ); + + XDestroyWindow( display, win ); + XFreeColormap( display, cmap ); + XCloseDisplay( display ); + + return 0; +} + |