summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp')
-rw-r--r--Build/source/utils/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp1118
1 files changed, 1118 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp b/Build/source/utils/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp
new file mode 100644
index 00000000000..68aa22720b9
--- /dev/null
+++ b/Build/source/utils/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp
@@ -0,0 +1,1118 @@
+#include "X11OpenGLWindow.h"
+#include "OpenGLInclude.h"
+
+#include<stdio.h>
+#include<stdlib.h>
+#ifdef GLEW_STATIC
+#include "CustomGL/glew.h"
+#else
+#include <GL/glew.h>
+#endif//GLEW_STATIC
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+#include "CustomGL/glxew.h"
+#else
+#include<GL/glx.h>
+#endif // GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+#include <assert.h>
+
+//#define DYNAMIC_LOAD_X11_FUNCTIONS
+#ifdef DYNAMIC_LOAD_X11_FUNCTIONS
+#include <dlfcn.h>
+#endif //DYNAMIC_LOAD_X11_FUNCTIONS
+
+//#include<X11/X.h>
+//#include<X11/Xlib.h>
+//#include<GL/gl.h>
+
+//defined in GL/glxew.h
+//#include<GL/glu.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <pthread.h>
+
+GLint att[] = { GLX_RGBA,
+GLX_DEPTH_SIZE, 24,
+GLX_RED_SIZE , 8,
+GLX_GREEN_SIZE , 8,
+GLX_BLUE_SIZE , 8,
+GLX_ALPHA_SIZE , 8,
+GLX_STENCIL_SIZE , 8,
+GLX_DOUBLEBUFFER,
+None };
+/*
+ static int att[] =
+ {
+ GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None
+
+ 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,
+ None
+ };
+*/
+static bool forceOpenGL3 = true;
+
+
+
+#ifdef DYNAMIC_LOAD_X11_FUNCTIONS
+
+///our X11 function typedefs
+
+typedef int (*PFNXFREE)(void*);
+typedef XErrorHandler (* PFNXSETERRORHANDLER) (XErrorHandler);
+typedef int (* PFNXSYNC) (Display* a,Bool b);
+typedef Display* (* PFNXOPENDISPLAY) (_Xconst char* a);
+typedef Colormap (*PFNXCREATECOLORMAP) (Display* a,Window b,Visual* c,int d);
+typedef Window (*PFNXCREATEWINDOW) (Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,int h,unsigned int i,Visual* j,unsigned long k,XSetWindowAttributes* l);
+typedef int (*PFNXMAPWINDOW) (Display*, Window);
+typedef int (*PFNXSTORENAME) (Display* a,Window b,_Xconst char* c);
+typedef int (*PFNXCLOSEDISPLAY) (Display* a);
+typedef int (*PFNXDESTROYWINDOW) (Display* a,Window b);
+typedef int (*PFNXRAISEWINDOW) (Display* a, Window b);
+
+#if NeedWidePrototypes
+ typedef KeySym* (*PFNXGETKEYBOARDMAPPING) (Display*,unsigned int,int,int*);
+ typedef KeySym (*PFNXKEYCODETOKEYSYM) (Display* a,unsigned int b,int c);
+#else
+ typedef KeySym* (*PFNXGETKEYBOARDMAPPING) (Display*,KeyCode,int,int*);
+ typedef KeySym (*PFNXKEYCODETOKEYSYM) (Display* a,KeyCode b,int c);
+#endif
+typedef void (*PFNXCONVERTCASE) (KeySym /* sym */,KeySym * /* lower */,KeySym * /* upper */);
+typedef int (*PFNXPENDING) (Display* a);
+typedef int (*PFNXNEXTEVENT) (Display* a,XEvent* b);
+typedef int (*PFNXEVENTSQUEUED) (Display* a,int b);
+typedef int (*PFNXPEEKEVENT) (Display* a,XEvent* b);
+typedef KeySym (*PFNXLOOKUPKEYSYM) (XKeyEvent* a,int b);
+typedef Status (*PFNXGETWINDOWATTRIBUTES) (Display* a,Window b,XWindowAttributes* c);
+
+#define X11_LIBRARY "libX11.so.6"
+
+#define MyXSync m_data->m_x11_XSync
+#define MyXGetKeyboardMapping m_data->m_x11_XGetKeyboardMapping
+#define MyXSetErrorHandler m_data->m_x11_XSetErrorHandler
+#define MyXOpenDisplay m_data->m_x11_XOpenDisplay
+#define MyXCreateColormap m_data->m_x11_XCreateColormap
+#define MyXCreateWindow m_data->m_x11_XCreateWindow
+#define MyXMapWindow m_data->m_x11_XMapWindow
+#define MyXStoreName m_data->m_x11_XStoreName
+#define MyXDestroyWindow m_data->m_x11_XDestroyWindow
+#define MyXRaiseWindow m_data->m_x11_XRaiseWindow
+#define MyXCloseDisplay m_data->m_x11_XCloseDisplay
+#define MyXKeycodeToKeysym m_data->m_x11_XKeycodeToKeysym
+#define MyXConvertCase m_data->m_x11_XConvertCase
+#define MyXPending m_data->m_x11_XPending
+#define MyXNextEvent m_data->m_x11_XNextEvent
+#define MyXEventsQueued m_data->m_x11_XEventsQueued
+#define MyXPeekEvent m_data->m_x11_XPeekEvent
+#define MyXNextEvent m_data->m_x11_XNextEvent
+#define MyXGetWindowAttributes m_data->m_x11_XGetWindowAttributes
+#define MyXStoreName m_data->m_x11_XStoreName
+#define MyXFree m_data->m_x11_XFree
+#define MyXMapWindow m_data->m_x11_XMapWindow
+#define MyXStoreName m_data->m_x11_XStoreName
+#define MyXLookupKeysym m_data->m_x11_XLookupKeysym
+
+#else
+#define MyXSync XSync
+#define MyXGetKeyboardMapping XGetKeyboardMapping
+#define MyXSetErrorHandler XSetErrorHandler
+#define MyXOpenDisplay XOpenDisplay
+#define MyXCreateColormap XCreateColormap
+#define MyXCreateWindow XCreateWindow
+#define MyXMapWindow XMapWindow
+#define MyXStoreName XStoreName
+#define MyXDestroyWindow XDestroyWindow
+#define MyXRaiseWindow XRaiseWindow
+#define MyXCloseDisplay XCloseDisplay
+#define MyXKeycodeToKeysym XKeycodeToKeysym
+#define MyXConvertCase XConvertCase
+#define MyXPending XPending
+#define MyXNextEvent XNextEvent
+#define MyXEventsQueued XEventsQueued
+#define MyXPeekEvent XPeekEvent
+#define MyXNextEvent XNextEvent
+#define MyXGetWindowAttributes XGetWindowAttributes
+#define MyXStoreName XStoreName
+#define MyXFree XFree
+#define MyXMapWindow XMapWindow
+#define MyXStoreName XStoreName
+#define MyXLookupKeysym XLookupKeysym
+
+#endif//DYNAMIC_LOAD_X11_FUNCTIONS
+
+enum
+{
+ MY_X11_ALT_KEY = 1,
+ MY_X11_SHIFT_KEY = 2,
+ MY_X11_CONTROL_KEY = 4
+};
+
+struct InternalData2
+{
+ Display* m_dpy;
+ Window m_root;
+ XVisualInfo* m_vi;
+ Colormap m_cmap;
+ XSetWindowAttributes m_swa;
+ Window m_win;
+ GLXContext m_glc;
+ XWindowAttributes m_gwa;
+ XEvent m_xev;
+ GLXFBConfig m_bestFbc;
+ int m_modifierFlags;
+ int m_glWidth;
+ int m_glHeight;
+
+#ifdef DYNAMIC_LOAD_X11_FUNCTIONS
+ //dynamically load stuff
+ void* m_x11_library;
+ PFNXFREE m_x11_XFree;
+ PFNXSETERRORHANDLER m_x11_XSetErrorHandler;
+ PFNXSYNC m_x11_XSync;
+ PFNXOPENDISPLAY m_x11_XOpenDisplay;
+ PFNXCREATECOLORMAP m_x11_XCreateColormap;
+ PFNXCREATEWINDOW m_x11_XCreateWindow;
+ PFNXMAPWINDOW m_x11_XMapWindow;
+ PFNXSTORENAME m_x11_XStoreName;
+ PFNXCLOSEDISPLAY m_x11_XCloseDisplay;
+ PFNXDESTROYWINDOW m_x11_XDestroyWindow;
+ PFNXRAISEWINDOW m_x11_XRaiseWindow;
+ PFNXKEYCODETOKEYSYM m_x11_XKeycodeToKeysym;
+ PFNXGETKEYBOARDMAPPING m_x11_XGetKeyboardMapping;
+ PFNXCONVERTCASE m_x11_XConvertCase;
+ PFNXPENDING m_x11_XPending;
+ PFNXNEXTEVENT m_x11_XNextEvent;
+ PFNXEVENTSQUEUED m_x11_XEventsQueued;
+ PFNXPEEKEVENT m_x11_XPeekEvent;
+ PFNXLOOKUPKEYSYM m_x11_XLookupKeysym;
+ PFNXGETWINDOWATTRIBUTES m_x11_XGetWindowAttributes;
+#endif //DYNAMIC_LOAD_X11_FUNCTIONS
+
+ b3WheelCallback m_wheelCallback;
+ b3MouseMoveCallback m_mouseMoveCallback;
+ b3MouseButtonCallback m_mouseButtonCallback;
+ b3ResizeCallback m_resizeCallback;
+ b3KeyboardCallback m_keyboardCallback;
+
+ InternalData2()
+ :m_dpy(0),
+ m_vi(0),
+ m_modifierFlags(0),
+ m_glWidth(-1),
+ m_glHeight(-1),
+ m_wheelCallback(0),
+ m_mouseMoveCallback(0),
+ m_mouseButtonCallback(0),
+ m_resizeCallback(0),
+ m_keyboardCallback(0)
+ {
+#ifdef DYNAMIC_LOAD_X11_FUNCTIONS
+ m_x11_library = dlopen(X11_LIBRARY, RTLD_LOCAL | RTLD_NOW);
+ if (!m_x11_library)
+ {
+ printf("Error opening X11 library %s\n", X11_LIBRARY);
+ exit(0);
+ }
+
+ bool missingFunc = false;
+
+ missingFunc = ((m_x11_XFree = (PFNXFREE) dlsym(m_x11_library, "XFree"))==NULL) | missingFunc;
+ assert(!missingFunc);
+ if (missingFunc) { printf("Error: missing func XFree in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XSetErrorHandler = (PFNXSETERRORHANDLER) dlsym(m_x11_library,"XSetErrorHandler"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XSetErrorHandler in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XSetErrorHandler = (PFNXSETERRORHANDLER) dlsym(m_x11_library,"XSetErrorHandler"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XSetErrorHandler in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XSync = (PFNXSYNC) dlsym(m_x11_library,"XSync"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XSync in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XOpenDisplay = (PFNXOPENDISPLAY) dlsym(m_x11_library,"XOpenDisplay"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XOpenDisplay in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XCreateColormap = (PFNXCREATECOLORMAP) dlsym(m_x11_library,"XCreateColormap"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XCreateColormap in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XCreateWindow = (PFNXCREATEWINDOW) dlsym(m_x11_library,"XCreateWindow"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XCreateWindow in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XMapWindow = (PFNXMAPWINDOW) dlsym(m_x11_library,"XMapWindow"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XMapWindow in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XStoreName = (PFNXSTORENAME) dlsym(m_x11_library,"XStoreName"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XStoreName in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XCloseDisplay = (PFNXCLOSEDISPLAY) dlsym(m_x11_library,"XCloseDisplay"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XCloseDisplay in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XDestroyWindow = (PFNXDESTROYWINDOW) dlsym(m_x11_library,"XDestroyWindow"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XDestroyWindow in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XRaiseWindow = (PFNXRAISEWINDOW) dlsym(m_x11_library,"XRaiseWindow"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XRaiseWindow in %s, exiting!\n", X11_LIBRARY); exit(0);}
+
+ missingFunc = ((m_x11_XGetKeyboardMapping = (PFNXGETKEYBOARDMAPPING) dlsym(m_x11_library,"XGetKeyboardMapping"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XGetKeyboardMapping in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XKeycodeToKeysym = (PFNXKEYCODETOKEYSYM) dlsym(m_x11_library,"XKeycodeToKeysym"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XKeycodeToKeysym in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XConvertCase = (PFNXCONVERTCASE) dlsym(m_x11_library,"XConvertCase"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XConvertCase in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XPending = (PFNXPENDING) dlsym(m_x11_library,"XPending"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XPending in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XNextEvent = (PFNXNEXTEVENT) dlsym(m_x11_library,"XNextEvent"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XNextEvent in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XEventsQueued = (PFNXEVENTSQUEUED) dlsym(m_x11_library,"XEventsQueued"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XEventsQueued in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XPeekEvent = (PFNXPEEKEVENT) dlsym(m_x11_library,"XPeekEvent"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XPeekEvent in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XLookupKeysym = (PFNXLOOKUPKEYSYM) dlsym(m_x11_library,"XLookupKeysym"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XLookupKeysym in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XGetWindowAttributes = (PFNXGETWINDOWATTRIBUTES) dlsym(m_x11_library,"XGetWindowAttributes"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XGetWindowAttributes in %s, exiting!\n", X11_LIBRARY); exit(0);}
+
+ if (missingFunc)
+ {
+ printf("Error: a missing func in %s, exiting!\n", X11_LIBRARY);
+ exit(0);
+ } else
+ {
+ printf("X11 functions dynamically loaded using dlopen/dlsym OK!\n");
+ }
+#endif //DYNAMIC_LOAD_X11_FUNCTIONS
+ }
+};
+
+#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);
+
+ 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;
+}
+
+
+
+
+X11OpenGLWindow::X11OpenGLWindow()
+:m_OpenGLInitialized(false),
+m_requestedExit(false)
+{
+ m_data = new InternalData2;
+}
+
+X11OpenGLWindow::~X11OpenGLWindow()
+{
+ if (m_OpenGLInitialized)
+ {
+ disableOpenGL();
+ }
+
+ delete m_data;
+}
+
+
+
+void X11OpenGLWindow::enableOpenGL()
+{
+
+
+ if (forceOpenGL3)
+ {
+ // Get the default screen's GLX extension list
+ const char *glxExts = glXQueryExtensionsString( m_data->m_dpy,
+ DefaultScreen( m_data->m_dpy ) );
+
+ // NOTE: It is not necessary to create or make current to a context before
+ // calling glXGetProcAddressARB, unless we dynamically load OpenGL/GLX/X11
+
+ 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.
+ ctxErrorOccurred = false;
+ int (*oldHandler)(Display*, XErrorEvent*) =
+ MyXSetErrorHandler(&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( m_data->m_dpy, m_data->m_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, 2,
+ GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
+ GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,None
+ };
+/*
+ int context_attribs[] =
+ {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+
+ //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+ None
+ };
+*/
+ printf( "Creating context\n" );
+ ctx = glXCreateContextAttribsARB( m_data->m_dpy, m_data->m_bestFbc, 0,
+ True, context_attribs );
+
+ // Sync to ensure any errors generated are processed.
+ MyXSync( m_data->m_dpy, 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( m_data->m_dpy, m_data->m_bestFbc, 0,
+ True, context_attribs );
+ }
+ }
+
+ // Sync to ensure any errors generated are processed.
+ MyXSync( m_data->m_dpy, False );
+
+ // Restore the original error handler
+ MyXSetErrorHandler( oldHandler );
+
+ if ( ctxErrorOccurred || !ctx )
+ {
+ printf( "Failed to create an OpenGL context\n" );
+ exit(1);
+ }
+
+ // Verifying that context is a direct context
+ if ( ! glXIsDirect ( m_data->m_dpy, ctx ) )
+ {
+ printf( "Indirect GLX rendering context obtained\n" );
+ }
+ else
+ {
+ printf( "Direct GLX rendering context obtained\n" );
+ }
+
+ printf( "Making context current\n" );
+ glXMakeCurrent( m_data->m_dpy, m_data->m_win, ctx );
+ m_data->m_glc = ctx;
+
+ } else
+ {
+ m_data->m_glc = glXCreateContext(m_data->m_dpy, m_data->m_vi, NULL, GL_TRUE);
+ glXMakeCurrent(m_data->m_dpy, m_data->m_win, m_data->m_glc);
+ }
+
+#ifdef GLEW_INIT_OPENGL11_FUNCTIONS
+{
+ GLboolean res = glewOpenGL11Init();
+ if (res==0)
+ {
+ printf("glewOpenGL11Init OK!\n");
+ } else
+ {
+ printf("ERROR: glewOpenGL11Init failed, exiting!\n");
+ exit(0);
+ }
+}
+
+#endif //GLEW_INIT_OPENGL11_FUNCTIONS
+
+ const GLubyte* ven = glGetString(GL_VENDOR);
+ printf("GL_VENDOR=%s\n", ven);
+
+ const GLubyte* ren = glGetString(GL_RENDERER);
+ printf("GL_RENDERER=%s\n",ren);
+ const GLubyte* ver = glGetString(GL_VERSION);
+ printf("GL_VERSION=%s\n", ver);
+ const GLubyte* sl = glGetString(GL_SHADING_LANGUAGE_VERSION);
+ printf("GL_SHADING_LANGUAGE_VERSION=%s\n", sl);
+
+//Access pthreads as a workaround for a bug in Linux/Ubuntu
+//See https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers-319/+bug/1248642
+
+ int i=pthread_getconcurrency();
+ printf("pthread_getconcurrency()=%d\n",i);
+
+// const GLubyte* ext = glGetString(GL_EXTENSIONS);
+// printf("GL_EXTENSIONS=%s\n", ext);
+}
+
+void X11OpenGLWindow::disableOpenGL()
+{
+ glXMakeCurrent(m_data->m_dpy, None, NULL);
+ glXDestroyContext(m_data->m_dpy, m_data->m_glc);
+}
+
+
+void X11OpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
+{
+
+ m_data->m_dpy = MyXOpenDisplay(NULL);
+
+ if(m_data->m_dpy == NULL) {
+ printf("\n\tcannot connect to X server\n\n");
+ exit(0);
+ }
+
+ m_data->m_root = DefaultRootWindow(m_data->m_dpy);
+
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+GLboolean res = glewXInit();
+if (res==0)
+{
+ printf("glewXInit OK\n");
+} else
+{
+ printf("glewXInit failed, exit\n");
+ exit(0);
+}
+#endif //GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+
+ if (ci.m_openglVersion < 3)
+ {
+ forceOpenGL3 = false;
+ }
+
+ if (forceOpenGL3)
+ {
+ int glxMinor, glxMajor;
+ if (!glXQueryVersion(m_data->m_dpy,&glxMajor,&glxMinor) || (((glxMajor==1)&&(glxMinor<3)) || (glxMajor<1)))
+ {
+ printf("Invalid GLX version: major %d, minor %d\n",glxMajor,glxMinor);
+ exit(0);
+ }
+
+ 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,
+ None
+ };
+ int fbcount;
+ GLXFBConfig* fbc = glXChooseFBConfig(m_data->m_dpy, DefaultScreen(m_data->m_dpy), visual_attribs, &fbcount);
+ if (!fbc)
+ {
+ printf( "Failed to retrieve a framebuffer config\n" );
+ exit(1);
+ }
+///don't use highest samples, it is really slow on some NVIDIA Quadro cards
+#ifdef USE_HIGHEST_SAMPLES
+ 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( m_data->m_dpy, fbc[i] );
+ if ( vi )
+ {
+ int samp_buf, samples;
+ glXGetFBConfigAttrib( m_data->m_dpy, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
+ glXGetFBConfigAttrib( m_data->m_dpy, 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;
+ }
+ MyXFree( vi );
+ }
+
+ m_data->m_bestFbc = fbc[ best_fbc ];
+#else
+ m_data->m_bestFbc = *fbc;
+#endif
+ // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
+ MyXFree( fbc );
+
+ m_data->m_vi = glXGetVisualFromFBConfig( m_data->m_dpy, m_data->m_bestFbc );
+
+
+ m_data->m_swa.colormap = m_data->m_cmap = MyXCreateColormap( m_data->m_dpy,
+ RootWindow( m_data->m_dpy, m_data->m_vi->screen ),
+ m_data->m_vi->visual, AllocNone );
+ m_data->m_swa.background_pixmap = None ;
+ m_data->m_swa.border_pixel = 0;
+ m_data->m_swa.event_mask = ExposureMask | KeyReleaseMask | KeyPressMask |ButtonPressMask | ButtonReleaseMask |PointerMotionMask|StructureNotifyMask;
+;
+ m_data->m_root = RootWindow( m_data->m_dpy, m_data->m_vi->screen );
+
+ m_data->m_win = MyXCreateWindow( m_data->m_dpy, m_data->m_root,
+ 0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput,
+ m_data->m_vi->visual,
+ CWBorderPixel|CWColormap|CWEventMask, &m_data->m_swa );
+
+ //m_data->m_win = m_data->m_x11_XCreateWindow(m_data->m_dpy, m_data->m_root, 0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput, m_data->m_vi->visual, CWColormap | CWEventMask, &m_data->m_swa);
+
+
+ if (!m_data->m_win)
+ {
+ printf("Cannot create window\n");
+ exit(0);
+ }
+
+ MyXMapWindow(m_data->m_dpy, m_data->m_win);
+ MyXStoreName(m_data->m_dpy, m_data->m_win, "OpenGL3 Window");
+
+
+ } else
+ {
+ m_data->m_vi = glXChooseVisual(m_data->m_dpy, 0, att);
+
+ printf("4\n");
+
+ if(m_data->m_vi == NULL) {
+ printf("\n\tno appropriate visual found\n\n");
+ exit(0);
+ }
+ else {
+ printf("\n\tvisual %p selected\n", (void *)m_data->m_vi->visualid); /* %p creates hexadecimal output like in glxinfo */
+ }
+
+
+ m_data->m_cmap = MyXCreateColormap(m_data->m_dpy, m_data->m_root, m_data->m_vi->visual, AllocNone);
+ m_data->m_swa.colormap = m_data->m_cmap;
+ m_data->m_swa.event_mask = ExposureMask | KeyReleaseMask | KeyPressMask |ButtonPressMask | ButtonReleaseMask |PointerMotionMask|StructureNotifyMask;
+ m_data->m_win = MyXCreateWindow(m_data->m_dpy, m_data->m_root, 0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput, m_data->m_vi->visual, CWColormap | CWEventMask, &m_data->m_swa);
+
+ MyXMapWindow(m_data->m_dpy, m_data->m_win);
+
+ MyXStoreName(m_data->m_dpy, m_data->m_win, "OpenGL2 Window");
+
+
+ }
+
+ enableOpenGL();
+}
+
+void X11OpenGLWindow::closeWindow()
+{
+ disableOpenGL();
+
+ MyXDestroyWindow(m_data->m_dpy, m_data->m_win);
+ MyXCloseDisplay(m_data->m_dpy);
+}
+
+int X11OpenGLWindow::getAsciiCodeFromVirtualKeycode(int keycode)
+{
+ int result = 0;
+
+ KeySym key, key_lc, key_uc;
+
+ int keysyms_per_keycode_return;
+ KeySym *keysym = MyXGetKeyboardMapping(m_data->m_dpy,
+ keycode,
+ 1,
+ &keysyms_per_keycode_return);
+
+ key = keysym[0];
+
+
+ //key = MyXKeycodeToKeysym( m_data->m_dpy, keycode, 0 );
+
+ switch( key )
+ {
+ case XK_Escape: return B3G_ESCAPE;
+ case XK_Return: return B3G_RETURN;
+
+ case XK_Control_L:
+ case XK_Control_R: {
+ return B3G_CONTROL;
+ }
+ case XK_Left: return B3G_LEFT_ARROW;
+ case XK_Right: return B3G_RIGHT_ARROW;
+ case XK_Up: return B3G_UP_ARROW;
+ case XK_Down: return B3G_DOWN_ARROW;
+
+ case XK_Alt_L:
+ case XK_Alt_R:
+ {
+ return B3G_ALT;
+ }
+ case XK_Shift_L:
+ case XK_Shift_R: return B3G_SHIFT;
+ case XK_F1: return B3G_F1;
+ case XK_F2: return B3G_F2;
+ case XK_F3: return B3G_F3;
+ case XK_F4: return B3G_F4;
+ case XK_F5: return B3G_F5;
+ case XK_F6: return B3G_F6;
+ case XK_F7: return B3G_F7;
+ case XK_F8: return B3G_F8;
+ case XK_F9: return B3G_F9;
+ case XK_F10: return B3G_F10;
+ case XK_F11: return B3G_F11;
+ case XK_F12: return B3G_F12;
+ case XK_F13: return B3G_F13;
+ case XK_F14: return B3G_F14;
+ case XK_F15: return B3G_F15;
+ default:
+ // Make lowercase
+ MyXConvertCase( key, &key_lc, &key_uc );
+ key = key_lc;
+ // Valid ISO 8859-1 character?
+ if( (key >= 32 && key <= 126) ||(key >= 160 && key <= 255) )
+ {
+ return (int) key;
+ }
+ result = -1;
+ }
+
+ MyXFree(keysym);
+
+ return result;
+}
+
+bool X11OpenGLWindow::isModifierKeyPressed(int key)
+{
+ bool isPressed = false;
+
+ switch (key)
+ {
+ case B3G_ALT:
+ {
+ isPressed = ((m_data->m_modifierFlags & MY_X11_ALT_KEY)!=0);
+ break;
+ };
+ case B3G_SHIFT:
+ {
+ isPressed = ((m_data->m_modifierFlags & MY_X11_SHIFT_KEY)!=0);
+ break;
+ };
+ case B3G_CONTROL:
+ {
+ isPressed = ((m_data->m_modifierFlags & MY_X11_CONTROL_KEY )!=0);
+ break;
+ };
+
+ default:
+ {
+ }
+ };
+ return isPressed;
+}
+
+void X11OpenGLWindow::pumpMessage()
+{
+
+ int buttonState = 1;
+
+ // Process all pending events
+ while( MyXPending( m_data->m_dpy ) )
+ {
+ MyXNextEvent(m_data->m_dpy, &m_data->m_xev);
+ // printf("#");
+ // fflush(stdout);
+ switch( m_data->m_xev.type )
+ {
+ case KeyPress:
+ {
+ int keycode = getAsciiCodeFromVirtualKeycode(m_data->m_xev.xkey.keycode);
+ switch (keycode)
+ {
+ case B3G_ALT:
+ m_data->m_modifierFlags |= MY_X11_ALT_KEY;
+ break;
+ case B3G_SHIFT:
+ m_data->m_modifierFlags |= MY_X11_SHIFT_KEY;
+ break;
+ case B3G_CONTROL:
+ m_data->m_modifierFlags |= MY_X11_CONTROL_KEY;
+ break;
+ default:
+ {}
+ };
+ if (m_data->m_keyboardCallback)
+ {
+
+ int state = 1;
+ (*m_data->m_keyboardCallback)(keycode,state);
+ // printf("keycode %d",keycode);
+ // fflush(stdout);
+
+ }
+ break;
+ }
+
+ case KeyRelease:
+ {
+ // fflush(stdout);
+ int keycode = getAsciiCodeFromVirtualKeycode( m_data->m_xev.xkey.keycode);
+ switch (keycode)
+ {
+ case B3G_ALT:
+ m_data->m_modifierFlags &= ~MY_X11_ALT_KEY;
+ break;
+ case B3G_SHIFT:
+ m_data->m_modifierFlags &= ~MY_X11_SHIFT_KEY;
+ break;
+ case B3G_CONTROL:
+ m_data->m_modifierFlags &= ~MY_X11_CONTROL_KEY;
+ break;
+ default:
+ {}
+ };
+
+ if (m_data->m_keyboardCallback)
+ {
+#if 0
+ unsigned short is_retriggered = 0;
+///filter out keyboard repeat
+//see http://stackoverflow.com/questions/2100654/ignore-auto-repeat-in-x11-applications
+ if (MyXEventsQueued(m_data->m_dpy, QueuedAfterReading))
+ {
+ XEvent nev;
+ MyXPeekEvent(m_data->m_dpy, &nev);
+
+ if (nev.type == KeyPress && nev.xkey.time == m_data->m_xev.xkey.time &&
+ nev.xkey.keycode == m_data->m_xev.xkey.keycode)
+ {
+ fprintf (stdout, "key #%ld was retriggered.\n",
+ (long) MyXLookupKeysym(&nev.xkey, 0));
+
+ // delete retriggered KeyPress event
+ MyXNextEvent(m_data->m_dpy, & m_data->m_xev);
+ is_retriggered = 1;
+ }
+ }
+#endif
+ int state = 0;
+ (*m_data->m_keyboardCallback)(keycode,state);
+ }
+
+ break;
+ }
+
+ case ButtonRelease:
+ buttonState = 0;
+ //continue with ButtonPress code
+ case ButtonPress:
+ {
+// printf("!");
+// fflush(stdout);
+
+ int button=-1;
+
+ switch (m_data->m_xev.xbutton.button)
+ {
+ case Button1:
+ {
+ button=0;
+ break;
+ }
+ case Button2:
+ {
+ button=1;
+ break;
+ }
+ case Button3:
+ {
+ button=2;
+ break;
+ }
+ case Button4:
+ {
+ if (m_data->m_wheelCallback)
+ {
+ (*m_data->m_wheelCallback)(0,10);
+ }
+ break;
+ }
+ case Button5:
+ {
+ if (m_data->m_wheelCallback)
+ {
+ (*m_data->m_wheelCallback)(0,-10);
+ }
+ break;
+ }
+ }
+ int xpos = m_data->m_xev.xmotion.x;
+ int ypos = m_data->m_xev.xmotion.y;
+
+ if (button>=0 && m_data->m_mouseButtonCallback)
+ {
+// printf("xpos = %d, ypos = %d\n",xpos,ypos);
+
+ (*m_data->m_mouseButtonCallback)(button,buttonState,xpos,ypos);
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+// printf("!");
+// fflush(0);
+ if (m_data->m_mouseMoveCallback)
+ {
+ int xpos = m_data->m_xev.xmotion.x;
+ int ypos = m_data->m_xev.xmotion.y;
+ (*m_data->m_mouseMoveCallback)(xpos,ypos);
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ // printf("@");
+ // fflush(0);
+ m_data->m_glWidth = m_data->m_xev.xconfigure.width;
+ m_data->m_glHeight = m_data->m_xev.xconfigure.height;
+
+ if (m_data->m_resizeCallback)
+ {
+ (*m_data->m_resizeCallback)(m_data->m_xev.xconfigure.width,m_data->m_xev.xconfigure.height);
+ }
+ break;
+ }
+ case ClientMessage:
+ {
+ // printf("?");
+ // fflush(stdout);
+ break;
+ }
+ case Expose:
+ {
+ break;
+ }
+ case DestroyNotify:
+ {
+ break;
+ }
+ default:
+ {
+ //XRRUpdateConfiguration( &event );
+ }
+ };
+ }
+}
+
+
+
+void X11OpenGLWindow::startRendering()
+{
+ pumpMessage();
+
+ MyXGetWindowAttributes(m_data->m_dpy, m_data->m_win, &m_data->m_gwa);
+ glViewport(0, 0, m_data->m_gwa.width, m_data->m_gwa.height);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //clear buffers
+
+ //glCullFace(GL_BACK);
+ //glFrontFace(GL_CCW);
+ glEnable(GL_DEPTH_TEST);
+}
+
+void X11OpenGLWindow::renderAllObjects()
+{
+
+}
+
+void X11OpenGLWindow::endRendering()
+{
+ glXSwapBuffers(m_data->m_dpy, m_data->m_win);
+}
+
+void X11OpenGLWindow::runMainLoop()
+{
+
+}
+
+float X11OpenGLWindow::getTimeInSeconds()
+{
+ return 0.f;
+}
+
+bool X11OpenGLWindow::requestedExit() const
+{
+ return m_requestedExit;
+}
+
+void X11OpenGLWindow::setRequestExit()
+{
+ m_requestedExit=true;
+}
+
+void X11OpenGLWindow::setRenderCallback( b3RenderCallback renderCallback)
+{
+
+}
+
+void X11OpenGLWindow::setWindowTitle(const char* title)
+{
+ MyXStoreName(m_data->m_dpy, m_data->m_win, title);
+}
+
+
+void X11OpenGLWindow::setWheelCallback(b3WheelCallback wheelCallback)
+{
+ m_data->m_wheelCallback = wheelCallback;
+}
+
+void X11OpenGLWindow::setMouseMoveCallback(b3MouseMoveCallback mouseCallback)
+{
+ m_data->m_mouseMoveCallback = mouseCallback;
+}
+
+void X11OpenGLWindow::setMouseButtonCallback(b3MouseButtonCallback mouseCallback)
+{
+ m_data->m_mouseButtonCallback = mouseCallback;
+}
+
+void X11OpenGLWindow::setResizeCallback(b3ResizeCallback resizeCallback)
+{
+ if (resizeCallback && m_data->m_glWidth>0 && m_data->m_glHeight > 0)
+ {
+ resizeCallback(m_data->m_glWidth, m_data->m_glHeight);
+ }
+ m_data->m_resizeCallback = resizeCallback;
+}
+
+void X11OpenGLWindow::setKeyboardCallback( b3KeyboardCallback keyboardCallback)
+{
+ m_data->m_keyboardCallback = keyboardCallback;
+
+}
+
+b3MouseMoveCallback X11OpenGLWindow::getMouseMoveCallback()
+{
+ return m_data->m_mouseMoveCallback;
+}
+b3MouseButtonCallback X11OpenGLWindow::getMouseButtonCallback()
+{
+ return m_data->m_mouseButtonCallback;
+}
+b3ResizeCallback X11OpenGLWindow::getResizeCallback()
+{
+ return m_data->m_resizeCallback;
+}
+b3WheelCallback X11OpenGLWindow::getWheelCallback()
+{
+ return m_data->m_wheelCallback;
+}
+
+
+b3KeyboardCallback X11OpenGLWindow::getKeyboardCallback()
+{
+ return m_data->m_keyboardCallback;
+}
+
+int X11OpenGLWindow::getWidth() const
+{
+ if (m_data)
+ return m_data->m_glWidth;
+ return 0;
+}
+int X11OpenGLWindow::getHeight() const
+{
+ if (m_data)
+ return m_data->m_glHeight;
+ return 0;
+}
+
+
+#include <stdio.h>
+
+int X11OpenGLWindow::fileOpenDialog(char* filename, int maxNameLength)
+{
+ int len = 0;
+ FILE * output = popen("zenity --file-selection --file-filter=\"*.urdf\" --file-filter=\"*.sdf\" --file-filter=\"*.obj\" --file-filter=\"*.*\"","r");
+ if (output)
+ {
+ while( fgets(filename, maxNameLength-1, output) != NULL )
+ {
+ len=strlen(filename);
+ if (len>0)
+ {
+ filename[len-1]=0;
+ printf("file open (length=%d) = %s\n", len,filename);
+ }
+ }
+ pclose(output);
+ } else
+ {
+ printf("Error: fileOpenDialog no popen output, perhaps install zenity?\n");
+ }
+ MyXRaiseWindow(m_data->m_dpy, m_data->m_win);
+ return len;
+
+}