glGenFramebuffers или glGenFramebuffersEXT? - PullRequest
8 голосов
/ 02 августа 2011

Я в замешательстве. Чтобы использовать расширение объекта Framebuffer (FBO) в OpenGL 1.x в Windows, какие из них мне использовать?:

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 будет НЕДЕЙСТВИТЕЛЕН и сбой. Есть идеи ...?

Ответы [ 2 ]

10 голосов
/ 02 августа 2011

Если присутствует расширение GL_EXT_framebuffer_object, вы можете использовать wglGetProcAddress("glGenFramebuffersEXT");.

Если версия OpenGL> = 3.0 (в этой версии в ядро ​​было добавлено расширение FBO), тогда вы можете использовать wglGetProcAddress("glGenFramebuffers");.

4 голосов
/ 26 августа 2011

Код, который вы включили, не является проблемой.Конечно, точки привязки должны быть получены, как вы уже делаете.

В случае, если поддерживается ARB_framebuffer_object , используются точки входа без суффикса EXT .В случае, если поддерживается EXT_framebuffer_object , используются точки входа с суффиксом EXT .Если оба поддерживаются, вы можете выбрать реализацию, получив правильные точки привязки.

Я очень заинтересован в этом вопросе (поскольку у меня было подобное сомнение , потому что вы).

Если вы сравните спецификацию ARB со спецификацией EXT , вы можете заметить множество различий.

Здесь я приведу наиболее интересные ARB параграфы спецификации на эту тему.

Спецификация очень длинная, но вариант ARB содержит много дискуссий по проблеме совместимости EXT .Поскольку вы запускаете приложение, точки входа, вероятно, верны, и ошибка (как предложил Николас Болас) может быть в полноте кадрового буфера.

Ввести каждую возможную проверку и дважды проверить реализацию дважды (один с учетом 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.
...