openglx11glewglx

GLX create GL 4.x context with GLEW crashes glXChooseFBConfig


I have problems creating a GL 4.x context using plain GLX and GLEW (1.12). All solutions I found here are not working for me.

What I am trying to do (and what I found in other questions): Create a 'base' GL context, call glewInit(), then create the proper GL 4.x context using glXCreateContextAttribsARB(...). This did not work for me, since glXChooseFBConfig keeps segfaulting.

I read that I have to call glxewInit first, but that didn't work. Building without GLEW_MX defined resulted in glxewInit not being available. Building with GLEW_MX defined resulted in the following compile error:

error: 'glxewGetContext' was not declared in this scope #define glxewInit() glxewContextInit(glxewGetContext())
note: in expansion of macro 'glewxInit' auto result = glxewInit()

When I ommit calling glxewInit() the application crashes when calling glXChooseFBConfig(...)

I am rather stuck here. What is the proper way to get a GL 4.x context using plain GLX? (I cannot use glfw or something similiar, I am working on a given application, and I get a Display pointer and a Window id to work with, the window is already there)


Solution

  • Thanks to the hint from Nicol I was able to fix the problem myself. Looking at the glfw code I did the following (might not apply to everyone).

    Thanks againg to Nicol, I don't know why I didn't think of looking at other code.

    Here's my solution:

    XMapWindow( m_X11View->m_pDisplay, m_X11View->m_hWindow );
    
    XWindowAttributes watt;
    XGetWindowAttributes( m_X11View->m_pDisplay, m_X11View->m_hWindow, &watt );
    XVisualInfo temp;
    temp.visualid = XVisualIDFromVisual(watt.visual);
    int n;
    XVisualInfo* visual = XGetVisualInfo( m_X11View->m_pDisplay, VisualIDMask, &temp, &n );
    
    int      n_elems    = 0;
    
    if (glXQueryExtension(m_X11View->m_pDisplay,NULL,NULL))
    {
        // create dummy base context to init glew, create proper 4.x context
        m_X11View->m_GLXContext = glXCreateContext( m_X11View->m_pDisplay, visual, 0, true );
    
    
        glXMakeCurrent( m_X11View->m_pDisplay, m_X11View->m_hWindow, m_X11View->m_GLXContext );
    
        // some debug output stuff
        std::cerr << "GL vendor: " << glGetString(GL_VENDOR) << std::endl;
        std::cerr << "GL renderer: " << glGetString(GL_RENDERER) << std::endl;
        std::cerr << "GL Version: " << glGetString(GL_VERSION) << std::endl;
        std::cerr << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
    
        int glx_version_major;
        int glx_version_minor;
    
        if (glXQueryVersion(m_X11View->m_pDisplay,&glx_version_major,&glx_version_minor))
        {
            if (ExtensionSupported(m_X11View->m_pDisplay,screen,"GLX_SGIX_fbconfig"))
            {
                int result = glewInit();
    
                if (GLEW_OK==result)
                {
                    std::cerr << "GLEW init successful" << std::endl;
    
                    PFNGLXGETFBCONFIGATTRIBSGIXPROC GetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)
                    glXGetProcAddress( (GLubyte*)"glXGetFBConfigAttribSGIX");
    
                    PFNGLXCHOOSEFBCONFIGSGIXPROC ChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)
                        glXGetProcAddress( (GLubyte*)"glXChooseFBConfigSGIX");
    
                    PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC CreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)
                        glXGetProcAddress( (GLubyte*)"glXCreateContextWithConfigSGIX");
    
                    PFNGLXGETVISUALFROMFBCONFIGSGIXPROC GetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)
                        glXGetProcAddress( (GLubyte*)"glXGetVisualFromFBConfigSGIX");
    
                    int gl_attribs[] = {
                        GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
                        GLX_CONTEXT_MINOR_VERSION_ARB, 4,
                        GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
                        //GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
                        0
                    };
    
                    GLXFBConfigSGIX* configs = ChooseFBConfigSGIX( m_X11View->m_pDisplay, screen, NULL, &n_elems );
                    glXDestroyContext( m_X11View->m_pDisplay, m_X11View->m_GLXContext );
    
                    m_X11View->m_GLXContext = glXCreateContextAttribsARB( m_X11View->m_pDisplay, configs[0], 0, true, gl_attribs );
                    glXMakeCurrent( m_X11View->m_pDisplay, m_X11View->m_hWindow, m_X11View->m_GLXContext );
    
                    /*
                    glDebugMessageCallback( GLDebugLog, NULL );
    
                    // setup message control
                    // disable everything
                    // enable errors only
                    glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_FALSE );
                    glDebugMessageControl( GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE,
                        0, 0, GL_TRUE );
                    */
    
                }
                else
                {
                    std::cerr << "GLEW init failed: " << glewGetErrorString(result) << std::endl;
                }
            }
    
        }
    }