Войти
ПрограммированиеСтатьиГрафика

OpenGL: Extensions (Расширения).

Автор:

Введение.

Эта статья рассказывает, что такое extensions (расширения) в терминах OpenGL 1.2.

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

Многие новые расширения стандартизируются, кроме того, в последующих версиях OpenGL некоторые из них будут уже входить в сам OpenGL, а не в виде его расширений.

Такие возможности, как мультитекстурирование, specular и компрессия текстур достаются в OpenGL 1.2 через механизм расширений.

Как же пользоваться расширениями?

Описание расширения обычно представляет собой обычный текстовый файл (Пример).

Можно самому добавлять каждый раз определение нового расширения в свой код. Однако почти все определения расширений можно получить из файла glext.h.

Сам файл glext.h можно взять из файла glext.zip, собранного из NVSDK, или сам glext.h с сайта SGI.

Не забудьте в вашем коде включить этот заголовочный файл:

#include "glext.h"

Определяем наличие расширения.

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

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

Функцией glGetString() с параметром GL_EXTENSIONS вы сможете получить список всех расширений, которые поддерживаются вашим акселератором. (Помните, что это стандартная функция OpenGL и вызывать её необходимо после инициализации OpenGL).

const GLubyte * pExtString = glGetString(GL_EXTENSIONS);

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

Использование дополнительных функций.

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

К примеру, одной из таких функций расширения "ARB мультитекстурирование" (GL_ARB_multitexture) является функция glActiveTextureARB().

Объявление этой функции в файле glext.h выглядит следующим образом:

extern void APIENTRY glActiveTextureARB (GLenum);

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

Тип указателя на функцию тоже определён в glext.h для каждой функции, например, для нашего случая:

typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture);

Для использования функции необходимо в вашем коде глобально объявить указатель на функцию:

PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;

И после инициализации OpenGL, присвоить ему указатель на существующую функцию, который можно получить специальной функцией wglGetProcAddress().

wglGetProcAddress() - функция не относится к чистому OpenGL, а относится к Windows-дополнению OpenGL (WGL). Она принимает в качестве параметра строку с именем искомой функции. Эта функция возвращает тип PROC, поэтому делаем приведение типов.

glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)

  wglGetProcAddress("glActiveTextureARB");

Если ваш указатель стал ненулевым, вы можете спокойно им пользоваться в своих нуждах в функциональном виде:

glActiveTextureARB(GL_TEXTURE1_ARB);

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

Пример:

// пример подготовки перед использованием некоторых
// функций расширения GL_ARB_multitexture

#include <windows.h>
#include <GL/gl.h>
#include "glext.h"

PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;

bool IsExtEnable(const char * pName)
{
  // Получить строку со списком доступных расширений
  const char * ch = (const char *)glGetString(GL_EXTENSIONS);

  size_t size = strlen(pName);
  while(ch)
  {
    if(!strncmp(ch,pName,size) && (*(ch+size)==0 || *(ch+size)==' '))
      return true;
    ch=strchr(ch,' ');
    if(ch)
      ch++;
  }

  return false;
}


bool Init_GL_ARB_multitexture()
{
  // Проверяем наличие расширения
  if(!IsExtEnable("GL_ARB_multitexture"))
    return false;
  
  // Получить адрес функции и присвоить его глобальному указателю
  glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)
    wglGetProcAddress("glActiveTextureARB");
  glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)
    wglGetProcAddress("glClientActiveTextureARB");
  glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)
    wglGetProcAddress("glMultiTexCoord2fARB");
  return true;
}

Полезные ссылки:
SGI.com: Список расширений.
OpenGL.org: Что такое расширения для OpenGL.

#расширения OpenGL, #OpenGL

15 февраля 2002

Комментарии [12]