Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: help: problem getting OpenGL v4.30 context (or newer than OpenGL v2.10 context)

Hybrid View

  1. #1
    Intern Contributor
    Join Date
    Jan 2008
    Location
    phobos, mars
    Posts
    75

    help: problem getting OpenGL v4.30 context (or newer than OpenGL v2.10 context)

    NOTE: This is a continuation of a thread about problems with the glGenVertexArray() function, but apparently the problem is that my program is not getting a recent OpenGL context since I upgrated my GPU card from GTX285 to GTX680 and my nvidia driver from <who-knows> to <v310.19>. The new thread is because the old title is very misleading.

    -----

    Yes, I am almost sure the context is the problem. Further down you'll see that various output my program prints implies the program only has a OpenGL v2.12 context. Probably OpenGL v2.10 didn't support VAOs yet, hence the behavior.

    The program was running with OpenGL v3.30 context before I installed the latest nvidia driver on my 64-bit ubuntu v12.04 computer (nvidia driver 310.19, which is still shown as current as of today). After I installed the new driver, the program stopped working and the first error generated by my program was the VAO issue.

    So the question probably is, why is my program not getting an OpenGL v4.30 context?

    Since we seem to have narrowed down the problem to OpenGL context and not VAO functions, I create this new, appropriately named threat to continue this conversation.

    I have always had problems initializing the combination of xlib, GLX, GLEW, OpenGL. I have never been able to sufficiently grasp everything necessary about xlib, GLX, GLEW and OpenGL to fully understand what is necessary, much less appropriate.

    To be clear, I suspect I only need to handle the new OpenGL v4.30 context. I assume OpenGL v3.30 programs will also run on this newer context. If not, please say so.

    I guess the best way to attempt to resolve this is to explain exactly what I am doing now. Here goes:

    #1: Before anything significant happens in my program, it executes the ig_graphics_initialize() function, which only calls old-style GLX functions and creates, then destroys a window.

    #2: Later, after everything is initialized, the application creates a default window with newer GLX functions (and should-be most recent context). It was creating an OpenGL v3.30 context before I updated my nvidia driver to v310.19 (64-bit version).

    Next I'll be more specific and show the code in the ig_graphics_initialize() function, and then the ig_window_create() function. I suspect that something "minor" changed that obsoletes my old approach, and now requires something be done in a different order, or with different functions or arguments. But what do I know? Not much, obviously.

    I'll appreciate any tips or comments anyone might have, especially from xlib, GLX, GLEW, OpenGL initialization gurus.

    Code cpp:
    CORE_PUBLIC_DEFINE_CPU  ig_graphics_initialize (cpu mode, cpu options) {
    //
    // We must initialize GLX, OpenGL and GLEW.
    //
    // However, apparently we cannot initialize GLEW until we have created GLX and OpenGL contexts,
    // which requires we create an XWindows window, and then create a GLX/OpenGL [rendering] context.
    // Therefore, during application initialization, we must create an X window (no need to map it),
    // then create a GLX/OpenGL [rendering] context, then call glewInit(), then destroy the window
    // and the context - then free any resources we created to do all the above.
    //
    // By calling glewInit() we set up the addresses of all later-version GLX and OpenGL functions,
    // so henceforth we can create and manipulate GLX/OpenGL contexts with more advanced functions.
     
      int error = 0;
      static int glew_initialized = 0;
     
      Window xwindow = 0;
      Display* xdisplay = XOpenDisplay(NULL);
      int xscreen = XDefaultScreen (xdisplay);
      Window xroot = XRootWindow (xdisplay, xscreen);
      Window xwindow_root_default = XDefaultRootWindow (xdisplay);
      Screen* xscreen_default_of_display = XDefaultScreenOfDisplay (xdisplay);
      Screen* xscreen_of_display = XScreenOfDisplay (xdisplay, xscreen);
      GC xgraphics_context = XDefaultGC (xdisplay, xscreen);
      Visual* xvisual_default = XDefaultVisual (xdisplay, xscreen);
      int xdisplay_width = XDisplayWidth (xdisplay, xscreen);
      int xdisplay_height = XDisplayHeight (xdisplay, xscreen);
     
      Colormap              xcolormap;
      GLXWindow             glxwindow;
      GLXContext            glxcontext;
      XVisualInfo*          xvisualinfo = 0;
      GLXFBConfig*          glxfbconfig = 0;
      XSetWindowAttributes  xsetwindowattributes;
     
      int major = 0;
      int minor = 0;
      int errorbase = 0;
      int eventbase = 0;
    //
    // not sure what the following line is for, but see comments in various forums
    //
      glewExperimental = GL_TRUE;
     
      error = glXQueryVersion (xdisplay, &major, &minor);
      error = glXQueryExtension (xdisplay, &errorbase, &eventbase);
      const char* extensions = glXQueryExtensionsString (xdisplay, xscreen);
      const char* clientvendor = glXGetClientString (xdisplay, GLX_VENDOR);
      const char* clientversion = glXGetClientString (xdisplay, GLX_VERSION);
      const char* clientextensions = glXGetClientString (xdisplay, GLX_EXTENSIONS);
      const char* servervendor = glXQueryServerString (xdisplay, xscreen, GLX_VENDOR);
      const char* serverversion = glXQueryServerString (xdisplay, xscreen, GLX_VERSION);
      const char* serverextensions = glXQueryServerString (xdisplay, xscreen, GLX_EXTENSIONS);
     
      printf ("GLX version          ::: major.minor == %d.%d\n", major, minor);
      printf ("GLX offsets          ::: errorbase : eventbase == %d %d\n", errorbase, eventbase);
      printf ("GLX extensions       ::: <%s>\n", extensions);
      printf ("GLX clientvendor     ::: <%s>\n", clientvendor);
      printf ("GLX clientversion    ::: <%s>\n", clientversion);
      printf ("GLX clientextensions ::: <%s>\n", clientextensions);
      printf ("GLX servervendor     ::: <%s>\n", servervendor);
      printf ("GLX serverversion    ::: <%s>\n", serverversion);
      printf ("GLX serverextensions ::: <%s>\n", serverextensions);
    //
    // set up xvisualattributes[] array needed in glXChooseVisual() argument list
    //
      int xvisualattributes[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, 0 };
    //
    // create xvisualinfo so we can create GLX/OpenGL context so we can call glewInit()
    //
      xvisualinfo = glXChooseVisual (xdisplay, xscreen, xvisualattributes);
      if (xvisualinfo == 0) {
        printf ("glXChooseVisual() : error : xvisualinfo == 0 : GLX/OpenGL initialization failed\n");
        return (CORE_ERROR_INTERNAL);
      }
    //
    // create colormap so we can create GLX/OpenGL context so we can call glewInit()
    //
      xcolormap = XCreateColormap (xdisplay, xroot, xvisualinfo->visual, AllocNone);
      if (xcolormap == 0) {
        XFree (xvisualinfo);
        printf ("XCreateColormap() : error : xcolormap == 0 : GLX/OpenGL initialization failed\n");
        return (CORE_ERROR_INTERNAL);
      }
    //
    // #####  establish variables required to create the window  #####
    //
    // to eliminate events of one or more types, comment out the corresponding lines below
    //
      int xeventmask = 0;
      xeventmask = xeventmask | KeyPressMask;                 // bit  0
      xeventmask = xeventmask | KeyReleaseMask;               // bit  1
      xeventmask = xeventmask | ButtonPressMask;              // bit  2
      xeventmask = xeventmask | ButtonReleaseMask;            // bit  3
      xeventmask = xeventmask | EnterWindowMask;              // bit  4
      xeventmask = xeventmask | LeaveWindowMask;              // bit  5
      xeventmask = xeventmask | PointerMotionMask;            // bit  6
      xeventmask = xeventmask | PointerMotionHintMask;        // bit  7
      xeventmask = xeventmask | Button1MotionMask;            // bit  8
      xeventmask = xeventmask | Button2MotionMask;            // bit  9
      xeventmask = xeventmask | Button3MotionMask;            // bit 10
      xeventmask = xeventmask | Button4MotionMask;            // bit 11
      xeventmask = xeventmask | Button5MotionMask;            // bit 12
      xeventmask = xeventmask | ButtonMotionMask;             // bit 13
      xeventmask = xeventmask | KeymapStateMask;              // bit 14
      xeventmask = xeventmask | ExposureMask;                 // bit 15
      xeventmask = xeventmask | VisibilityChangeMask;         // bit 16
      xeventmask = xeventmask | StructureNotifyMask;          // bit 17
    //xeventmask = xeventmask | ResizeRedirectMask;           // bit 18   DANGER --- DO NOT ENABLE
      xeventmask = xeventmask | SubstructureNotifyMask;       // bit 19
      xeventmask = xeventmask | SubstructureRedirectMask;     // bit 20
      xeventmask = xeventmask | FocusChangeMask;              // bit 21
      xeventmask = xeventmask | PropertyChangeMask;           // bit 22
      xeventmask = xeventmask | ColormapChangeMask;           // bit 23
      xeventmask = xeventmask | OwnerGrabButtonMask;          // bit 24
     
      xsetwindowattributes.colormap = xcolormap;      // vanilla RGBA
      xsetwindowattributes.background_pixel = None;   // prevent background clear (let OpenGL glClear())
      xsetwindowattributes.background_pixmap = None;  // default = None
      xsetwindowattributes.border_pixmap = None;      // default = CopyFromParent
      xsetwindowattributes.border_pixel = None;       // default = Undefined
      xsetwindowattributes.cursor = None;             // default = None
      xsetwindowattributes.event_mask = xeventmask;   // 0x0001FFFF if events of all types are enabled
      xsetwindowattributes.bit_gravity = StaticGravity;
    //
    // assign values to any arguments to XCreateWindow() that are not already specified
    //
      int x = 32;
      int y = 32;
      int width = 640;
      int height = 480;
      int xselectattributes = (CWBackPixel | CWBorderPixel | CWBitGravity | CWColormap | CWEventMask);
    //
    // create xwindow so we can create GLX/OpenGL context so we can call glewInit()
    //
      xwindow = XCreateWindow (xdisplay, xroot, x, y, width, height, 0, xvisualinfo->depth, InputOutput, xvisualinfo->visual, xselectattributes, &xsetwindowattributes);
      if (xwindow == 0) {
        XFree (xvisualinfo);
        printf ("XCreateWindow() : error : xwindow == 0 : GLX/OpenGL initialization failed\n");
        return (CORE_ERROR_INTERNAL);
      }
    //
    // no need for the next 2 lines
    //
    //    XMapWindow (xdisplay, xwindow);
    //    XStoreName (xdisplay, xwindow, "GLX/OpenGL initialization");
    //
    // create GLX / OpenGL context so we can create GLX/OpenGL context so we can call glewInit()
    //
      glxcontext = glXCreateContext (xdisplay, xvisualinfo, 0, GL_TRUE);
      if (glxcontext == 0) {
        XFree (xvisualinfo);
        printf ("glXCreateContext() : error : glxcontext == 0 : GLX/OpenGL initialization failed\n");
        return (CORE_ERROR_INTERNAL);
      }
    //
    // make GLX / OpenGL context current == active
    //
      glXMakeCurrent (xdisplay, xwindow, glxcontext);
    //
    // call glewInit() to initialize GLX/OpenGL functions (so we can call those functions)
    //
      error = glewInit();
      if (error != GLEW_OK) {
        printf("glewInit() : error : %s\n", glewGetErrorString(error));
        return (CORE_ERROR_INTERNAL);
      } else {
        glew_initialized = 1;
        printf ("status: GLEW initialized %s\n", glewGetString(GLEW_VERSION));
      }
    //
    // destroy window, destroy GLX/OpenGL context
    //
      error = XUnmapWindow (xdisplay, xwindow);   // unmap window here if window mapped, else not needed
      error = XDestroyWindow (xdisplay, xwindow);
     
      glXDestroyContext (xdisplay, glxcontext);   // destroy GLX/OpenGL [rendering] context
      XFree (xvisualinfo);                        // free allocated resource
    //
    // test some basic OpenGL functions - and make sure OpenGL is initialized
    //
      const GLubyte* glvendor = glGetString (GL_VENDOR);
      const GLubyte* glversion = glGetString (GL_VERSION);
      const GLubyte* glrenderer = glGetString (GL_RENDERER);
      const GLubyte* glextensions = glGetString (GL_EXTENSIONS);
     
      printf ("OGL vendor           ::: %s\n", (char*)glvendor);
      printf ("OGL version          ::: %s\n", (char*)glversion);
      printf ("OGL renderer         ::: %s\n", (char*)glrenderer);
      printf ("OGL extensions       ::: %s\n", (char*)glextensions);
      return (0);
    }

    NOTE: You can skip the first ~130 lines below to get to the meat of the function (where real xlib, GLX, GLEW stuff happens)

    Code cpp:
    CORE_PUBLIC_DEFINE_CPU  ig_window_create (cpu winid, cpu options, cpu x, cpu y, cpu width, cpu height, cpu dispid) {
     
      int error = 0;
      int success = 0;
      int fullscreen = 0;
      int objects = igstate.object_after;
     
      static cpu glew_initialized = 0;
     
      ig_display* display = 0;
      display = (ig_display*)igstate.object[dispid];      // get display structure
      error = ig_window_new (winid, 0);                   // create and initialize new window structure
      if (error < 0) { return (error); }
     
      ig_window* window = 0;
      window = (ig_window*)igstate.object[winid];         // get address of window structure
    //
    // establish display characteristics
    //
      int display_width = display->width;
      int display_height = display->height;
      Display* xdisplay = display->xdisplay;
      Window xwindow = 0;
    //
    // NOTE: much of the following information was put into the IG display structure when the display was opened with XOpenDisplay() in ig_display_create().  In the long run we must work with the values from our display object so windows can be opened on other displays (on the same computer and across any network).
    //
      int xscreen = XDefaultScreen (xdisplay);
      Window xroot = XRootWindow (xdisplay, xscreen);
      Window xwindow_root_default = XDefaultRootWindow (xdisplay);
      Screen* xscreen_default_of_display = XDefaultScreenOfDisplay (xdisplay);
      Screen* xscreen_of_display = XScreenOfDisplay (xdisplay, xscreen);
      GC xgraphics_context = XDefaultGC (xdisplay, xscreen);
      Visual* xvisual_default = XDefaultVisual (xdisplay, xscreen);
      int xdisplay_width = XDisplayWidth (xdisplay, xscreen);
      int xdisplay_height = XDisplayHeight (xdisplay, xscreen);
     
      Colormap                xcolormap;
      XVisualInfo*            xvisualinfo = 0;
      XSetWindowAttributes    xsetwindowattributes;
      GLXWindow               glxwindow;
      GLXContext              glxcontext;
      GLXFBConfig*            glxfbconfig = 0;
    //
    // get system metrics --- size-in-pixels of window frame and title-bar
    //
      int cmo = 1;              // number of display-monitors on this/local computer
      int xfr = 4;              // frame width in pixels = 4 usually (on both left and right edges)
      int yfr = 4;              // frame height in pixels = 4 usually (on both top and bottom edges)
      int yca = 19;             // guess this value until we capture information in window message handler
      int xsc = display_width;  // full screen width - possibly reduced to support start/other bars
      int ysc = display_height; // full screen height - possibly reduced to support start/other bars
      int xfs = display_width;  // full screen width - not reduced by start-bar or other travesties
      int yfs = display_height; // full screen height - not reduced by start-bar or other travesties
    //
    // find functions to return the following values --- generally "window manager hints" in XWindows
    //
      if (x < 0) { x = 0; }                                // fix invalid x coordinate
      if (y < 0) { y = 0; }                                // fix invalid y coordinate
      if (x > display_width) { x = display_width - 32; }   // make window at least partially visible
      if (y > display_height) { y = display_height - 32; } // make window at least partially visible
      if (width <= 0) { options = options | IG_OPTION_WINDOW_FULLWIDTH; }   // width <= 0 is "full-width"
      if (height <= 0) { options = options | IG_OPTION_WINDOW_FULLHEIGHT; } // height <= 0 is "full-height"
      if (options & IG_OPTION_WINDOW_FULLSCREEN) { fullscreen = IG_OPTION_WINDOW_FULLSCREEN; }
      if ((options & IG_OPTION_WINDOW_FULLWIDTH) && (options & IG_OPTION_WINDOW_FULLHEIGHT)) { fullscreen = IG_OPTION_WINDOW_FULLSCREEN; }
    //
    // later need to support fullscreen window that HAS border, caption and minimize/maximize/close buttons
    //
      if (fullscreen) {        // fullscreen window if window width and height == display width and height
        x = 0;                 // origin is always at top-left corner of display
        y = 0;                 // origin is always at top-left corner of display
        xsc = 0;                                // ditto
        ysc = 0;                                // ditto
        xfr = 0;                                // ditto
        yfr = 0;                                // ditto
        yca = 0;                                // ditto
        width = display_width;                  // width == display_width
        height = display_height;                // height == display_height
      } else {
        if (x < xfr) { x = xfr; }                  // window border at left (4-pixels usually)
        if (y < (yfr + yca)) { y = (yfr + yca); }  // window border and title-bar at top
        if (display_width < (width - (xfr + xfr))) { width = display_width - (xfr + xfr); }
        if (display_height < (height - (yca + yfr + yfr))) { height = display_height - (yca + yfr + yfr); }
      }
     
      if (width < 16) { width = 16; }
      if (height < 16) { height = 16; }
    //
    // test basic GLX functions and get basic GLX information
    //
      int major = 0;
      int minor = 0;
      int errorbase = 0;
      int eventbase = 0;
     
      error = glXQueryVersion (xdisplay, &major, &minor);
      error = glXQueryExtension (xdisplay, &errorbase, &eventbase);
      const char* extensions = glXQueryExtensionsString (xdisplay, xscreen);
      const char* clientvendor = glXGetClientString (xdisplay, GLX_VENDOR);
      const char* clientversion = glXGetClientString (xdisplay, GLX_VERSION);
      const char* clientextensions = glXGetClientString (xdisplay, GLX_EXTENSIONS);
      const char* servervendor = glXQueryServerString (xdisplay, xscreen, GLX_VENDOR);
      const char* serverversion = glXQueryServerString (xdisplay, xscreen, GLX_VERSION);
      const char* serverextensions = glXQueryServerString (xdisplay, xscreen, GLX_EXTENSIONS);
     
      printf ("GLX version          ::: major.minor == %d.%d\n", major, minor);
      printf ("GLX offsets          ::: errorbase : eventbase == %d %d\n", errorbase, eventbase);
      printf ("GLX extensions       ::: <%s>\n", extensions);
      printf ("GLX clientvendor     ::: <%s>\n", clientvendor);
      printf ("GLX clientversion    ::: <%s>\n", clientversion);
      printf ("GLX clientextensions ::: <%s>\n", clientextensions);
      printf ("GLX servervendor     ::: <%s>\n", servervendor);
      printf ("GLX serverversion    ::: <%s>\n", serverversion);
      printf ("GLX serverextensions ::: <%s>\n", serverextensions);
    //
    // the following is an expanded version of glxfbconfigattributes002 below (for ease of reading)
    //
      GLint glxfbconfigattributes[] = {
        GLX_BUFFER_SIZE,                32,
        GLX_DOUBLEBUFFER,               1,
        GLX_RED_SIZE,                   8,
        GLX_GREEN_SIZE,                 8,
        GLX_BLUE_SIZE,                  8,
        GLX_ALPHA_SIZE,                 8,
        GLX_DEPTH_SIZE,                 24,
        GLX_STENCIL_SIZE,               1,
        GLX_DRAWABLE_TYPE,              GLX_WINDOW_BIT,
        GLX_X_VISUAL_TYPE,              GLX_TRUE_COLOR,
        GLX_CONFIG_CAVEAT,              GLX_NONE,
        GLX_CONTEXT_MAJOR_VERSION_ARB,  3,
        GLX_CONTEXT_MINOR_VERSION_ARB,  2,
        GLX_CONTEXT_PROFILE_MASK_ARB,   GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
        0,                              0,
        0,                              0
      };
    //
    // create integer array of GL/GLX framebuffer configuration attributes
    //
      int glxfbconfigelements = 0;
      int glxfbconfigattributes000[] = { GLX_BUFFER_SIZE, 32, GLX_DOUBLEBUFFER, 1, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 1, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_CONFIG_CAVEAT, GLX_NONE, GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 1, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0, 0, 0, 0 };
      int glxfbconfigattributes001[] = { GLX_BUFFER_SIZE, 32, GLX_DOUBLEBUFFER, 1, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 1, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_CONFIG_CAVEAT, GLX_NONE, GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0, 0, 0, 0 };
      int glxfbconfigattributes002[] = { GLX_BUFFER_SIZE, 32, GLX_DOUBLEBUFFER, 1, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 1, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_CONFIG_CAVEAT, GLX_NONE, GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 3, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0, 0, 0, 0 };
      int glxfbconfigattributes003[] = { GLX_BUFFER_SIZE, 32, GLX_DOUBLEBUFFER, 1, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 1, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_CONFIG_CAVEAT, GLX_NONE, GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 2, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0, 0, 0, 0 };
      int glxfbconfigattributes004[] = { GLX_BUFFER_SIZE, 32, GLX_DOUBLEBUFFER, 1, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 1, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_CONFIG_CAVEAT, GLX_NONE, GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 2, 0, 0, 0, 0 };
      int glxfbconfigattributes005[] = { GLX_BUFFER_SIZE, 32, GLX_DOUBLEBUFFER, 1, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 1, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_CONFIG_CAVEAT, GLX_NONE, 0, 0, 0, 0 };
      int glxfbconfigattributes006[] = { GLX_BUFFER_SIZE, 32, GLX_DOUBLEBUFFER, 1, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 1, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 0, 0, 0, 0 };
      int glxfbconfigattributes007[] = { GLX_BUFFER_SIZE, 32, GLX_DOUBLEBUFFER, 1, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 32, GLX_STENCIL_SIZE, 1, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 0, 0, 0, 0 };
      int glxfbconfigattributes008[] = { 0, 0, 0, 0 };
    //
    // choose framebuffer configuration closest to desired (in order specified above)
    //
    // glxfbconfig = glXChooseFBConfig (xdisplay, xscreen, 0, &glxfbconfigelements);
      glxfbconfig = glXChooseFBConfig (xdisplay, xscreen, (int*)glxfbconfigattributes000, &glxfbconfigelements);
      if ((glxfbconfig == 0) || (glxfbconfigelements < 1)) {
        printf ("glXChooseFBConfig() : error : glxfbconfigattributes000 failed - trying less restrictive...\n");
        glxfbconfig = glXChooseFBConfig (xdisplay, xscreen, (int*)glxfbconfigattributes001, &glxfbconfigelements);
        if ((glxfbconfig == 0) || (glxfbconfigelements < 1)) {
          printf ("glXChooseFBConfig() : error : glxfbconfigattributes001 failed - trying less restrictive...\n");
          glxfbconfig = glXChooseFBConfig (xdisplay, xscreen, (int*)glxfbconfigattributes002, &glxfbconfigelements);
          if ((glxfbconfig == 0) || (glxfbconfigelements < 1)) {
            printf ("glXChooseFBConfig() : error : glxfbconfigattributes002 failed - trying less restrictive...\n");
            glxfbconfig = glXChooseFBConfig (xdisplay, xscreen, (int*)glxfbconfigattributes003, &glxfbconfigelements);
            if ((glxfbconfig == 0) || (glxfbconfigelements < 1)) {
              printf ("glXChooseFBConfig() : error : glxfbconfigattributes003 failed - trying less restrictive...\n");
              glxfbconfig = glXChooseFBConfig (xdisplay, xscreen, (int*)glxfbconfigattributes004, &glxfbconfigelements);
              if ((glxfbconfig == 0) || (glxfbconfigelements < 1)) {
                printf ("glXChooseFBConfig() : error : glxfbconfigattributes004 failed - trying less restrictive...\n");
                glxfbconfig = glXChooseFBConfig (xdisplay, xscreen, (int*)glxfbconfigattributes005, &glxfbconfigelements);
                if ((glxfbconfig == 0) || (glxfbconfigelements < 1)) {
                  printf ("glXChooseFBConfig() : error : glxfbconfigattributes005 failed - nothing less restrictive - permanent failure - terminate process\n");
                  return (CORE_ERROR_INTERNAL);
                }
              }
            }
          }
        }
      }
     
      xvisualinfo = glXGetVisualFromFBConfig (xdisplay, glxfbconfig[0]);
      if (xvisualinfo == 0) { printf ("glXGetVisualFromFBConfig() : error : xvisualinfo == 0 : terminate process\n"); return (CORE_ERROR_INTERNAL); }
     
      glxcontext = glXCreateNewContext (xdisplay, glxfbconfig[0], GLX_RGBA_TYPE, 0, GL_TRUE);
      if (glxcontext == 0) { printf ("glXCreateNewContext() : error : glxcontext == 0 : terminate process\n"); return (CORE_ERROR_INTERNAL); }
     
      xcolormap = XCreateColormap (xdisplay, xroot, xvisualinfo->visual, AllocNone);
      if (xcolormap == 0) { printf ("XCreateColormap() : error : xcolormap == 0 : terminate process\n"); return (CORE_ERROR_INTERNAL); }
    //
    // define XCreateWindow() arguments
    //
      int xeventmask = 0;
      xeventmask = xeventmask | KeyPressMask;              // bit  0
      xeventmask = xeventmask | KeyReleaseMask;            // bit  1
      xeventmask = xeventmask | ButtonPressMask;           // bit  2
      xeventmask = xeventmask | ButtonReleaseMask;         // bit  3
      xeventmask = xeventmask | EnterWindowMask;           // bit  4
      xeventmask = xeventmask | LeaveWindowMask;           // bit  5
      xeventmask = xeventmask | PointerMotionMask;         // bit  6
      xeventmask = xeventmask | PointerMotionHintMask;     // bit  7
      xeventmask = xeventmask | Button1MotionMask;         // bit  8
      xeventmask = xeventmask | Button2MotionMask;         // bit  9
      xeventmask = xeventmask | Button3MotionMask;         // bit 10
      xeventmask = xeventmask | Button4MotionMask;         // bit 11
      xeventmask = xeventmask | Button5MotionMask;         // bit 12
      xeventmask = xeventmask | ButtonMotionMask;          // bit 13
      xeventmask = xeventmask | KeymapStateMask;           // bit 14
      xeventmask = xeventmask | ExposureMask;              // bit 15
      xeventmask = xeventmask | VisibilityChangeMask;      // bit 16
      xeventmask = xeventmask | StructureNotifyMask;       // bit 17
    //xeventmask = xeventmask | ResizeRedirectMask;        // bit 18    DANGER ::: DO NOT ENABLE
      xeventmask = xeventmask | SubstructureNotifyMask;    // bit 19
      xeventmask = xeventmask | SubstructureRedirectMask;  // bit 20
      xeventmask = xeventmask | FocusChangeMask;           // bit 21
      xeventmask = xeventmask | PropertyChangeMask;        // bit 22
      xeventmask = xeventmask | ColormapChangeMask;        // bit 23
      xeventmask = xeventmask | OwnerGrabButtonMask;       // bit 24
     
      xsetwindowattributes.colormap = xcolormap;     // vanilla RGBA
      xsetwindowattributes.background_pixel = None;  // prevent background clear (let OpenGL glClear())
      xsetwindowattributes.background_pixmap = None; // default = None
      xsetwindowattributes.border_pixmap = None;     // default = CopyFromParent
      xsetwindowattributes.border_pixel = None;      // default = Undefined
      xsetwindowattributes.cursor = None;            // default = None
      xsetwindowattributes.event_mask = xeventmask;  // 0x0001FFFF if events of all types are enabled
      xsetwindowattributes.bit_gravity = StaticGravity;
     
      int xselectattributes = (CWBackPixel | CWBorderPixel | CWBitGravity | CWColormap | CWEventMask);
     
      xwindow = XCreateWindow (xdisplay, xroot, x, y, width, height, 0, xvisualinfo->depth, InputOutput, xvisualinfo->visual, xselectattributes, &xsetwindowattributes);
      if (xwindow == 0) { printf ("error ::: XCreateWindow()\n"); return (-1); }
     
      error = XSetStandardProperties (xdisplay, xwindow, "IG", "window.bmp", 0, 0, 0, 0);
      if (error == 0) { printf ("error ::: XSetStandardProperties()\n"); }
     
      char* STRING_WM_DELETE_WINDOW = (char*) "WM_DELETE_WINDOW";
      Atom XA_WM_DELETE_WINDOW = XInternAtom (xdisplay, STRING_WM_DELETE_WINDOW, 0);
      error = XSetWMProtocols (xdisplay, xwindow, &XA_WM_DELETE_WINDOW, 1);
      igstate.message_close_window = XA_WM_DELETE_WINDOW;
    //
    // #######################  in theory the glXMakeContextCurrent() should not be here, but........
    // #####  IMPORTANT  #####  simple tests indicate this glXMakeContextCurrent() must be here
    // #######################  because putting this in CreateNotify causes segment violation
    //
      glxwindow = glXCreateWindow (xdisplay, glxfbconfig[0], xwindow, 0);
      error = glXMakeContextCurrent (xdisplay, glxwindow, glxwindow, glxcontext);
    //
    // do not automatically map/show/display windows --- we have a function for that == ig_window_display()
    //
    //  error = XMapWindow (xdisplay, xwindow);
    //
    // populate window structure
    //
      window->displayid = dispid;
      window->xdisplay = xdisplay;
      window->xwindow = xwindow;
      window->glxwindow = glxwindow;
      window->glxcontext = glxcontext;
      window->glxfbconfig = glxfbconfig[0];
      window->style = 0;
      window->type = options;
     
      if (fullscreen) {
        window->x = 0;
        window->y = 0;
        window->xdisp = x;
        window->ydisp = y;
        window->width = width;
        window->height = height;
        window->xframe = x;
        window->yframe = y;
        window->wframe = width;
        window->hframe = height;
        window->lborder = 0;
        window->tborder = 0;
        window->rborder = 0;
        window->bborder = 0;
        window->cborder = 0;
        window->resized = 1;
      } else {
        window->x = 0;
        window->y = 0;
        window->xdisp = x;
        window->ydisp = y;
        window->width = width;
        window->height = height;
        window->xframe = x - xfr;
        window->yframe = y - yfr - yca;
        window->wframe = width + xfr + xfr;
        window->hframe = height + yfr + yfr + yca;
        window->lborder = xfr;
        window->tborder = yfr;
        window->rborder = xfr;
        window->bborder = yfr;
        window->cborder = yca;
        window->resized = 1;
      }
    //
    //
    // ###############################################################################
    // #####  XWindows does NOT generate an event when a new window is created!  #####
    // #####  But work must be done when windows are created, so generate event  #####
    // ###############################################################################
    //
      XCreateWindowEvent xmessage;
      xmessage.type = CreateNotify;
      xmessage.display = xdisplay;
      xmessage.window = xwindow;
      xmessage.parent = xroot;
      xmessage.send_event = 0;
      xmessage.serial = 0;
      xmessage.x = x;
      xmessage.y = y;
      xmessage.width = width;
      xmessage.height = height;
      xmessage.border_width = xfr;
      xmessage.override_redirect = 0;
      error = XSendEvent (xdisplay, xwindow, 0, StructureNotifyMask, (XEvent*)&xmessage);
    //
    // free all resources we're supposed to free according to xlib and GLX function documentation
    //
      XFree (glxfbconfig);
      XFree (xvisualinfo);
     
      return (winid);            // return window id #
    }
    Last edited by Dark Photon; 12-29-2012 at 08:19 AM.

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,194
    Please use [code]...[/code] or [highlight=cpp]...[/highlight] tags to mark code blocks, especially long ones. Keeps the indentation, uses pretty-printing, and doesn't take up so much space. Fixed that for you.

    Glanced over your code, and it looks like you've some unneeded code in there. I'd simply it down a bit. Also, there's some surprising things to me such as passing GLX_CONTEXT_MAJOR/MINOR_VERSION_ARB symbols to glXChooseFBConfig() rather than glXCreateContextAttribsARB(). Are you sure this is valid?

    Anyway, here's a stand-alone, working, test program that creates a new-style context via GLX. Specifically, it requests a 4.3 compatibility context -- though you can tweak that. Might give you some ideas. Give it a shot:

    Code cpp:
    //------------------------------------------------------------------------------
    // glx_simple_new - Shows how to create an X window and a new-style 
    //   GL context without GLUT or any helper libraries.
    //
    //   COMPILE WITH:
    //       g++ -g -o glx_simple_new glx_simple_new.cxx -lGLU -lGL -lX11
     
    //------------------------------------------------------------------------------
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <sys/time.h>
    #define GL_GLEXT_PROTOTYPES
    #define GLX_GLXEXT_PROTOTYPES
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/glx.h>
     
    struct MyWin
    {
      Display  *display;
      Window    win;
      bool      displayed;
      int       width;
      int       height;
    };
     
    //----------------------------------------------------------------------------
     
    const int   WIN_XPOS    = 256;
    const int   WIN_YPOS    = 64;
    const int   WIN_XRES    = 320;
    const int   WIN_YRES    = 320;
    const int   NUM_SAMPLES = 4;
     
    //----------------------------------------------------------------------------
     
    MyWin        Win;
     
    //----------------------------------------------------------------------------
     
    double elapsedMsec( const struct timeval &start, const struct timeval &stop )
    {
      return ( ( stop.tv_sec  - start.tv_sec  ) * 1000.0 +
               ( stop.tv_usec - start.tv_usec ) / 1000.0 );
    }
     
    //----------------------------------------------------------------------------
     
    double elapsedUsec( const struct timeval &start, const struct timeval &stop )
    {
      return ( ( stop.tv_sec  - start.tv_sec  ) * 1000000.0 +
               ( stop.tv_usec - start.tv_usec ) );
    }
     
    //-----------------------------------------------------------------------------
     
    /// check() - Check for GL errors, and report any queued
     
    void check( const char hdr[] = "" )
    {
      int err;
     
      while ( ( err = glGetError() ) != GL_NO_ERROR )
        fprintf( stderr, "OpenGL Error at %s: %s\n", hdr, gluErrorString(err) );
    }
     
    //----------------------------------------------------------------------------
     
    void displayCB()
    {
      glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     
      //---------------------------------------------------
      // FIXME: Insert GL draw code here
      //---------------------------------------------------
     
      // Display it
      glXSwapBuffers( Win.display, Win.win );
     
      check( "displayCB()" );
    }
     
    //----------------------------------------------------------------------------
     
    void keyboardCB( KeySym sym, unsigned char key, int x, int y,
                     bool &setting_change )
    {
      switch ( tolower( key ) )
      {
        case 27:
          // ESCape - We're done!
          exit (0);
          break;
     
        case 'k':
          printf( "You hit the 'k' key\n" );
          break;
     
        case 0:
          switch ( sym )
          {
            case XK_Left  : 
              printf( "You hit the Left Arrow key\n" );
              break;
     
            case XK_Right :
              printf( "You hit the Right Arrow key\n" );
              break;
          }
          break;
      }
    }
     
    //----------------------------------------------------------------------------
     
    void reshapeCB( int width, int height )
    {
      Win.width = width;
      Win.height = height;
    }
     
    //----------------------------------------------------------------------------
     
    /** chooseFBConfig() - Try to find a framebuffer config that matches
     *    the specified pixel requirements.
     */
     
    GLXFBConfig chooseFBConfig( Display *display, int screen )
    {
      // Default template
      static const 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 attribs [ 100 ] ;
      memcpy( attribs, Visual_attribs, sizeof( Visual_attribs ) );
     
      // DELETED
     
      GLXFBConfig ret = 0;
     
      int fbcount;
      GLXFBConfig *fbc = glXChooseFBConfig( display, screen,
                                            attribs, &fbcount );
      if ( fbc )
      {
        if ( fbcount >= 1 )
          ret = fbc[0];
     
        XFree( fbc );
      }
     
      return ret;
    }
     
    //----------------------------------------------------------------------------
     
    GLXContext createContext( Display *display, int screen,
                              GLXFBConfig fbconfig, XVisualInfo *visinfo, 
                              Window window )
    {
    #define GLX_CONTEXT_MAJOR_VERSION_ARB       0x2091
    #define GLX_CONTEXT_MINOR_VERSION_ARB       0x2092
    typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
     
      // Verify GL driver supports glXCreateContextAttribsARB()
      //   Create an old-style GLX context first, to get the correct function ptr.
      glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
     
      GLXContext ctx_old = glXCreateContext( display, visinfo, 0, True );
      if ( !ctx_old ) 
      {
        printf( "Could not even allocate an old-style GL context!\n" );
        exit(1);
      }
     
      glXMakeCurrent ( display, window, ctx_old ) ;
     
      // Verify that GLX implementation supports the new context create call
      if ( strstr( glXQueryExtensionsString( display, screen ), 
                   "GLX_ARB_create_context" ) != 0 )
        glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
          glXGetProcAddress( (const GLubyte *) "glXCreateContextAttribsARB" );
     
      if ( !glXCreateContextAttribsARB )
      {
        printf( "Can't create new-style GL context\n" );
        exit(1);
      }
     
      // Got the pointer.  Nuke old context.
      glXMakeCurrent( display, None, 0 );
      glXDestroyContext( display, ctx_old );
     
      // Try to allocate a GL 4.3 COMPATIBILITY context
      static int Context_attribs[] =
      {
        GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
        GLX_CONTEXT_MINOR_VERSION_ARB, 3,
        GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
        //GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
        //GLX_CONTEXT_FLAGS_ARB       , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
        //GLX_CONTEXT_FLAGS_ARB       , GLX_CONTEXT_DEBUG_BIT_ARB,
        None
      };
     
      GLXContext context = glXCreateContextAttribsARB( display, fbconfig, 0, 
                                                       True, Context_attribs );
     
      // Forcably wait on any resulting X errors
      XSync( display, False );
     
      if ( !context )
      {
        printf( "Failed to allocate a GL 4.3 context\n" );
        exit(1);
      }
     
      printf( "Created GL 4.3 context\n" );
     
      return context;
    }
     
    //----------------------------------------------------------------------------
     
    void createWindow()
    {
      // Init X and GLX
      Win.displayed = false;
      Display *display = Win.display = XOpenDisplay( ":0.0" );
      if ( !display )
        printf( "Cannot open X display\n" );
     
      int    screen   = DefaultScreen( display );
      Window root_win = RootWindow( display, screen );
     
      if ( !glXQueryExtension( display, 0, 0 ) )
        printf( "X Server doesn't support GLX extension\n" );
     
      // Pick an FBconfig and visual
      GLXFBConfig fbconfig = chooseFBConfig( display, screen );
      if ( !fbconfig )
      {
        printf( "Failed to get GLXFBConfig\n" );
        exit(1);
      }
     
      XVisualInfo *visinfo = glXGetVisualFromFBConfig( display, fbconfig );
      if ( !visinfo )
      {
        printf( "Failed to get XVisualInfo\n" );
        exit(1);
      }
      printf( "X Visual ID = 0x%.2x\n", int( visinfo->visualid ) );
     
      // Create the X window
      XSetWindowAttributes winAttr ;
     
      winAttr.event_mask = StructureNotifyMask | KeyPressMask ;
      winAttr.background_pixmap = None ;
      winAttr.background_pixel  = 0    ;
      winAttr.border_pixel      = 0    ;
     
      winAttr.colormap = XCreateColormap( display, root_win,
                                          visinfo->visual, AllocNone );
     
      unsigned int mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
     
      Window win = Win.win = XCreateWindow ( display, root_win, 
                                             WIN_XPOS, WIN_YPOS, 
                                             WIN_XRES, WIN_YRES, 0, 
                                             visinfo->depth, InputOutput, 
                                             visinfo->visual, mask, &winAttr ) ;
     
      XStoreName( Win.display, win, "My GLX Window");
     
      // Create an OpenGL context and attach it to our X window
      GLXContext context = createContext( display, screen, fbconfig, visinfo, win );
     
      if ( ! glXMakeCurrent( display, win, context ) )
        printf( "glXMakeCurrent failed.\n" );
     
      if ( ! glXIsDirect ( display, glXGetCurrentContext() ) )
        printf( "Indirect GLX rendering context obtained\n" );
     
      // Display the window
      XMapWindow( display, win );
     
      if ( ! glXMakeCurrent( display, win, context ) )
        printf( "glXMakeCurrent failed.\n" );
     
      check( "createWindow()" );
     
      printf( "Window Size    = %d x %d\n", WIN_XRES, WIN_YRES );
      printf( "Window Samples = %d\n", NUM_SAMPLES );
    }
     
    //----------------------------------------------------------------------------
     
    void processXEvents( Atom wm_protocols, Atom wm_delete_window )
    {
      bool setting_change = false;
     
      while ( XEventsQueued( Win.display, QueuedAfterFlush ) )
      {
        XEvent    event;
     
        XNextEvent( Win.display, &event );
     
        if( event.xany.window != Win.win )
          continue;
     
        switch ( event.type )
        {
          case MapNotify:
            {
              Win.displayed = true;
              break;
            }
          case ConfigureNotify:
            {
              XConfigureEvent &cevent = event.xconfigure;
              reshapeCB( cevent.width, cevent.height );
              break;
            }
          case KeyPress:
            {
              char      chr;
              KeySym    symbol;
              XComposeStatus status;
     
              XLookupString( &event.xkey, &chr, 1, &symbol, &status );
     
              keyboardCB( symbol, chr, event.xkey.x, event.xkey.y,
                          setting_change );
              break;
            }
          case ClientMessage:
            {
              if ( event.xclient.message_type      == wm_protocols &&
                   Atom( event.xclient.data.l[0] ) == wm_delete_window )
              {
                //printf( "Received WM_DELETE_WINDOW\n" );
                exit(0);
              }
              break;
            }
        }
      }
    }
     
    //----------------------------------------------------------------------------
     
    void mainLoop()
    {
      // Register to receive window close events (the "X" window manager button)
      Atom wm_protocols     = XInternAtom( Win.display, "WM_PROTOCOLS"    , False);
      Atom wm_delete_window = XInternAtom( Win.display, "WM_DELETE_WINDOW", False);
      XSetWMProtocols( Win.display, Win.win, &wm_delete_window, True );
     
      while (1) 
      {
        // Redraw window (after it's mapped)
        if ( Win.displayed )
          displayCB();
     
        // Update frame rate
        static timeval last_xcheck   = {0,0};
        struct timeval now;
        gettimeofday( &now, 0 );
     
        // Check X events every 1/10 second
        if ( elapsedMsec( last_xcheck, now ) > 100 )
        {
          processXEvents( wm_protocols, wm_delete_window );
          last_xcheck = now;
        }
      }
    }
     
    //----------------------------------------------------------------------------
     
    int main( int argc, char *argv[] )
    {
      // Init globals
      Win.width = WIN_XRES, Win.height = WIN_YRES;
     
      // Create context and window
      createWindow();
     
      // Init OpenGL
      glViewport  ( 0, 0, Win.width, Win.height ); 
      glColorMask ( 1,1,1,1 );
      glClearColor( 0,0,1,1 );
      glClear     ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     
      // Go
      printf( "Valid keys: Left, Right, k, ESC\n" );
      printf( "Press ESC to quit\n" );
     
      mainLoop();
     
      return 0;
    }
    Last edited by Dark Photon; 12-29-2012 at 09:10 AM.

  3. #3
    Intern Contributor
    Join Date
    Jan 2008
    Location
    phobos, mars
    Posts
    75
    Quote Originally Posted by Dark Photon View Post
    Please use [code]...[/code] or [highlight=cpp]...[/highlight] tags to mark code blocks, especially long ones. Keeps the indentation, uses pretty-printing, and doesn't take up so much space. Fixed that for you.

    Glanced over your code, and it looks like you've some unneeded code in there. I'd simply it down a bit. Also, there's some surprising things to me such as passing GLX_CONTEXT_MAJOR/MINOR_VERSION_ARB symbols to glXChooseFBConfig() rather than glXCreateContextAttribsARB(). Are you sure this is valid?

    Anyway, here's a stand-alone, working, test program that creates a new-style context via GLX. Specifically, it requests a 4.3 compatibility context -- though you can tweak that. Might give you some ideas. Give it a shot:
    Thanks for the comments and code, and for fixing up my code.

    Yes, I do have a lot of debug code to query various values and sometimes print them out. That was to help me find problems in the code by reference to strange looking values. In fact, in this case I noticed that it seems to report my OpenGL version as 2.1.2 instead of something newer (like v3.20 or v4.30).

    Yes, I just noticed GLX_CONTEXT_MAJOR_VERSION_ARB and GLX_CONTEXT_MINOR_VERSION_ARB there too. I assume they were allowed in earlier versions of GLX --- or I simply screwed up somewhere along the line. But that code was working until I installed my new driver, though it might have been failing on those lines and then finding one of the later lines without those constants. Not sure.

    In the new code I've been trying to get working the last day or so, I put those constants where they belong. Unfortunately, now glXCreateContextAttribsARB() is blowing up. My application calls that function, but never returns, glXCreateContextAttribsARB() just terminates itself somehow, and no dialogs appear saying "segment violation" or anything, which is odd.

    When I try creating the context with the older functions, then the context is created, but I'm back in the situation that I was in before... glGenVertexArrays() always returns zero for VAO identifiers (which is invalid, of course). I assume this happens because I have an old OpenGL context (probably v2.10) which doesn't know what VAOs are.

    I tried to compile your code, but... I don't have GLU on my computer. I avoid every library that I possibly can (though admittedly I gave in and adopted GLEW a while back to save myself a LOT of pointless work and hassle).

    So I hesitate to download and install GLU, because then if that works, I still don't know what is my problem. I'm trying to make my program work without GLU but with GLEW... that's my problem, and that's what I need to get to work. I am very appreciative of the time and effort you put into helping me, but I've been avoiding GLU for years, and wish to continue without GLU (but with GLEW). Not sure what to do now.

    The approach I was taking was working before, but I didn't have glXCreateContextAttribsARG() in my code --- I was calling glXCreateNewContext() instead. That was giving me an OpenGL v3.20 or v3.30 context, which is adequate for the state of my code as it stands now, though the reason I bought the GTX680 and installed the nvidia v310.19 drivers was to update my engine to v4.30 capabilities. My code ran on the GTX680 before I installed the new drivers, so my working theory has been that something changed in their new drivers. However, the nvidia website says all the old stuff should work, and I haven't noticed anyone else having the problem I am having.

    What should I try next?

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,194
    Quote Originally Posted by bootstrap View Post
    I tried to compile your code, but... I don't have GLU on my computer.
    Just install Mesa-libGLU and Mesa-libGLU-devel packages. Then you'll have it.

    Alternatively, there's only one usage of a glu symbol in my entire test program -- so just comment it out. That is, comment out this:

    Code cpp:
    // #include <GL/glu.h>

    and change the gluErrorString call as follows:

    Code cpp:
    //    fprintf( stderr, "OpenGL Error at %s: %s\n", hdr, gluErrorString(err) );
        fprintf( stderr, "OpenGL Error at %s: 0x%x\n", hdr, err );

    What should I try next?
    I'd suggest you compile my test program and binary-search the differences. I'd start with:


    1. the presence of GLX_CONTEXT_MAJOR_VERSION_ARB and GLX_CONTEXT_MINOR_VERSION_ARB in the glXChooseFBConfig() args which I believe is invalid.
    2. Then address the missing glXCreateContextAttribsARB() call in your code. Check the man page links I've provided in this paragraph for details. Note that your call to glXCreateNewContext() according to the GLX_ARB_create_context extension specs will only create a context with version <= 2.1.
    Last edited by Dark Photon; 12-29-2012 at 08:06 PM.

  5. #5
    Intern Contributor
    Join Date
    Jan 2008
    Location
    phobos, mars
    Posts
    75
    Actually, I already did all that (except install GLU). The problem is, when I remove the GLU, I get boatloads of unrecognized OpenGL symbols (because your program doesn't involve GLEW, I assume).

  6. #6
    Intern Contributor
    Join Date
    Jan 2008
    Location
    phobos, mars
    Posts
    75
    An update. I decided to take your approach and create a fairly stripped down version of my ig_graphics_initialize() and ig_window_create() functions. I don't know why, but after the initialization code created a context via the older functions and then called glewInit(), queries indicated that the code created an OpenGL v4.30 context.

    Also, when the ig_window_create() function executed, the glXCreateContextAttribsARB() function no longer failed.

    All I can guess is that I have some bit set or value specified in my non-stripped-down functions that cause the problem. I have no idea what that might be, but I suppose I can find out by disabling bits and values one by one until it produces an OpenGL v4.30 context and the functions don't terminate the application.

    For whatever it is worth, and in case someone else has similar problems, I will paste the program that works correctly below:

    Code cpp:
    #include    <stdio.h>
    #include    <memory.h>
    #include    <X11/Xlib.h>            // include xlib.h
    #include    <GL/glew.h>                // include glew.h
    #include    <GL/glxew.h>            // include glxew.h
    #include    <GL/glx.h>                // include glx.h
    //
    //
    //
    int ig_graphics_initialize (int mode, int options);
    int ig_window_create (int winid, int options, int x, int y, int width, int height, int dispid);
     
    int main (int argc, int argv[]) {
     
        int error = 0;
        error = ig_graphics_initialize (0, 0);
        error = ig_window_create (10, 0, 32, 32, 640, 480, 1);
     
        return (error);
    }
     
    // initialize graphics --- create old style GLX context so we can initialize GLEW and then access all GLX and OpenGL functions
     
    int ig_graphics_initialize (int mode, int options) {
     
        int error = 0;
        static int glew_initialized = 0;
        if (glew_initialized) { return (0); }
     
        Window xwindow = 0;
        Display* xdisplay = XOpenDisplay(NULL);
        int xscreen = XDefaultScreen (xdisplay);
        Window xroot = XRootWindow (xdisplay, xscreen);
        int xdisplay_width = XDisplayWidth (xdisplay, xscreen);
        int xdisplay_height = XDisplayHeight (xdisplay, xscreen);
     
        Colormap                xcolormap;
        XVisualInfo*            xvisualinfo = 0;
        XSetWindowAttributes    xsetwindowattributes;
        GLXWindow                glxwindow;
        GLXContext                glxcontext;
        GLXFBConfig*            glxfbconfig = 0;
     
        int xvisualattributes[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, 0 };    // set up xvisualattributes[] for glXChooseVisual() argument list
     
        xvisualinfo = glXChooseVisual (xdisplay, xscreen, xvisualattributes);                // create xvisualinfo
        if (xvisualinfo == 0) { printf ("glXChooseVisual() : error : xvisualinfo == 0 : GLX/OpenGL initialization failed\n"); return(-1); }
     
        xcolormap = XCreateColormap (xdisplay, xroot, xvisualinfo->visual, AllocNone);        // create colormap
        if (xcolormap == 0) { XFree (xvisualinfo); printf ("XCreateColormap() : error : xcolormap == 0 : GLX/OpenGL initialization failed\n"); return (-1); }
     
    // to eliminate events of one or more types, comment out the corresponding lines below (do not be an idiot and delete them)
     
        int xeventmask = 0;
        xeventmask = xeventmask | KeyPressMask;                                // bit  0
        xeventmask = xeventmask | ExposureMask;                                // bit 15
     
        memset (&xsetwindowattributes, 0, sizeof(XSetWindowAttributes));    // clear structure before initialization
     
        xsetwindowattributes.colormap = xcolormap;
        xsetwindowattributes.event_mask = xeventmask;
     
        int xselectattributes = (CWColormap | CWEventMask);
     
    // create xwindow so we can create GLX/OpenGL context so we can call glewInit()
     
        xwindow = XCreateWindow (xdisplay, xroot, 32, 32, 640, 480, 0, xvisualinfo->depth, InputOutput, xvisualinfo->visual, xselectattributes, &xsetwindowattributes);
        if (xwindow == 0) { XFree (xvisualinfo); printf ("XCreateWindow() : error : xwindow == 0 : GLX/OpenGL initialization failed\n"); return (-1); }
     
    // create GLX / OpenGL context so we can create GLX/OpenGL context so we can call glewInit()
     
        glxcontext = glXCreateContext (xdisplay, xvisualinfo, 0, GL_TRUE);
        if (glxcontext == 0) { XFree (xvisualinfo); printf ("glXCreateContext() : error : glxcontext == 0 : GLX/OpenGL initialization failed\n"); return (-1); }
     
    // make GLX / OpenGL context current == active
     
        glXMakeCurrent (xdisplay, xwindow, glxcontext);
     
    // get GLX information
     
        int major = 0;
        int minor = 0;
        int errorbase = 0;
        int eventbase = 0;
     
        error = glXQueryVersion (xdisplay, &major, &minor);
        error = glXQueryExtension (xdisplay, &errorbase, &eventbase);
        const char* extensions = glXQueryExtensionsString (xdisplay, xscreen);
        const char* clientvendor = glXGetClientString (xdisplay, GLX_VENDOR);
        const char* clientversion = glXGetClientString (xdisplay, GLX_VERSION);
        const char* clientextensions = glXGetClientString (xdisplay, GLX_EXTENSIONS);
        const char* servervendor = glXQueryServerString (xdisplay, xscreen, GLX_VENDOR);
        const char* serverversion = glXQueryServerString (xdisplay, xscreen, GLX_VERSION);
        const char* serverextensions = glXQueryServerString (xdisplay, xscreen, GLX_EXTENSIONS);
     
        printf ("GLX version          ::: major.minor == %d.%d\n", major, minor);
        printf ("GLX offsets          ::: errorbase : eventbase == %d %d\n", errorbase, eventbase);
        printf ("GLX extensions       ::: <%s>\n", extensions);
        printf ("GLX clientvendor     ::: <%s>\n", clientvendor);
        printf ("GLX clientversion    ::: <%s>\n", clientversion);
        printf ("GLX clientextensions ::: <%s>\n", clientextensions);
        printf ("GLX servervendor     ::: <%s>\n", servervendor);
        printf ("GLX serverversion    ::: <%s>\n", serverversion);
        printf ("GLX serverextensions ::: <%s>\n", serverextensions);
    //
    // call glewInit() to initialize GLX/OpenGL functions (so we can call those functions)
    //
        glewExperimental = GL_TRUE;
     
        error = glewInit();
        if (error != GLEW_OK) { printf("glewInit() : error : %s\n", glewGetErrorString(error)); return (-1); }
     
        glew_initialized = 1;
        printf ("status: GLEW initialized %s\n", glewGetString(GLEW_VERSION));
     
        error = XDestroyWindow (xdisplay, xwindow);                    // figure out how the best way to destroy windows in xlib/XWindows
        glXDestroyContext (xdisplay, glxcontext);                    // destroy GLX/OpenGL [rendering] context
        XFree (xvisualinfo);                                        // free allocated resource
     
    // test some basic OpenGL functions - and make sure OpenGL is initialized
     
        const GLubyte* glvendor = glGetString (GL_VENDOR);
        const GLubyte* glversion = glGetString (GL_VERSION);
        const GLubyte* glrenderer = glGetString (GL_RENDERER);
        const GLubyte* glextensions = glGetString (GL_EXTENSIONS);
     
        printf ("OpenGL vendor      == %s\n", (char*)glvendor);
        printf ("OpenGL version     == %s\n", (char*)glversion);
        printf ("OpenGL renderer    == %s\n", (char*)glrenderer);
        printf ("OpenGL extensions  == %s\n", (char*)glextensions);
     
        return (0);
    }
     
     
     
    int ig_window_create (int winid, int options, int x, int y, int width, int height, int dispid) {
     
        printf ("ig_window_create() : %d %d %d %d %d %d %d\n", winid, options, x, y, width, height, dispid);
     
        int error = 0;
        int success = 0;
        int fullscreen = 0;
     
        static int glew_initialized = 0;
     
        int glxmajor = 0;
        int glxminor = 0;
        int errorbase = 0;
        int eventbase = 0;
     
        Window xwindow = 0;
        Display* xdisplay = XOpenDisplay(0);
        int xscreen = XDefaultScreen (xdisplay);
        Window xroot = XRootWindow (xdisplay, xscreen);
        int display_width = XDisplayWidth (xdisplay, xscreen);
        int display_height = XDisplayHeight (xdisplay, xscreen);
     
        error = glXQueryVersion (xdisplay, &glxmajor, &glxminor);
        error = glXQueryExtension (xdisplay, &errorbase, &eventbase);
        const char* extensions = glXQueryExtensionsString (xdisplay, xscreen);
        const char* clientvendor = glXGetClientString (xdisplay, GLX_VENDOR);
        const char* clientversion = glXGetClientString (xdisplay, GLX_VERSION);
        const char* clientextensions = glXGetClientString (xdisplay, GLX_EXTENSIONS);
        const char* servervendor = glXQueryServerString (xdisplay, xscreen, GLX_VENDOR);
        const char* serverversion = glXQueryServerString (xdisplay, xscreen, GLX_VERSION);
        const char* serverextensions = glXQueryServerString (xdisplay, xscreen, GLX_EXTENSIONS);
     
        printf ("GLX version          ::: major.minor == %d.%d\n", glxmajor, glxminor);
        printf ("GLX offsets          ::: errorbase : eventbase == %d %d\n", errorbase, eventbase);
        printf ("GLX extensions       ::: <%s>\n", extensions);
        printf ("GLX clientvendor     ::: <%s>\n", clientvendor);
        printf ("GLX clientversion    ::: <%s>\n", clientversion);
        printf ("GLX clientextensions ::: <%s>\n", clientextensions);
        printf ("GLX servervendor     ::: <%s>\n", servervendor);
        printf ("GLX serverversion    ::: <%s>\n", serverversion);
        printf ("GLX serverextensions ::: <%s>\n", serverextensions);
     
        if (glxmajor < 2) {
            if ((glxmajor != 1) || (glxminor < 4)) { printf ("fatal error ::: GLX version is prior to v0140 ::: %1d.%1d\n", glxmajor, glxminor); return (-1); }
        }
     
    // the following is an expanded version of glxfbconfigattributes002 below (for ease of reading)
     
        GLint glxfbconfigattributes[] = {
            GLX_BUFFER_SIZE,                32,
            GLX_DOUBLEBUFFER,                 1,
            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_DRAWABLE_TYPE,                GLX_WINDOW_BIT,
            GLX_X_VISUAL_TYPE,                GLX_TRUE_COLOR,
            GLX_CONFIG_CAVEAT,                GLX_NONE,
            0,                                 0,
            0,                                 0
        };
     
    // create GLX framebuffer configuration attributes
    // choose framebuffer configuration closest to desired (in order specified above)
    // ask function to create a list of frame buffer configuration attributes based on our request
     
        int glxfbconfigelements = 0;
        GLXFBConfig* glxfbconfig = 0;
        glxfbconfig = glXChooseFBConfig (xdisplay, xscreen, (int*)glxfbconfigattributes, &glxfbconfigelements);
        if ((glxfbconfig == 0) || (glxfbconfigelements < 1)) { printf ("glXChooseFBConfig() : error : glxfbconfigattributes failed\n"); return (-1); }
     
        GLXFBConfig fbconfig = glxfbconfig[0];
        printf ("glXChooseFBConfig() returned %d matching frame buffer configurations\n", glxfbconfigelements);
     
        XVisualInfo* xvisualinfo = 0;
        xvisualinfo = glXGetVisualFromFBConfig (xdisplay, glxfbconfig[0]);
        if (xvisualinfo == 0) { XFree(glxfbconfig); printf ("glXGetVisualFromFBConfig() : error : xvisualinfo == 0 : terminate process\n"); return (-1); }
     
        Colormap xcolormap = 0;
        xcolormap = XCreateColormap (xdisplay, xroot, xvisualinfo->visual, AllocNone);
        if (xcolormap == 0) { XFree(glxfbconfig); XFree(xvisualinfo); printf ("XCreateColormap() : error : xcolormap == 0 : terminate process\n"); return (-1); }
     
    // define XCreateWindow() arguments
     
        int xeventmask = 0;
        xeventmask = xeventmask | KeyPressMask;                    // bit  0
        xeventmask = xeventmask | KeyReleaseMask;                // bit  1
        xeventmask = xeventmask | ButtonPressMask;                // bit  2
        xeventmask = xeventmask | ButtonReleaseMask;            // bit  3
        xeventmask = xeventmask | EnterWindowMask;                // bit  4
        xeventmask = xeventmask | LeaveWindowMask;                // bit  5
        xeventmask = xeventmask | PointerMotionMask;            // bit  6
        xeventmask = xeventmask | PointerMotionHintMask;        // bit  7
        xeventmask = xeventmask | Button1MotionMask;            // bit  8
        xeventmask = xeventmask | Button2MotionMask;            // bit  9
        xeventmask = xeventmask | Button3MotionMask;            // bit 10
        xeventmask = xeventmask | Button4MotionMask;            // bit 11
        xeventmask = xeventmask | Button5MotionMask;            // bit 12
        xeventmask = xeventmask | ButtonMotionMask;                // bit 13
        xeventmask = xeventmask | KeymapStateMask;                // bit 14
        xeventmask = xeventmask | ExposureMask;                    // bit 15
        xeventmask = xeventmask | VisibilityChangeMask;            // bit 16
        xeventmask = xeventmask | StructureNotifyMask;            // bit 17
    //    xeventmask = xeventmask | ResizeRedirectMask;            // bit 18    !!!!!  DANGER  !!!!!  if this is enabled - total disaster occurs (the newly exposed window is not cleared and other glViewport() mistakes occur)
        xeventmask = xeventmask | SubstructureNotifyMask;        // bit 19
        xeventmask = xeventmask | SubstructureRedirectMask;        // bit 20
        xeventmask = xeventmask | FocusChangeMask;                // bit 21
        xeventmask = xeventmask | PropertyChangeMask;            // bit 22
        xeventmask = xeventmask | ColormapChangeMask;            // bit 23
        xeventmask = xeventmask | OwnerGrabButtonMask;            // bit 24
     
        XSetWindowAttributes xsetwindowattributes;
        memset (&xsetwindowattributes, 0, sizeof(XSetWindowAttributes));    // clear xsetwindowattributes structure before we assign values
        xsetwindowattributes.colormap = xcolormap;
        xsetwindowattributes.background_pixel = None;
        xsetwindowattributes.background_pixmap = None;
        xsetwindowattributes.border_pixmap = None;
        xsetwindowattributes.border_pixel = None;
        xsetwindowattributes.cursor = None;
        xsetwindowattributes.event_mask = xeventmask;
        xsetwindowattributes.bit_gravity = StaticGravity;
     
        int xselectattributes = (CWBackPixel | CWBorderPixel | CWBitGravity | CWColormap | CWEventMask);
     
        xwindow = XCreateWindow (xdisplay, xroot, x, y, width, height, 0, xvisualinfo->depth, InputOutput, xvisualinfo->visual, xselectattributes, &xsetwindowattributes);
        if (xwindow == 0) { XFree(glxfbconfig); XFree(xvisualinfo); printf ("error ::: XCreateWindow()\n"); return (-1); }
     
        error = XSetStandardProperties (xdisplay, xwindow, "IG", "window.bmp", 0, 0, 0, 0);
        if (error == 0) { printf ("error ::: XSetStandardProperties()\n"); }
     
        char* STRING_WM_DELETE_WINDOW = (char*) "WM_DELETE_WINDOW";
        Atom XA_WM_DELETE_WINDOW = XInternAtom (xdisplay, STRING_WM_DELETE_WINDOW, 0);
        error = XSetWMProtocols (xdisplay, xwindow, &XA_WM_DELETE_WINDOW, 1);
        int message = XA_WM_DELETE_WINDOW;
     
        GLXWindow glxwindow = 0;
        glxwindow = glXCreateWindow (xdisplay, glxfbconfig[0], xwindow, 0);
        if (glxwindow == 0) { XFree(glxfbconfig); XFree(xvisualinfo); printf ("error ::: glXCreateWindow()\n"); return (-1); }
     
        error = glewIsSupported ("GL_VERSION_3_2");
        error = glewIsSupported ("GL_VERSION_3_3");
        error = glewIsSupported ("GL_VERSION_4_0");
        error = glewIsSupported ("GL_VERSION_4_1");
        error = glewIsSupported ("GL_VERSION_4_2");
        error = glewIsSupported ("GL_VERSION_4_3");
     
    //    int glxcontextattribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 1, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, 0, 0, 0, 0 };
        int glxcontextattribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 3, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0, 0, 0, 0 };
    //    int glxcontextattribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 4, GLX_CONTEXT_MINOR_VERSION_ARB, 2, 0, 0, 0, 0 };
        error = glxcontextattribs[0];
        error = glxcontextattribs[1];
        error = glxcontextattribs[2];
        error = glxcontextattribs[3];
        error = glxcontextattribs[4];
        error = glxcontextattribs[5];
     
    // calling function glXCreateContextAttribsARB() terminates the program with no error message printed
    // the older glXMakeContextCurrent() function apparently cannot create OpenGL contexts for v3.20 and above
     
        bool directrender = true;
        GLXContext glxcontext = 0;
    //    glxcontext = glXCreateNewContext (xdisplay, glxfbconfig[0], GLX_RGBA_TYPE, 0, 1);                                            // older function (no versions)
        glxcontext = glXCreateContextAttribsARB (xdisplay, glxfbconfig[0], 0, directrender, glxcontextattribs);                        // newer function (supports versions)
        if (glxcontext == 0) { printf ("glXCreateNewContext() : error : glxcontext == 0 : terminate process\n"); return (-1); }
     
    // NOTE:  glXMakeContextCurrent() returns zero on success and one on failure --- abnormal
     
        error = 0;
        error = glXMakeContextCurrent (xdisplay, glxwindow, glxwindow, glxcontext);
        if (error == 0) { XFree(glxfbconfig); XFree(xvisualinfo); printf ("glXMakeContextCurrent() : error : return value != 0 : terminate process\n"); return (-1); }
    //
    // a GLX context has been created, so now we should be able to initialize GLEW --- did we need to make it current before the following GLEW initialization ?????
    //
    // call glewInit() to initialize GLX/OpenGL functions (so we can call those functions)
    //
        if (glew_initialized == 0) {
            error = glewInit();
            if (error != GLEW_OK) {
                printf("glewInit() : error : %s\n", glewGetErrorString(error));
                XFree(glxfbconfig);
                XFree(xvisualinfo);
                return (-1);
            } else {
                glew_initialized = 1;
                printf ("status: GLEW initialized %s\n", glewGetString(GLEW_VERSION));
            }
        }
     
    // test some basic OpenGL functions - and make sure OpenGL is initialized
     
        const GLubyte* glvendor = glGetString (GL_VENDOR);
        const GLubyte* glversion = glGetString (GL_VERSION);
        const GLubyte* glrenderer = glGetString (GL_RENDERER);
        const GLubyte* glextensions = glGetString (GL_EXTENSIONS);
     
        printf ("OpenGL vendor      == %s\n", (char*)glvendor);
        printf ("OpenGL version     == %s\n", (char*)glversion);
        printf ("OpenGL renderer    == %s\n", (char*)glrenderer);
        printf ("OpenGL extensions  == %s\n", (char*)glextensions);
     
        error = glewIsSupported ("GL_VERSION_3_2");
        error = glewIsSupported ("GL_VERSION_3_3");
        error = glewIsSupported ("GL_VERSION_4_0");
        error = glewIsSupported ("GL_VERSION_4_1");
        error = glewIsSupported ("GL_VERSION_4_2");
        error = glewIsSupported ("GL_VERSION_4_3");
     
    // do not automatically map/show/display windows --- we have a function for that == ig_window_show() --- or something like that
     
    //    error = XMapWindow (xdisplay, xwindow);
     
        XCreateWindowEvent xmessage;
        xmessage.type = CreateNotify;
        xmessage.display = xdisplay;
        xmessage.window = xwindow;
        xmessage.parent = xroot;
        xmessage.send_event = 0;
        xmessage.serial = 0;
        xmessage.x = x;
        xmessage.y = y;
        xmessage.width = width;
        xmessage.height = height;
        xmessage.border_width = 4;
        xmessage.override_redirect = 0;
        error = XSendEvent (xdisplay, xwindow, 0, StructureNotifyMask, (XEvent*)&xmessage);
     
    // free all resources we're supposed to free according to xlib and GLX function documentation
     
        XFree (glxfbconfig);
        XFree (xvisualinfo);
     
        return (0);                                    // return window id #
    }
    Last edited by bootstrap; 12-30-2012 at 04:50 PM.

  7. #7
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,194
    Glad you made some progress. Looks like calling glXCreateContextAttribsARB() was the ticket.

  8. #8
    Intern Contributor
    Join Date
    Jan 2008
    Location
    phobos, mars
    Posts
    75
    Quote Originally Posted by Dark Photon View Post
    Glad you made some progress. Looks like calling glXCreateContextAttribsARB() was the ticket.
    Nope, something else, because calling glXCreateContextAttribsARB() immediately terminated my application (no return from the function, no error message, just terminal window vanishes and application terminated).

    I'm just now working through the ig_graphics_initialize() function in my main application, making it more exactly like the sample. It is only slightly different from the sample now, but still only gets a v2.1.2 context versus v4.3.0 context in the sample (according to the printout of values). So there has to be something different. I'm beginning to wonder whether somehow the two cases are accidentally including a different header file, or in a different order. Or something even more mysterious. Once I find out, I'll add the information to this record.

    I appreciate your help!
    Last edited by bootstrap; 12-30-2012 at 04:49 PM. Reason: clarity

  9. #9
    Intern Contributor
    Join Date
    Jan 2008
    Location
    phobos, mars
    Posts
    75
    ##### SOLVED #####

    Ah, just shoot me! I hate when this kind of nonsense happens. Maybe/Probably my fault.

    In my IDE, I had directory "/usr/lib" specified as a linker search path... probably from before they switched over to /usr/lib/i386-linux-gnu and /usr/lib/x64-linux-gnu a year or so ago. I had both specified, but "/usr/lib" was first in the list (which might matter).

    So presumably what was happening was one or another of the libraries my 3D engine was linking to was an older version in the "/usr/lib" directory, while a newer version exists in the "/usr/lib/i386-linux-gnu" and "/usr/lib/x64-linux-gnu" directories.

    It also seems to me like the codeblocks IDE (or perhaps the GNU tools/linker) has gotten "smarter" (maybe too smart) about what directories to search for shared libraries. I forgot to put any linker library names or search directories in my test program, yet somehow it linked to xlib and GL (neither of which is that standard a library, nothing like the C standard libraries or something).

    Anyhow, that was the problem all along. Gads, can't believe how much BS I went through where no problems in my programs existed.

    Probably the new nvidia drivers put their shared libraries in the /usr/lib/i386-linux-gnu and /usr/lib/x64-linux-gnu directories... while older versions of the shared libraries got put in /usr/lib directly (or something along those lines). Otherwise, who freaking knows.

    Nice to have it solved, but I hate when I waste a day or three on something as stupid as this. Sigh.
    Last edited by bootstrap; 12-30-2012 at 08:30 PM. Reason: elaborate

  10. #10
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,194
    Quote Originally Posted by bootstrap View Post
    ##### SOLVED #####

    Ah, just shoot me! I hate when this kind of nonsense happens. ... Nice to have it solved, but I hate when I waste a day or three on something as stupid as this. Sigh.
    No worries. Happens to all of us now and then.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •