glGenFramebuffers or glGenFramebuffersEXT?
Asked Answered
R

2

8

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

Runway answered 2/8, 2011 at 13:39 Comment(3)
I'm not looking to get the bounty here, but you might be interested in GLEW (#17870). It's helped ease the pain of managing extensions across multiple platforms in several projects for me now and I would highly recommend it over calling wglGetProcAddress manually.Aubarta
It would be really helpful if you told us what specifically was going wrong. How you're using FBOs, what ATI cards are having a problem, etc. Do you have any remote reports from your customers? Perhaps some logging about which kind of FBO is supported, whether the framebuffer is complete, etc?Profitsharing
Have you tried activating window frame buffer after creating the new one. Some implementations might switch to it immediately.Centi
E
10

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");.

Enneagon answered 2/8, 2011 at 13:45 Comment(6)
Thanks. If the OpenGL version is >= 3, will wglGetProcAddress("glGenFramebuffersEXT") still work or has it been removed?Runway
@AshleysBrain: I think that depends on the driver manufacturer, but I'm not sure about that. Maybe someone else can jump in :-)Enneagon
Oh well I guess it doesn't matter. I'll just request the non-EXT version if OpenGL version >= 3. Thanks!Runway
Note that the GL_ARB_framebuffer_object extension also offers glGenFramebuffers. It doesn't use suffixes on its function or enum names, so they are identical to the 3.x version.Profitsharing
So what was the problem? Using EXT on >= 3.0 ?Compose
@paulm, yeah basically, using EXT suffix when you're on OGL >= 3.0 or when the ARB extension is advertised.Enneagon
N
4

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.
Nakitanalani answered 26/8, 2011 at 9:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.