Использование расширений OpenGL в Windows

Я хочу использовать функции, представленные в расширениях OpenGL. Я использую Windows, как мне это сделать?

Ответов (4)

Решение

Простое решение : используйте GLEW . Посмотрите, как здесь .

Сложное решение : если у вас есть действительно веская причина не использовать GLEW, вот как добиться того же без него:

Определите расширение OpenGL и API-интерфейсы расширений, которые вы хотите использовать. Расширения OpenGL перечислены в реестре расширений OpenGL .

Пример: я хочу использовать возможности расширения EXT_framebuffer_object . API, которые я хочу использовать из этого расширения:

glGenFramebuffersEXT()
glBindFramebufferEXT()
glFramebufferTexture2DEXT()
glCheckFramebufferStatusEXT()
glDeleteFramebuffersEXT()

Проверьте, поддерживает ли ваша графическая карта расширение, которое вы хотите использовать. Если да, значит, ваша работа почти сделана! Загрузите и установите последние версии драйверов и SDK для вашей видеокарты.

Пример: видеокарта в моем ПК - NVIDIA 6600 GT . Итак, я захожу на веб-страницу NVIDIA OpenGL Extension Specifications и обнаруживаю, что расширение EXT_framebuffer_object поддерживается. Затем я загружаю последнюю версию NVIDIA OpenGL SDK и устанавливаю ее.

Производитель вашей графической карты предоставляет файл заголовка glext.h (или файл заголовка с аналогичным названием) со всеми декларациями, необходимыми для использования поддерживаемых расширений OpenGL. (Обратите внимание, что не все расширения могут поддерживаться.) Либо поместите этот файл заголовка в место, где ваш компилятор сможет его забрать, либо включите его каталог в список включаемых каталогов вашего компилятора.

Добавьте #include <glext.h> строку в свой код, чтобы включить файл заголовка в ваш код.

Откройте glext.h , найдите API, который хотите использовать, и возьмите его соответствующее уродливое объявление.

Пример: я ищу указанные выше API фреймбуфера и нахожу их соответствующие уродливые объявления:

typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); for GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei, GLuint *);

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

Для каждого API расширения, которое вы хотите использовать, добавьте в свой код объявления имени функции как типа уродливой строки.

Пример:

PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;

Хотя это выглядит некрасиво, все, что мы делаем, - это объявляем указатели на функции того типа, который соответствует API расширения.

Инициализируйте эти указатели на функции с их законными функциями. Эти функции предоставляются библиотекой или драйвером. Для этого нам нужно использовать функцию wglGetProcAddress () .

Пример:

glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) wglGetProcAddress("glGenFramebuffersEXT");
glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) wglGetProcAddress("glBindFramebufferEXT");
glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) wglGetProcAddress("glFramebufferTexture2DEXT");
glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) wglGetProcAddress("glCheckFramebufferStatusEXT");
glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) wglGetProcAddress("glDeleteFramebuffersEXT");

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

Пример:

if (NULL == glGenFramebuffersEXT || NULL == glBindFramebufferEXT || NULL == glFramebufferTexture2DEXT
    || NULL == glCheckFramebufferStatusEXT || NULL == glDeleteFramebuffersEXT)
{
    // Extension functions not loaded!
    exit(1);
}

Вот и все, мы закончили! Теперь вы можете использовать эти указатели на функции так же, как если бы существовали вызовы функций.

Пример:

glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorTex[0], 0);

Ссылка: Выход за рамки OpenGL 1.1 для Windows, автор: Дэйв Эстл. Статья немного устарела, но содержит всю необходимую информацию, чтобы понять, почему эта жалкая ситуация существует в Windows и как ее обойти.

GL3W - это общедоступный скрипт, который создает библиотеку, которая загружает только основные функции OpenGL 3/4. Его можно найти на github по адресу:

https://github.com/skaslev/gl3w

GL3W требует Python 2.6 для создания библиотек и заголовков для OpenGL; после этого он не требует Python.

@Kronikarz: Судя по всему, GLEW - это путь в будущее. NVIDIA уже поставляет его вместе со своим OpenGL SDK . И его последний выпуск был в 2007 году по сравнению с GLEE, который был в 2006 году.

Но использование обеих библиотек мне кажется почти одинаковым. (У GLEW есть init (), который нужно вызывать перед чем-либо еще.) Итак, вам не нужно переключаться, если вы не обнаружите, что какое-либо расширение не поддерживается в GLEE.

«Очень веская причина» не использовать GLEW может заключаться в том, что библиотека не поддерживается вашим компилятором / IDE. Например: Borland C++ Builder.

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