Определение возможностей OpenGL, поддерживаемых средством рендеринга

Одно из преимуществ использования OpenGL - то, что это расширяемо. Расширение обычно представляется одним или более поставщиками и затем позже принято Рабочей группой OpenGL. Некоторым расширениям способствует от специфичного для поставщика расширения до одного совместно используемого больше чем один поставщик, иногда даже включаемый в базовый OpenGL API. Расширения позволяют OpenGL охватывать инновации, но потребовать Вы проверять, что функциональность OpenGL Вы хотите использовать, доступны.

Поскольку расширения могут быть представлены на уровне поставщика, больше чем одно расширение может обеспечить ту же основную функциональность. Могло бы также быть ARB-утвержденное расширение, имеющее функциональность, подобную тому из специфичного для поставщика расширения. Ваше приложение должно предпочесть базовую функциональность или ARB-утвержденные расширения по определенным для определенного поставщика, когда обоим предлагает то же средство рендеринга. Это упрощает прозрачно поддерживать новые средства рендеринга от других поставщиков.

Поскольку определенная функциональность становится широко принятой, она может быть перемещена в базовый OpenGL API ARB. В результате функциональность, которую Вы хотите использовать, могла быть включена как расширение как часть базового API или обоих. Например, возможность объединить среды текстуры поддерживается через GL_ARB_texture_env_combine и GL_EXT_texture_env_combine расширения. Это - также часть базовой версии 1.3 OpenGL API. Несмотря на то, что у каждого есть схожая функциональность, они используют различный синтаксис. Вы, возможно, должны зарегистрироваться в нескольких местах (базовый OpenGL API и дополнительные строки), чтобы определить, поддерживает ли определенное средство рендеринга функциональность, которую Вы хотите использовать.

Обнаружение функциональности

OpenGL имеет два типа команд — те, которые являются частью базового API и тех, которые являются частью расширения OpenGL. Ваше приложение сначала должно проверить на версию базового OpenGL API и затем проверить на доступные расширения. Следует иметь в виду, что функциональность OpenGL доступна на основе на средство рендеринга. Например, средство рендеринга программного обеспечения не могло бы поддерживать эффекты вуали даже при том, что эффекты вуали доступны в расширении OpenGL, реализованном поставщиком оборудования в той же системе. Поэтому важно, чтобы Вы проверили на функциональность на основе на средство рендеринга.

Независимо от какой функциональности Вы проверяете на, подход является тем же. Необходимо вызвать функцию OpenGL glGetString дважды. В первый раз передают GL_VERSION постоянный. Функция возвращает строку, указывающую версию OpenGL. Во второй раз, передача GL_EXTENSIONS постоянный. Функция возвращает указатель на дополнительную строку имени. Дополнительная строка имени является разделенным пробелами списком расширений OpenGL, поддерживающихся текущим средством рендеринга. Эта строка может быть довольно длинной, не выделяйте строку фиксированной длины для возвращаемого значения glGetString функция. Используйте указатель и оцените строку на месте.

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

Если расширение становится частью базового OpenGL API, OpenGL продолжает экспортировать строки имени способствовавших расширений. Это также продолжает поддерживать предыдущие версии любого расширения, экспортированного в более ранних версиях OS X. Поскольку расширения обычно не удаляются, методология, которую Вы используете сегодня для проверки на функцию, работает в будущих версиях OS X.

Проверка функциональность, несмотря на то, что довольно прямой, включает запись большого блока кода. Лучший способ проверить на функциональность OpenGL состоит в том, чтобы реализовать функцию проверки возможностей, которую Вы вызываете, когда Ваша программа запускает, и затем любое время изменения средства рендеринга. Перечисление 8-1 показывает выборку кода что проверки на несколько расширений. Подробное объяснение каждой строки кода появляется после перечисления.

  Проверка перечисления 8-1 функциональность OpenGL

GLint maxRectTextureSize;
GLint myMaxTextureUnits;
GLint myMaxTextureSize;
const GLubyte * strVersion;
const GLubyte * strExt;
float myGLVersion;
GLboolean isVAO, isTexLOD, isColorTable, isFence, isShade,
          isTextureRectangle;
strVersion = glGetString (GL_VERSION); // 1
sscanf((char *)strVersion, "%f", &myGLVersion);
strExt = glGetString (GL_EXTENSIONS); // 2
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &myMaxTextureUnits); // 3
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &myMaxTextureSize); // 4
isVAO =
    gluCheckExtension ((const GLubyte*)"GL_APPLE_vertex_array_object",strExt); // 5
isFence = gluCheckExtension ((const GLubyte*)"GL_APPLE_fence", strExt); // 6
isShade =
     gluCheckExtension ((const GLubyte*)"GL_ARB_shading_language_100", strExt); // 7
isColorTable =
     gluCheckExtension ((const GLubyte*)"GL_SGI_color_table", strExt) ||
             gluCheckExtension ((const GLubyte*)"GL_ARB_imaging", strExt); // 8
isTexLOD =
     gluCheckExtension ((const GLubyte*)"GL_SGIS_texture_lod", strExt) ||
                                  (myGLVersion >= 1.2); // 9
isTextureRectangle = gluCheckExtension ((const GLubyte*)
                                 "GL_EXT_texture_rectangle", strExt);
if (isTextureRectangle)
      glGetIntegerv (GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &maxRectTextureSize);
else
     maxRectTextureSize = 0; // 10

Вот то, что делает код:

  1. Получает строку, указывающую версию OpenGL.

  2. Получает дополнительную строку имени.

  3. Вызывает функцию OpenGL glGetIntegerv получить значение атрибута передало ему, который, в этом случае, является максимальным количеством модулей текстуры.

  4. Получает максимальный размер текстуры.

  5. Проверки, поддерживаются ли объекты массива вершины.

  6. Проверки на расширение предела Apple.

  7. Проверки на поддержку версии 1.0 языка штриховки OpenGL.

  8. Проверки на поддержку таблицы цветов RGBA-формата. В этом случае код должен проверить на специфичную для поставщика строку и на строку ARB. Если любой присутствует, функциональность поддерживается.

  9. Проверки на расширение имели отношение к параметру уровня детализации текстуры (ЛОД). В этом случае код должен проверить на специфичную для поставщика строку и на версию OpenGL. Если строка поставщика присутствует, или версия OpenGL больше, чем или равна 1,2, функциональность поддерживается.

  10. Получает предел OpenGL для прямоугольных текстур. Для некоторых расширений, таких как прямоугольное расширение текстуры, может не быть достаточно проверить, поддерживается ли функциональность. Вы, возможно, также должны проверить пределы. Можно использовать glGetIntegerv и связанные функции (glGetBooleanv, glGetDoublev, glGetFloatv) получить множество значений параметров.

Можно расширить этот пример для создания проверяющей полную функциональность подпрограммы для приложения. Для получения дополнительной информации посмотрите GLCheck.c файл в Какао пример приложения OpenGL.

Код в Перечислении 8-2 показывает один способ запросить текущее средство рендеринга. Это использует API CGL, который можно вызвать из приложений Какао. В действительности необходимо выполнить итерации по всем дисплеям и всем средствам рендеринга для каждого дисплея для получения истинного изображения функциональности OpenGL, доступной в определенной системе. Также необходимо обновить функциональность, создают снимки каждый раз список дисплеев или выводят на экран изменения конфигурации.

Перечисление 8-2  , Настраивающее допустимый контекст рендеринга для получения информацию функциональности средства рендеринга

#include <OpenGL/OpenGL.h>
#include <ApplicationServices/ApplicationServices.h>
CGDirectDisplayID display = CGMainDisplayID (); // 1
CGOpenGLDisplayMask myDisplayMask =
                CGDisplayIDToOpenGLDisplayMask (display); // 2
 
{ // Check capabilities of display represented by display mask
    CGLPixelFormatAttribute attribs[] = {kCGLPFADisplayMask,
                             myDisplayMask,
                             0}; // 3
    CGLPixelFormatObj pixelFormat = NULL;
    GLint numPixelFormats = 0;
    CGLContextObj myCGLContext = 0;
    CGLContextObj curr_ctx = CGLGetCurrentContext (); // 4
    CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats); // 5
    if (pixelFormat) {
        CGLCreateContext (pixelFormat, NULL, &myCGLContext); // 6
        CGLDestroyPixelFormat (pixelFormat); // 7
        CGLSetCurrentContext (myCGLContext); // 8
        if (myCGLContext) {
            // Check for capabilities and functionality here
        }
    }
    CGLDestroyContext (myCGLContext); // 9
    CGLSetCurrentContext (curr_ctx); // 10
}

Вот то, что делает код:

  1. Получает дисплей ID основного дисплея.

  2. Отображает дисплей ID на маску OpenGL.

  3. Заполняется формат пикселя приписывает массив с атрибутом маски дисплея и значением маски.

  4. Сохраняет текущий контекст так, чтобы он мог быть восстановлен позже.

  5. Получает объект формата пикселя для дисплея. numPixelFormats параметр указывает, сколько форматов пикселя перечислено в объекте формата пикселя.

  6. Создает контекст на основе первого формата пикселя в списке, предоставленном объектом формата пикселя. Только одно средство рендеринга будет связано с этим контекстом.

    В Вашем приложении необходимо было бы выполнить итерации через все форматы пикселя для этого дисплея.

  7. Уничтожает объект формата пикселя, когда он больше не необходим.

  8. Устанавливает текущий контекст в недавно создаваемый, контекст единственного средства рендеринга. Теперь Вы готовы проверить на функциональность, поддерживаемую текущим средством рендеринга. См. Перечисление 8-1 для примера проверяющего функциональность кода.

  9. Уничтожает контекст, потому что он больше не необходим.

  10. Восстанавливает ранее сохраненный контекст как текущий контекст, таким образом не гарантируя проникновения на пользователя.

Инструкции для кода, проверяющего на функциональность

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

Средство рендеринга OpenGL зависящие от реализации значения

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

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

Таблица 8-1  Общие ограничения средства рендеринга OpenGL

Максимальный размер текстуры

GL_MAX_TEXTURE_SIZE

Число плоскостей буфера глубины

GL_DEPTH_BITS

Число плоскостей буфера шаблонов

GL_STENCIL_BITS

Предел на размере и сложности Ваших программ построения теней является ключевой областью, которую необходимо протестировать. Все аппаратное обеспечение машинной графики поддерживает ограниченную память для передачи атрибутов в программы построения теней фрагмента и вершину. Ваше приложение должно или сохранить свое использование ниже минимумов, как определено в спецификации, или это должно проверить ограничения программы построения теней, задокументированные в Таблицу 8-2, и выбрать программы построения теней, которые являются в тех пределах.

Таблица 8-2  ограничения программы построения теней OpenGL

Максимальное количество атрибутов вершины

GL_MAX_VERTEX_ATTRIBS

Максимальное количество универсальных векторов вершины

GL_MAX_VERTEX_UNIFORM_COMPONENTS

Максимальное количество универсальных векторов фрагмента

GL_MAX_FRAGMENT_UNIFORM_COMPONENTS

Максимальное количество переменных векторов

GL_MAX_VARYING_FLOATS

Максимальное количество модулей текстуры, применимых в вершинном шейдере

GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS

Максимальное количество модулей текстуры, применимых в программе построения теней фрагмента

GL_MAX_TEXTURE_IMAGE_UNITS