首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GLX上下文创建错误: GLXBadFBConfig

GLX上下文创建错误: GLXBadFBConfig
EN

Stack Overflow用户
提问于 2021-01-01 17:20:00
回答 1查看 2.6K关注 0票数 1

我使用glXCreateContext来创建上下文,但是这个函数被废弃了,并且总是导致OpenGL版本3.0,在这里我至少需要4个版本。现在,如果我理解正确的话,GLXContext glXCreateContextAttribsARB(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int* attrib_list);取代了glXCreateContext。“新”函数允许在它的attrib_list中显式地指定主版本、次要版本、概要文件等,例如:

代码语言:javascript
复制
int context_attribs[] =
{
    GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
    GLX_CONTEXT_MINOR_VERSION_ARB, 5,
    GLX_CONTEXT_FLAGS_ARB,         GLX_CONTEXT_DEBUG_BIT_ARB,
    GLX_CONTEXT_PROFILE_MASK_ARB,  GLX_CONTEXT_COMPABILITY_PROFILE_BIT_ARB,
    None
};

然后使用以下函数:

代码语言:javascript
复制
glXCreateContextAttribsARB(dpy, config, NULL, true, context_attribs);

这就是我在我的节目中所做的。窗口已经创建,dpy是要显示的有效指针。我定义的config是这样的:

代码语言:javascript
复制
// GLXFBConfig config; created at the beginning of the program
int attrib_list[] =
{
    GLX_RENDER_TYPE,    GLX_RGBA_BIT,
    GLX_RED_SIZE,       8,
    GLX_GREEN_SIZE,     8,
    GLX_BLUE_SIZE,      8,
    GLX_DEPTH_SIZE,     24,
    GLX_DOUBLEBUFFER,   True,
    None
};
int nAttribs;

config = glXChooseFBConfig(dpy, 0, attrib_list, &nAttribs);

使用glxinfo进行检查时,我对它有正确的可视化;vi已设置为0x120,可以通过glxinfo | grep 0x120确认。它正好满足了上述的要求。到现在为止还好。但是,当运行应用程序(编译工作正常)时,我得到以下错误:

代码语言:javascript
复制
X Error of failed request: GLXBadFBConfig
Major opcode of failed request: 152 (GLX)
Minor opcode of failed request: 34 ()
Serial number of failed request: 31
Current serial number in output stream: 31

现在,这就是错误的意义所在:

如果不支持提供请求的API主要和次要版本、前向兼容标志和调试上下文标志的兼容OpenGL上下文,则生成GLXBadFBConfig。

所以,这个问题很简单。不过我不知道怎么解决。本质上,这意味着无法找到与我在attrib_list[]中指定的属性和context_attribs中的属性相对应的attrib_list[]上下文。使用glxinfo | grep Max,我确认了我的最高可能的OpenGL版本是4.5。我想听听你对我现在该做什么的建议。我在context_attribs中使用属性已经有一段时间了,但是没有得到任何结果。也许问题真的出在别的地方。也许我对GLX功能的概念在总体上是有缺陷的,如果是的话,请指出!

EN

回答 1

Stack Overflow用户

发布于 2021-01-02 07:38:34

上下文的规范清楚地说明了何时可能返回GLXBadFBConfig错误:

*如果不支持提供请求的API主要和次要版本、前向兼容标志和调试上下文标志的兼容OpenGL上下文,则生成GLXBadFBConfig。

这可能令人困惑(因为错误与已经创建的GLXFBConfig无关),但这就是我们所拥有的。因此,您所犯错误的最明显原因是您的系统实际上不支持您所请求的 OpenGL 4.5 Compatible Profile --尽管它可能支持较低版本的OpenGL 4.5 Core Profile或兼容/核心配置文件。对于Mesa驱动程序来说,这是一个非常常见的情况,它只支持OpenGL 3.3+核心概要文件,只支持对许多GPU兼容的OpenGL 3.0配置文件(但不是全部--有些支持Radeons这样的更好的兼容概要文件)。

如果您还不熟悉对OpenGL概要文件的概念,那么可以使用从这里开始

glxinfo显示了关于核心和兼容配置文件的信息,这些信息可以像下面这样被过滤掉:

代码语言:javascript
复制
glxinfo | grep -e "OpenGL version" -e "Core" -e "Compatible"

它在虚拟Ubuntu 18.04上将此返回给我:

代码语言:javascript
复制
OpenGL core profile version string: 3.3 (Core Profile) Mesa 19.2.8
OpenGL version string: 3.1 Mesa 19.2.8

如果您的应用程序确实需要OpenGL 4.5或更高版本,那么只需尝试使用GLX_CONTEXT_CORE_PROFILE_BIT_ARB位而不是GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB创建上下文,并确保不使用任何不推荐的功能。

请注意,请求特定版本的兼容概要文件通常是没有意义的--只需跳过版本参数就可以获得最受支持的版本,并从已经创建的上下文的GL_VERSION/GL_MAJOR_VERSION中筛选出不受支持的版本,就像在概要文件引入前几天所做的那样。对于核心配置文件来说,对于一些OpenGL驱动程序来说,请求最受支持的版本(例如,没有禁用高于请求的版本的功能)可能会很棘手--下面的代码片段可能很有用:

代码语言:javascript
复制
  //! A dummy XError handler which just skips errors
  static int xErrorDummyHandler (Display* , XErrorEvent* ) { return 0; }
  ...

  Window      aWindow    = ...;
  Display*    aDisp      = ...;
  GLXFBConfig anFBConfig = ...;
  bool toDebugContext = false;

  GLXContext  aGContext  = NULL
  const char* aGlxExts   = glXQueryExtensionsString (aDisp, aVisInfo.screen);
  if (!checkGlExtension (aGlxExts, "GLX_ARB_create_context_profile"))
  {
    std::cerr << "GLX_ARB_create_context_profile is NOT supported\n";
    return;
  }

  // Replace default XError handler to ignore errors.
  // Warning - this is global for all threads!
  typedef int (*xerrorhandler_t)(Display* , XErrorEvent* );
  xerrorhandler_t anOldHandler = XSetErrorHandler(xErrorDummyHandler);

  typedef GLXContext (*glXCreateContextAttribsARB_t)(Display* dpy, GLXFBConfig config,
                                                     GLXContext share_context, Bool direct,
                                                     const int* attrib_list);
  glXCreateContextAttribsARB_t aCreateCtxProc = (glXCreateContextAttribsARB_t )glXGetProcAddress((const GLubyte* )"glXCreateContextAttribsARB");
  int aCoreCtxAttribs[] =
  {
    GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
    GLX_CONTEXT_MINOR_VERSION_ARB, 2,
    GLX_CONTEXT_PROFILE_MASK_ARB,  GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
    GLX_CONTEXT_FLAGS_ARB,         toDebugContext ? GLX_CONTEXT_DEBUG_BIT_ARB : 0,
    0, 0
  };

  // try to create a Core Profile of highest OpenGL version (up to 4.6)
  for (int aLowVer4 = 6; aLowVer4 >= 0 && aGContext == NULL; --aLowVer4)
  {
    aCoreCtxAttribs[1] = 4;
    aCoreCtxAttribs[3] = aLowVer4;
    aGContext = aCreateCtxProc (aDisp, anFBConfig, NULL, True, aCoreCtxAttribs);
  }
  for (int aLowVer3 = 3; aLowVer3 >= 2 && aGContext == NULL; --aLowVer3)
  {
    aCoreCtxAttribs[1] = 3;
    aCoreCtxAttribs[3] = aLowVer3;
    aGContext = aCreateCtxProc (aDisp, anFBConfig, NULL, True, aCoreCtxAttribs);
  }
  bool isCoreProfile = aGContext != NULL;
  if (!isCoreProfile)
  {
    std::cerr << "glXCreateContextAttribsARB() failed to create Core Profile\n";
  }

  // try to create Compatible Profile
  if (aGContext == NULL)
  {
    int aCtxAttribs[] =
    {
      GLX_CONTEXT_FLAGS_ARB, toDebugContext ? GLX_CONTEXT_DEBUG_BIT_ARB : 0,
      0, 0
    };
    aGContext = aCreateCtxProc (aDisp, anFBConfig, NULL, True, aCtxAttribs);
  }
  XSetErrorHandler (anOldHandler);

  // fallback to glXCreateContext() as last resort
  if (aGContext == NULL)
  {
    aGContext = glXCreateContext (aDisp, aVis.get(), NULL, GL_TRUE);
    if (aGContext == NULL) { std::cerr << "glXCreateContext() failed\n"; }
  }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65531911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档