From a78f218a90cb140e558e2dac7ddbf13a5b97a79d Mon Sep 17 00:00:00 2001 From: ashkalokhe Date: Wed, 1 Apr 2020 09:58:03 -0400 Subject: [PATCH 1/2] Added glut for ubuntu --- .../pxScene2d/src/glut/pxContextUtils.cpp | 359 +++++++++++++++++- 1 file changed, 352 insertions(+), 7 deletions(-) diff --git a/examples/pxScene2d/src/glut/pxContextUtils.cpp b/examples/pxScene2d/src/glut/pxContextUtils.cpp index eac1d6efc7..ec16f5f066 100644 --- a/examples/pxScene2d/src/glut/pxContextUtils.cpp +++ b/examples/pxScene2d/src/glut/pxContextUtils.cpp @@ -18,23 +18,368 @@ limitations under the License. #include "pxContextUtils.h" +#include +#include + +#include +#include +#include +#include +#include + + +#include +#include "rtLog.h" +#include "rtMutex.h" + +bool glContextIsCurrent = false; +rtMutex eglContextMutex; int nextInternalContextId = 1; +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); + +extern GLXContext *openGLContext; +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); + +// 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); -pxError createInternalContext(int &id, bool /*depthBuffer*/) + if (!where) + break; + + terminator = where + strlen(extension); + + if ( where == start || *(where - 1) == ' ' ) + if ( *terminator == ' ' || *terminator == '\0' ) + return true; + + start = terminator; + } + + return false; +} +std::map internalContexts; +static bool ctxErrorOccurred = false; +static int ctxErrorHandler( Display *dpy, XErrorEvent *ev ) +{ + ctxErrorOccurred = true; + return 0; +} +GLXContext* getContext() { - id = nextInternalContextId++; - //TODO + Display *display = XOpenDisplay(NULL); + + if (!display) + { + printf("Failed to open X display\n"); + return NULL; + } + + // 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"); + return NULL; + } + + 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" ); + return NULL; + } + 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 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", 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" ); + return NULL; + } + + // 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 + glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) + 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. + bool 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 2.1 context! + else + { + int context_attribs[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 2, + GLX_CONTEXT_MINOR_VERSION_ARB, 1, + //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 2.1 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 2.1 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" ); + return NULL; + } + + // 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 ); + + glClearColor( 0, 0.5, 1, 1 ); + glClear( GL_COLOR_BUFFER_BIT ); + glXSwapBuffers ( display, win ); + + glClearColor ( 1, 0.5, 0, 1 ); + glClear ( GL_COLOR_BUFFER_BIT ); + glXSwapBuffers ( display, win ); + + glXMakeCurrent( display, 0, 0 ); + glXDestroyContext( display, ctx ); + + XDestroyWindow( display, win ); + XFreeColormap( display, cmap ); + XCloseDisplay( display ); + + return &ctx; +} + +pxError createGLContext(int id, bool depthBuffer) +{ + GLXContext *context = NULL; + rtMutexLockGuard eglContextMutexGuard(eglContextMutex); + if ( internalContexts.find(id) != internalContexts.end() ) + { + context = internalContexts.at(id); + } + if (context == NULL) + { + internalContexts[id] = getContext(); + } + return PX_OK; +} + +pxError createInternalContext(int &id, bool depthBuffer) +{ + { + rtMutexLockGuard eglContextMutexGuard(eglContextMutex); + id = nextInternalContextId++; + } + createGLContext(id, depthBuffer); return PX_OK; } -pxError deleteInternalGLContext(int) +pxError deleteInternalGLContext(int id) { - //TODO + rtMutexLockGuard eglContextMutexGuard(eglContextMutex); + if ( internalContexts.find(id) != internalContexts.end() ) + { + internalContexts.erase(id); + } return PX_OK; } -pxError makeInternalGLContextCurrent(bool, int) +pxError makeInternalGLContextCurrent(bool current, int id) { - //TODO + if (current) + { + GLXContext *context = NULL; + { + rtMutexLockGuard eglContextMutexGuard(eglContextMutex); + if (internalContexts.find(id) != internalContexts.end()) + { + context = internalContexts.at(id); + } + } + if (context != NULL) + { + createGLContext(id, false); + { + rtMutexLockGuard eglContextMutexGuard(eglContextMutex); + context = internalContexts[id]; + } + // [context makeCurrentContext]; + + #if 0 + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + #endif + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + } + glContextIsCurrent = true; + } + else + { + glFlush(); + // [openGLContext makeCurrentContext]; + glContextIsCurrent = false; + } return PX_OK; } From 3bafff97e1c7c4b0c0822744fbc8d897974f17a8 Mon Sep 17 00:00:00 2001 From: ashkalokhe Date: Wed, 1 Apr 2020 10:43:56 -0400 Subject: [PATCH 2/2] clean up --- examples/pxScene2d/src/glut/pxContextUtils.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/pxScene2d/src/glut/pxContextUtils.cpp b/examples/pxScene2d/src/glut/pxContextUtils.cpp index ec16f5f066..dfdfc893a8 100644 --- a/examples/pxScene2d/src/glut/pxContextUtils.cpp +++ b/examples/pxScene2d/src/glut/pxContextUtils.cpp @@ -83,6 +83,7 @@ static int ctxErrorHandler( Display *dpy, XErrorEvent *ev ) ctxErrorOccurred = true; return 0; } + GLXContext* getContext() { Display *display = XOpenDisplay(NULL);