OpenGL/GLEW: как выбрать правильное/существующее перечисление, не вызывая ошибки времени компиляции

В настоящее время я использую glew для обнаружения некоторых функций графического процессора связанного контекста openGL.

Представьте себе класс текстуры, в котором я хочу использовать перечисления openGL 3.0, если они доступны, и вернуться к расширениям, если opengl 3.0 не на месте, но расширение, т.е.:

uint32 chooseGlInternalFormat(uint32 _pixelType, uint32 _pixelFormat)
{
    uint32 ret;
    //...
    if(GLEW_EXT_texture_integer || GLEW_VERSION_3_0)
    {
        bool bUseExt = !GLEW_VERSION_3_0; //if only the extension is available but not gl 3.0, fallback
        ret = bUseIntEXT ? GL_LUMINANCE8UI_EXT : GL_R8UI;
    }
    //...
}

очевидно, это вызывает ошибку времени компиляции, поскольку GL_R8UI не будет существовать, если opengl 3.0 не поддерживается. Каков общий способ решения этой проблемы?


person moka    schedule 21.09.2011    source источник
comment
Почему это не работает? IIRC, эти макросы расширяются до вызовов функций во время выполнения (или глобальных переменных, заполненных glewInit). Принимая во внимание, что перечисления всегда предоставляются заголовочным файлом.   -  person Ben Voigt    schedule 21.09.2011
comment
ну, например, в настоящее время я разрабатываю на OSX, которая не поддерживает полную функциональность ogl 3.0. Тем не менее, я хочу принять это во внимание для будущего использования. Теперь, когда на моей платформе ogl 3.0 не завершен, некоторые из его перечислений просто не определены , что вызывает ошибку времени компиляции. в приведенном выше примере GL_R8UI не определен.   -  person moka    schedule 21.09.2011
comment
@moka: наличие перечислений в ваших заголовках не помешает, независимо от того, предоставляется ли OpenGL-3 вашей целевой платформой или нет. Кроме того, корректировки кодового пути для конкретной платформы реализуются посредством условной компиляции, т.е. #ifdef … {foobarblah;} #endif; GLEW устанавливает несколько определений в зависимости от того, какие функции включены во время компиляции. Они устанавливаются в зависимости от того, что может делать целевая платформа.   -  person datenwolf    schedule 21.09.2011
comment
Хорошо, скажем, я хочу использовать glGenerateMipmap в ogl 3.0 и более поздних версиях и glGenerateMipmapEXT во всех более ранних версиях. Какой должна быть надежная проверка времени компиляции для использования правильной функции? комментарии к ответу pmr показывают, что #ifdef GL_VERSION_3_0 в большинстве случаев не работает, есть идеи?   -  person moka    schedule 23.09.2011


Ответы (1)


Некоторые более крупные приложения берут новейшую спецификацию перечисления и добавляют на ее основе собственные перечисления. Если вам это нужно только один раз, вы можете просто определить свое собственное перечисление для этого единственного случая.

person pmr    schedule 21.09.2011
comment
не будут ли эти перечисления конфликтовать с теми, которые на самом деле уже есть, если существует opengl 3.x? - person moka; 21.09.2011
comment
@moka Конечно, вам нужно дать им разные имена. Важны значения, а не имена. - person pmr; 21.09.2011
comment
ах хорошо, я думаю, что я понял это сейчас. Еще одна вещь, которую я только что понял, заключается в том, что, хотя GLEW работает только во время выполнения, я могу использовать простые старые определения препроцессора #ifdef GL_VERSION_3_0 для включения материала только при достижении определенной версии GL. Спасибо за ваши подсказки! - person moka; 21.09.2011
comment
Препроцессор не вариант, если вы пытаетесь распространять двоичные файлы, а код болезненный и сложный для тестирования/отладки. Вот почему большинство проектов предпочитают хакерский обходной путь. - person pmr; 21.09.2011
comment
Не могли бы вы пояснить, почему определение GL_VERSION_3_0 не будет работать с двоичным файлом, если оно используется внутри .cpp? - person moka; 21.09.2011
comment
@moka Поскольку препроцессор запускается только при компиляции приложения, но GL-версия платформы, на которой выполняется двоичный файл, может быть определена только во время выполнения. - person pmr; 21.09.2011
comment
@moka: вы можете использовать препроцессор для обнаружения SDK, который вы создаете, например #ifdef GL_R8UI, но не тестируйте #ifdef GL_VERSION_3_0, поскольку он всегда будет определен, он расширяется до теста времени выполнения. - person Ben Voigt; 21.09.2011
comment
хорошая идея, Бен, как вы думаете, если я сделаю это для всех форматов, которые мне нужны: #ifndef GL_RGB8UI #define GL_RGB8UI GL_RGB8UI_EXT #endif будет безопасно? тогда я мог бы использовать только GL_RGB8UI в моем реальном коде, и если бы он автоматически возвращался к GL_RGB8UI_EXT, если это необходимо, верно? - person moka; 21.09.2011