繁体   English   中英

GLX 上下文创建错误:GLXBadFBConfig

[英]GLX Context Creation Error: GLXBadFBConfig

我使用glXCreateContext创建上下文,但 function 已被弃用,并且总是导致 OpenGL 版本 3.0,我至少需要 4 GLXContext glXCreateContextAttribsARB(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int* attrib_list); 替换glXCreateContext “新” function 允许在其attrib_list中明确指定主要版本、次要版本、配置文件等,例如:

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

然后使用 function:

glXCreateContextAttribsARB(dpy, config, NULL, true, context_attribs);

这就是我在我的程序中所做的。 window 已经创建,dpy 是指向 Display 的有效指针。 我这样定义的config

// 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确认。 glxinfo | grep 0x120 它完全满足了上述要求。 到目前为止,一切都很好。 但是在运行应用程序时(编译工作正常),我收到以下错误:

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

现在,这就是错误的原因:

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

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

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

 * If <config> does not support compatible OpenGL contexts providing the requested API major and minor version, forward-compatible flag, and debug context flag, GLXBadFBConfig is generated.

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

如果您还不熟悉OpenGL 配置文件的概念 - 您可以从这里开始

glxinfo显示有关 Core 和 Compatible 配置文件的信息,可以像这样过滤掉:

glxinfo | grep -e "OpenGL version" -e "Core" -e "Compatible"

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

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中过滤掉不受支持的版本,就像在配置文件发布前几天所做的那样介绍了。 Core Profile的情况下,某些 OpenGL 驱动程序请求支持的最高版本(例如,没有禁用高于请求的版本的功能)可能会很棘手 - 以下代码片段可能很有用:

  //! 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"; }
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM