| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197 |
- #ifndef B3_USE_GLFW
- #include "X11OpenGLWindow.h"
- #include "OpenGLInclude.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include "glad/gl.h"
- #ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
- #include "glad/glx.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)
- {
- // TODO: Properly handle this error.
- fprintf(stderr, "Error opening X11 library %s: %s\n", X11_LIBRARY, dlerror());
- exit(EXIT_FAILURE);
- }
- bool missingFunc = false;
- missingFunc = ((m_x11_XFree = (PFNXFREE)dlsym(m_x11_library, "XFree")) == NULL) | missingFunc;
- assert(!missingFunc);
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XFree in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XSetErrorHandler = (PFNXSETERRORHANDLER)dlsym(m_x11_library, "XSetErrorHandler")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XSetErrorHandler in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XSetErrorHandler = (PFNXSETERRORHANDLER)dlsym(m_x11_library, "XSetErrorHandler")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XSetErrorHandler in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XSync = (PFNXSYNC)dlsym(m_x11_library, "XSync")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XSync in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XOpenDisplay = (PFNXOPENDISPLAY)dlsym(m_x11_library, "XOpenDisplay")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XOpenDisplay in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XCreateColormap = (PFNXCREATECOLORMAP)dlsym(m_x11_library, "XCreateColormap")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XCreateColormap in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XCreateWindow = (PFNXCREATEWINDOW)dlsym(m_x11_library, "XCreateWindow")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XCreateWindow in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XMapWindow = (PFNXMAPWINDOW)dlsym(m_x11_library, "XMapWindow")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XMapWindow in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XStoreName = (PFNXSTORENAME)dlsym(m_x11_library, "XStoreName")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XStoreName in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XCloseDisplay = (PFNXCLOSEDISPLAY)dlsym(m_x11_library, "XCloseDisplay")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XCloseDisplay in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XDestroyWindow = (PFNXDESTROYWINDOW)dlsym(m_x11_library, "XDestroyWindow")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XDestroyWindow in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XRaiseWindow = (PFNXRAISEWINDOW)dlsym(m_x11_library, "XRaiseWindow")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XRaiseWindow in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XGetKeyboardMapping = (PFNXGETKEYBOARDMAPPING)dlsym(m_x11_library, "XGetKeyboardMapping")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XGetKeyboardMapping in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XKeycodeToKeysym = (PFNXKEYCODETOKEYSYM)dlsym(m_x11_library, "XKeycodeToKeysym")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XKeycodeToKeysym in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XConvertCase = (PFNXCONVERTCASE)dlsym(m_x11_library, "XConvertCase")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XConvertCase in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XPending = (PFNXPENDING)dlsym(m_x11_library, "XPending")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XPending in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XNextEvent = (PFNXNEXTEVENT)dlsym(m_x11_library, "XNextEvent")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XNextEvent in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XEventsQueued = (PFNXEVENTSQUEUED)dlsym(m_x11_library, "XEventsQueued")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XEventsQueued in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XPeekEvent = (PFNXPEEKEVENT)dlsym(m_x11_library, "XPeekEvent")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XPeekEvent in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XLookupKeysym = (PFNXLOOKUPKEYSYM)dlsym(m_x11_library, "XLookupKeysym")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XLookupKeysym in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- missingFunc = ((m_x11_XGetWindowAttributes = (PFNXGETWINDOWATTRIBUTES)dlsym(m_x11_library, "XGetWindowAttributes")) == NULL) | missingFunc;
- if (missingFunc)
- {
- fprintf(stderr, "Error: missing func XGetWindowAttributes in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- if (missingFunc)
- {
- fprintf(stderr, "Error: a missing func in %s, exiting!\n", X11_LIBRARY);
- exit(EXIT_FAILURE);
- }
- 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.3
- // 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.3 context!
- else
- {
- int context_attribs[] = {
- GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
- GLX_CONTEXT_MINOR_VERSION_ARB, 3,
- 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.3 context\n");
- else
- {
- // Couldn't create GL 3.3 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.3 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)
- {
- fprintf(stderr, "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);
- }
- if (!gladLoaderLoadGL())
- {
- printf("gladLoadGL failed!\n");
- exit(-1);
- }
- 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
- #if !defined(__NetBSD__) && !defined(__ANDROID__)
- int i = pthread_getconcurrency();
- printf("pthread_getconcurrency()=%d\n", i);
- #endif
- // 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);
- m_data->m_glWidth = ci.m_width;
- m_data->m_glHeight = ci.m_height;
- if (m_data->m_dpy == NULL)
- {
- fprintf(stderr, "\n\tcannot connect to X server\n\n");
- exit(EXIT_FAILURE);
- }
- m_data->m_root = DefaultRootWindow(m_data->m_dpy);
- #ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
- int res = gladLoaderLoadGLX(m_data->m_dpy, DefaultScreen(m_data->m_dpy));
- if (!res)
- {
- printf("Error in gladLoadGLX\n");
- exit(0);
- }
- #endif
- 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)))
- {
- fprintf(stderr, "Invalid GLX version: major %d, minor %d\n", glxMajor, glxMinor);
- exit(EXIT_FAILURE);
- }
- 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)
- {
- fprintf(stderr, "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)
- {
- fprintf(stderr, "Cannot create window\n");
- exit(EXIT_FAILURE);
- }
- 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)
- {
- fprintf(stderr, "\n\tno appropriate visual found\n\n");
- exit(EXIT_FAILURE);
- }
- 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 1
- 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;
- if (!is_retriggered)
- (*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;
- }
- #endif
|