glGenFramebuffers还是glGenFramebuffersEXT?

时间:2011-08-02 13:39:37

标签: c++ windows opengl driver fbo

我很困惑。要在Windows上的OpenGL 1.x中使用Framebuffer对象扩展(FBO),我使用哪些?:

wglGetProcAddress("glGenFramebuffers");
// or
wglGetProcAddress("glGenFramebuffersEXT");

据我从不同硬件用户的报告中可以看出,某些驱动程序支持两者中的任何一种,两者之一或两者的组合。

哪个是正确的?有些司机真的支持一个但不支持另一个吗?如果没找到,试图从一个回到另一个是否正确?


编辑:我仍然遇到ATI Radeon卡及其相关代码的严重问题。我们刚刚使用此代码(www.scirra.com)推出了商业编辑器。似乎无论我使用哪种代码组合使用FBO,一些不同的用户组合报告他们根本看不到任何东西(即没有任何渲染)。

这是我检测是否使用ARB功能(无后缀)或EXT后缀功能的代码。这在启动时运行:

gl_extensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
gl_vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
gl_renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
gl_version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
gl_shading_language = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));

// If OpenGL version >= 3, framebuffer objects are core - enable regardless of extension
// (the flags are initialised to false)
if (atof(gl_version) >= 3.0)
{
    support_framebuffer_object = true;
    support_framebuffer_via_ext = false;
}
else
{
    // Detect framebuffer object support via ARB (for OpenGL version < 3) - also uses non-EXT names
    if (strstr(gl_extensions, "ARB_framebuffer_object") != 0)
    {
        support_framebuffer_object = true;
        support_framebuffer_via_ext = false;
    }
    // Detect framebuffer object support via EXT (for OpenGL version < 3) - uses the EXT names
    else if (strstr(gl_extensions, "EXT_framebuffer_object") != 0)
    {
        support_framebuffer_object = true;
        support_framebuffer_via_ext = true;
    }
}

然后在启动期间,它会创建一个FBO,以期呈现纹理:

// Render-to-texture support: create a frame buffer object (FBO)
if (support_framebuffer_object)
{
    // If support is via EXT (OpenGL version < 3), add the EXT suffix; otherwise functions are core (OpenGL version >= 3)
    // or ARB without the EXT suffix, so just get the functions on their own.
    std::string suffix = (support_framebuffer_via_ext ? "EXT" : "");

    glGenFramebuffers = (glGenFramebuffers_t)wglGetProcAddress((std::string("glGenFramebuffers") + suffix).c_str());
    glDeleteFramebuffers = (glDeleteFramebuffers_t)wglGetProcAddress((std::string("glDeleteFramebuffers") + suffix).c_str());
    glBindFramebuffer = (glBindFramebuffer_t)wglGetProcAddress((std::string("glBindFramebuffer") + suffix).c_str());
    glFramebufferTexture2D = (glFramebufferTexture2D_t)wglGetProcAddress((std::string("glFramebufferTexture2D") + suffix).c_str());
    glCheckFramebufferStatus = (glCheckFramebufferStatus_t)wglGetProcAddress((std::string("glCheckFramebufferStatus") + suffix).c_str());
    glGenerateMipmap = (glGenerateMipmap_t)wglGetProcAddress((std::string("glGenerateMipmap") + suffix).c_str());

    // Create a FBO in anticipation of render-to-texture
    glGenFramebuffers(1, &fbo);
}

我经历过这段代码的许多变化,我根本无法让它为每个人工作。始终有一组用户根本不报告任何渲染。 ATI Radeon HD卡似乎特别成问题。我不确定是否涉及驱动程序错误,但我想我的上述代码更可能做出错误的假设。

500代表赏金,​​我将向任何知道错误的人发送免费营业执照! (价值99英镑)


编辑2:更多细节。以下是已知失败的卡片列表:

ATI Mobility Radeon HD 5650

ATI Radeon X1600 Pro

ATI Mobility Radeon HD 4200

实际上没有渲染到纹理。单独glGenFramebuffers调用似乎完全停止在这些卡上呈现。我可以推迟创建FBO到第一次渲染到纹理实际上完成了,但是大概它会再次停止渲染。

我可以使用GLEW,但是我的代码没有做什么呢?我查看了源代码,似乎使用了类似的wglGetProcAddress列表。在我的情况下返回方法,否则glGenFramebuffers将为NULL并崩溃。任何想法......?

2 个答案:

答案 0 :(得分:10)

如果扩展程序GL_EXT_framebuffer_object存在,那么您可以使用wglGetProcAddress("glGenFramebuffersEXT");

如果OpenGL版本是&gt; = 3.0(在此版本中,FBO扩展名已添加到核心),那么您可以使用wglGetProcAddress("glGenFramebuffers");

答案 1 :(得分:4)

您包含的代码不是问题。当然,绑定点应该像你已经那样获得。

如果支持ARB_framebuffer_object,则使用不带 EXT 后缀的入口点。在支持EXT_framebuffer_object的情况下,使用带有 EXT 后缀的入口点。如果两者都受支持,您可以通过获取正确的绑定点来选择实现。

我对这个问题很感兴趣(因为你有a similar doubt因为你)。

如果将 ARB 规范与 EXT 规范进行比较,您会发现很多差异。

在这里,我将引用关于此主题的最有趣的 ARB 规范段落。

规范很长,但 ARB 变体包含许多关于 EXT 兼容性问题的讨论。由于您正在运行应用程序,因此入口点可能是正确的,并且错误(由Nicolas Bolas建议)可能在帧缓冲区完整性中。

介绍每次检查,并仔细检查实施两次(一次考虑 ARB 规范,一次考虑 EXT 规范)。


  

此扩展程序包含哪些附加功能          EXT_framebuffer_object?

   Currently we incorporate the following layered extensions:

     * EXT_framebuffer_multisample
     * EXT_framebuffer_blit
     * EXT_packed_depth_stencil
  

以及以下功能:

     * Permit attachments with different width and height (mixed
       dimensions)

     * Permit color attachments with different formats (mixed
       formats).

     * Render to 1 and 2 component R/RG formats that are provided
       via the ARB_texture_rg extension. L/A/LA/I will be
       left for a separate (trivial) extension.

     * Gen'ed names must be used for framebuffer objects and
       renderbuffers.

     * Added FramebufferTextureLayer.
  ...

  

与EXT_framebuffer_object有什么不同。

     * Framebuffer completeness only considers the attachments named
       by DRAW_BUFFERi and READ_BUFFER.  Any other attachments do
       not affect framebuffer completeness.  (In
       EXT_framebuffer_object, all attachments affected framebuffer
       completeness, independent of the DRAW_BUFFERi and READ_BUFFER
       state.)
     * Added new queries for the sizes of the bit planes for color, 
       depth and stencil attachments at a framebuffer attachment point.
     * Added new queries for framebuffer attachment component type and
       color encoding.
     * Many other minor tweaks to synchronize with the GL3 framebuffer
       objects.
     * ARB FBOs are not shareable.

  

此扩展名和EXT_framebuffer_object都有“绑定”           framebuffer“functions(BindFramebuffer和BindFramebufferEXT)。是           这两个函数之间的功能有什么不同吗?

    RESOLVED: Yes. Both extensions will create a new framebuffer object
    if called with an unused name. However, BindFramebuffer defined in
    this extension will generate an INVALID_OPERATION error if the name
    provided has not been generated by GenFramebuffer. That error did
    not exist in EXT_framebuffer_object, and this extension does not
    modify the behavior of BindFramebufferEXT. This difference also
    applies to BindRenderbuffer from this extension vs.
    BindRenderbufferEXT from EXT_framebuffer_object.