glGenFramebuffers 还是 glGenFramebuffersEXT?

发布于 2024-11-27 15:27:52 字数 3607 浏览 0 评论 0原文

我很困惑。要在 Windows 上的 OpenGL 1.x 中使用帧缓冲区对象扩展 (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 并崩溃。有什么想法吗...?

I'm confused. To use the Framebuffer Object extension (FBO) in OpenGL 1.x on Windows, which of these do I use?:

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

As far as I can tell from reports from users with different hardware, some drivers support all combinations of neither, one of the two, or both.

Which is the right one to use? Do some drivers really support one but not the other? Is it correct to try to fall back from one to the other if not found?


Edit: I'm still having serious problems with ATI Radeon cards and the code around this. We just launched a commercial editor using this code (www.scirra.com). It seems no matter what combination of code I use to use FBOs, some different combination of users reports they cannot see anything at all (i.e. nothing renders).

Here's the code where I detect whether to use the ARB functions (no suffix) or the EXT-suffixed functions. This runs on startup:

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

Then later on during startup it creates a FBO in anticipation of rendering to texture:

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

I have been through many variations of this code, and I simply cannot get it to work for everyone. There is always a group of users who report nothing renders at all. ATI Radeon HD cards seem to be particularly problematic. I'm not sure if there's a driver bug involved, but I guess it's more likely my above code is making an incorrect assumption.

500 rep bounty and I'll send a free Business license to anyone who knows what's wrong! (Worth £99)


Edit 2: some more details. Here is a list of cards that this is known to fail on:

ATI Mobility Radeon HD 5650

ATI Radeon X1600 Pro

ATI Mobility Radeon HD 4200

No rendering to texture is actually done. It appears the glGenFramebuffers call alone stops rendering completely on these cards. I could defer creation of the FBO to the first time render-to-texture is actually done, but then presumably it will just stop rendering again.

I could use GLEW, but what does it do that my code doesn't? I had a look through the source and it seems to use a similar list of wglGetProcAddress. Methods are being returned in my case, else glGenFramebuffers would be NULL and crash. Any ideas...?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吹梦到西洲 2024-12-04 15:27:52

如果存在扩展 GL_EXT_framebuffer_object,则可以使用 wglGetProcAddress("glGenFramebuffersEXT");

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

If the extension GL_EXT_framebuffer_object is present, then you can use wglGetProcAddress("glGenFramebuffersEXT");.

If the OpenGL version is >= 3.0 (in this version the FBO extension was added to the core), then you can use wglGetProcAddress("glGenFramebuffers");.

云裳 2024-12-04 15:27:52

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

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

我对这个问题非常感兴趣(因为我有类似的疑问因为你)。

如果将 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 都具有“bind
Framebuffer”函数(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.

The code you have included is not the problem. Of course, the binding points shall be obtained as you already do.

In the case ARB_framebuffer_object is supported, uses the entry points without EXT suffix. In the case EXT_framebuffer_object is supported, uses the entry points with EXT suffix. If both are supported, you can select the implementation by getting the right binding points.

I am very interested on this issue (since I had a similar doubt because you).

If you compare the ARB specification with the EXT specification, you can notice a lot of differences.

Here, I will quote the most interesting ARB specification paragraphs on this topic.

The specification is the very long, but the ARB variant contains many discussions on the EXT compatibility issue. Since you're application run, the entry points are probably correct, and the error (as suggested by Nicolas Bolas) could be in the framebuffer completeness.

Introduce every check possible, and double-check the implementation twice (one taking ARB spec in mind, one taking EXT spec in mind).


What additional functionality does this extension include over
EXT_framebuffer_object?

   Currently we incorporate the following layered extensions:

     * EXT_framebuffer_multisample
     * EXT_framebuffer_blit
     * EXT_packed_depth_stencil

As well as the following features:

     * 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.
  ...

What are the other differences from 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.

This extension and EXT_framebuffer_object both have "bind
framebuffer" functions (BindFramebuffer and BindFramebufferEXT). Are
there any differences in functionality between the two functions?

    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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文