diff options
author | Sven Gothel <[email protected]> | 2010-11-14 09:05:49 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-11-14 09:05:49 +0100 |
commit | deeb2ee63d3765336325c095a22f494e2f6bfe5b (patch) | |
tree | df99175dab4df0c0f9bc591a24f7d48174327848 | |
parent | 83d3a3f2ea8dc328e621b3abbe671f46379c7e65 (diff) |
Simple native context tests to verify against a simple native application
-rw-r--r-- | test/native/glExtensionsListGL2.c | 95 | ||||
-rw-r--r-- | test/native/glExtensionsListGL3.c | 300 | ||||
-rwxr-xr-x | test/native/make.sh | 2 |
3 files changed, 397 insertions, 0 deletions
diff --git a/test/native/glExtensionsListGL2.c b/test/native/glExtensionsListGL2.c new file mode 100644 index 000000000..89815e9c0 --- /dev/null +++ b/test/native/glExtensionsListGL2.c @@ -0,0 +1,95 @@ +/** + * compile with: gcc -o displayMultiple02 displayMultiple02.c -lX11 -lGL + */ + +#include <stdio.h> +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <GL/glx.h> +#include <GL/gl.h> + +static void testExtensions(); + +int main(int nargs, char **vargs) { + testExtensions(); + return 0; +} + +static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx); +static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height); + +void testExtensions() { + int major, minor; + Display *disp1; + Window win1; + GLXContext ctx1; + + disp1 = XOpenDisplay(NULL); + createGLWin(disp1, 200, 200, &win1, &ctx1); + if(0 != win1 && 0 != ctx1) { + useGL(disp1, win1, ctx1, 200, 200); + + glXMakeCurrent(disp1, 0, 0); + glXDestroyContext(disp1, ctx1); + } + XCloseDisplay(disp1); +} + +/* attributes for a double buffered visual in RGBA format with at least + * 4 bits per color and a 16 bit depth buffer */ +static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, + GLX_RED_SIZE, 4, + GLX_GREEN_SIZE, 4, + GLX_BLUE_SIZE, 4, + GLX_DEPTH_SIZE, 16, + None }; + +void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx) +{ + int screen = DefaultScreen(dpy); + XVisualInfo *vi = glXChooseVisual(dpy, screen, attrListDbl); + Colormap cmap; + XSetWindowAttributes attr; + + /* create a GLX context */ + *rCtx = glXCreateContext(dpy, vi, 0, GL_TRUE); + /* create a color map */ + cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); + attr.colormap = cmap; + attr.border_pixel = 0; + + /* create a window in window mode*/ + attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | + StructureNotifyMask; + *rWin = XCreateWindow(dpy, RootWindow(dpy, vi->screen), + 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, + CWBorderPixel | CWColormap | CWEventMask, &attr); + + XMapRaised(dpy, *rWin); +} + +void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height) +{ + PFNGLGETSTRINGIPROC glGetStringi = 0; + int i, n; + + glXMakeCurrent(dpy, win, ctx); + + 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); + } + +} + 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; +} + diff --git a/test/native/make.sh b/test/native/make.sh index 2552eddb0..20bd49e4a 100755 --- a/test/native/make.sh +++ b/test/native/make.sh @@ -2,3 +2,5 @@ gcc -o displayMultiple01 displayMultiple01.c -lX11 -lGL gcc -o displayMultiple02 displayMultiple02.c -lX11 -lGL +gcc -o glExtensionsListGL2 glExtensionsListGL2.c -lX11 -lGL +gcc -o glExtensionsListGL3 glExtensionsListGL3.c -lX11 -lGL |