GLX 使用 GLEW 创建 GL 4.x 上下文崩溃 glXChooseFBConfig
GLX create GL 4.x context with GLEW crashes glXChooseFBConfig
我在使用普通 GLX 和 GLEW (1.12) 创建 GL 4.x 上下文时遇到问题。我在这里找到的所有解决方案都不适合我。
我正在尝试做的事情(以及我在其他问题中发现的):创建一个 'base' GL 上下文,调用 glewInit(),然后使用 glXCreateContextAttribsARB( ...)。这对我不起作用,因为 glXChooseFBConfig 不断出现段错误。
我读到必须先调用 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 或类似的东西,我正在处理一个给定的应用程序,我得到一个显示指针和一个 Window id 来使用,window 已经存在)
感谢 Nicol 的提示,我能够自己解决问题。查看 glfw 代码,我做了以下操作(可能不适用于所有人)。
- 使用给定的显示指针和 Window id 创建默认/老式 GL 上下文。我还调用 glXQueryExtension 来检查是否有适当的 glX 支持。
- 创建默认上下文后,我调用了
glewInit
,但创建了指向 glXChooseFBConfigSGIX
'by hand' 的函数指针。真的不知道为什么我必须使用 SGIX 扩展,懒得去深入了解。
- 这样我就可以得到一个正确的 FBConfig 结构来调用
glXCreateContextAttribsARB
并在销毁旧的上下文后创建一个新的上下文
- Et voilá,我得到了我的工作 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;
}
}
}
}
我在使用普通 GLX 和 GLEW (1.12) 创建 GL 4.x 上下文时遇到问题。我在这里找到的所有解决方案都不适合我。
我正在尝试做的事情(以及我在其他问题中发现的):创建一个 'base' GL 上下文,调用 glewInit(),然后使用 glXCreateContextAttribsARB( ...)。这对我不起作用,因为 glXChooseFBConfig 不断出现段错误。
我读到必须先调用 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 或类似的东西,我正在处理一个给定的应用程序,我得到一个显示指针和一个 Window id 来使用,window 已经存在)
感谢 Nicol 的提示,我能够自己解决问题。查看 glfw 代码,我做了以下操作(可能不适用于所有人)。
- 使用给定的显示指针和 Window id 创建默认/老式 GL 上下文。我还调用 glXQueryExtension 来检查是否有适当的 glX 支持。
- 创建默认上下文后,我调用了
glewInit
,但创建了指向glXChooseFBConfigSGIX
'by hand' 的函数指针。真的不知道为什么我必须使用 SGIX 扩展,懒得去深入了解。 - 这样我就可以得到一个正确的 FBConfig 结构来调用
glXCreateContextAttribsARB
并在销毁旧的上下文后创建一个新的上下文 - Et voilá,我得到了我的工作 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;
}
}
}
}