GLX使用GLEW崩溃创建GL 4.x上下文崩溃glXChooseFBConfig

时间:2016-02-03 06:58:31

标签: opengl x11 glew glx

使用普通GLX和GLEW(1.12)创建GL 4.x上下文时遇到问题。我在这里找到的所有解决方案都不适合我。

我想做什么(以及我在其他问题中找到的):创建一个基础' GL上下文,调用glewInit(),然后使用glXCreateContextAttribsARB(...)创建正确的GL 4.x上下文。这对我来说不起作用,因为glXChooseFBConfig保持了segfaulting。

我读到我必须先调用glxewInit,但那不起作用。没有定义GLEW_MX的构建导致glxewInit不可用。使用GLEW_MX定义的构建导致以下编译错误:

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

当我忽略调用glxewInit()时,应用程序在调用glXChooseFBConfig(...)时崩溃

我宁愿被困在这里。使用普通GLX获取GL 4.x上下文的正确方法是什么? (我不能使用glfw或类似的东西,我正在处理给定的应用程序,我得到一个Display指针和一个Window id来使用,窗口已经存在)

1 个答案:

答案 0 :(得分:1)

感谢Nicol的提示我能够自己解决问题。看看glfw代码我做了以下(可能不适用于所有人)。

  • 使用给定的Display指针和Window id创建默认/旧学校GL上下文。我还调用glXQueryExtension来检查正确的glX支持。
  • 创建默认上下文后,我调用glewInit,但手动创建了glXChooseFBConfigSGIX'的函数指针。真的不知道为什么我必须使用SGIX扩展,没有费心去深入了解。
  • 这样我就可以获得一个合适的FBConfig结构来调用glXCreateContextAttribsARB并在销毁旧的上下文后创建一个新的上下文
  • Etvoilá,我得到了我的GL 4.x上下文

感谢Nicol,我不知道为什么我不想考虑其他代码。

这是我的解决方案:

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;
            }
        }

    }
}