Главная » Статьи » Графика (OpenGL)

Работа с расширениями OpenGL и мультитекстурирование
Работа с расширениями OpenGL и мультитекстурирование

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

Итак, что же такое «расширение»?! В OpenGL под расширениями подразумевают ту или иную функцию(набор функций) которая расширяет стандартный функционал библиотеки OpenGL. Обычно под стандартным функционалом подразумевается OpenGL v1.1. Расширения создавались, в основном, производителями железа, которые добавляли поддержку тех или иных фичей в свое новоиспеченное железо, дабы обойти в конкурентной борьбе своих соперников. И причем каждое такое расширение поддерживалось видяхами только той канторы, которая его создала, а конкурирующая фирма выпускала свой продукт с поддержкой другого расширения, но со схожей или даже идентичной функциональностью. Такие телодвижения производителей железа вносили некую суматоху в ряды пользователей (программистов). Вот почему так много сторонников DirectX :) Но рано или поздно большинство таких расширений, после рассмотрения в комитете по стандартизации (ARB), становились частью стандарта и плавно перекочевывали в следующую версию OpenGL. На данный момент к релизу готовится уже третья версия библиотеки, и что она нам принесет можете прочитать здесь(http://www.khronos.org/developers/library/2007_08_siggraph/siggraph%202007%20bof-gl3%20overview.pdf).

Вернемся к нашим баранам.
За основу взяты исходники к статье «Инициализация OpenGL в Windows» и немного доработаны. Итак, первое что нам необходимо сделать, это добавит к нашему проекту два пустых файла: GLextensions.h и GLextensions.cpp. Как Вы, наверно, догадались они нужны нам для подключения наших расширений. Также нам понадобятся файлы glext.h (в нем содержатся прототипы расширений) и wglext.h (расширения OpenGL для windows). Еще не помешало бы обзавестись свеженькими библиотеками GLUT и GLAUX. Соответствующие файлы нужно положить в определенные папки Вашей среды разработки (в моем случае M$ VS2005 Pro), либо прописать к ним пути вручную в настройках проекта, но лучше 1й вариант.
Итак мы создали и подключили к нашему проекту два пустых файла, как описано выше. Открываем заголовочный (*.h) файл и пишем следующее:

#ifndef GL_EXTENSIONS_H
#define GL_EXTENSIONS_H

#include // Наша OpenGL библиотека
#include // Для подключения расширений
#include // Для подключения расширений Windows (wgl...)
#pragma warning (disable : 4786)


Первые две строчки служат для предотвращения повторного включения (#include) данного файла и объявления переменных и функций. Также каждый #ifndef должен заканчиваться оператором #endif его вы увидите в конце.
Также вместо всей этой конструкции вы можете просто написать #pragma once в начале заголовочного файла.

Далее следует прототип функции предназначенной для определения того, поддерживается наше расширение или нет. Описание ф-ции находится в файле GLextensions.cpp и будет рассмотрено позже.

//******* Ф-я проверки наличия расширения ********
bool GetGLExt(char *extName, unsigned char *string);


Теперь, собственно, идет прототипов наших функций необходимых для мультитекстурирования. Описание этих многих других ф-ций вы найдете в файле glext.h .

//>>>>>>>>>>> GL_ARB_multitexture <<<<<<<<<<<<<<<<<<<
extern PFNGLMULTITEXCOORD1FARBPROC glMultiTexCoord1fARB;
extern PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
extern PFNGLMULTITEXCOORD3FARBPROC glMultiTexCoord3fARB;
extern PFNGLMULTITEXCOORD4FARBPROC glMultiTexCoord4fARB;

extern PFNGLMULTITEXCOORD1FVARBPROC glMultiTexCoord1fvARB;
extern PFNGLMULTITEXCOORD2FVARBPROC glMultiTexCoord2fvARB;
extern PFNGLMULTITEXCOORD3FVARBPROC glMultiTexCoord3fvARB;
extern PFNGLMULTITEXCOORD4FVARBPROC glMultiTexCoord4fvARB;

extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;


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

void InitGL_multitexture(void);

Собственно то, о чем я говорил выше :)

#endif // GL_EXTENSIONS_H

Теперь рассмотрим GLextensions.cpp. В этом файле находятся функции обнаружения и инициализации расширений. Давайте все рассмотрим по порядку.

//******* Ф-я проверки наличия расширения ********
bool GetGLExt(char *extName, unsigned char *string)
{
// Тестим на предмет наличия расширения.....
if(strstr((const char*)string, extName))
{
return true; // Типа нашли... возвращаем ОК!
}
return false; // Типа не нашли.... возвращаем неудачу!!!
}


Как Вы уже заметили, эта ф-ция просто ищет одну строку в другой, подобно тому, как мы ищем слово или фразу в каком-либо текстовом документе.
Далее мы объявим наши функции-расширения:

//>>>>>>>>>>> GL_ARB_multitexture <<<<<<<<<<<<<<<<<<<
PFNGLMULTITEXCOORD1FARBPROC glMultiTexCoord1fARB = NULL;
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = NULL;
PFNGLMULTITEXCOORD3FARBPROC glMultiTexCoord3fARB = NULL;
PFNGLMULTITEXCOORD4FARBPROC glMultiTexCoord4fARB = NULL;

PFNGLMULTITEXCOORD1FVARBPROC glMultiTexCoord1fvARB = NULL;
PFNGLMULTITEXCOORD2FVARBPROC glMultiTexCoord2fvARB = NULL;
PFNGLMULTITEXCOORD3FVARBPROC glMultiTexCoord3fvARB = NULL;
PFNGLMULTITEXCOORD4FVARBPROC glMultiTexCoord4fvARB = NULL;

PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL;


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

void InitGL_multitexture(void)
{
glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC) wglGetProcAddress("glMultiTexCoord1fARB");
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB");
glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC) wglGetProcAddress("glMultiTexCoord3fARB");
glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC) wglGetProcAddress("glMultiTexCoord4fARB");

glMultiTexCoord1fvARB = (PFNGLMULTITEXCOORD1FVARBPROC) wglGetProcAddress("glMultiTexCoord1fvARB");
glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC) wglGetProcAddress("glMultiTexCoord2fvARB");
glMultiTexCoord3fvARB = (PFNGLMULTITEXCOORD3FVARBPROC) wglGetProcAddress("glMultiTexCoord3fvARB");
glMultiTexCoord4fvARB = (PFNGLMULTITEXCOORD4FVARBPROC) wglGetProcAddress("glMultiTexCoord4fvARB");

glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
glClientActiveTextureARB= (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB");
}


Итак что же мы видим? Функция wglGetProcAddress получает адрес необходимой нам функции и присваивает его нашей, определенной выше функции-расширению.
Откуда это она получает этот самый адрес, спросите Вы? Конечно же, из OpenGL32.dll (хотя название библиотеки может и отличаться в зависимости от производителя драйверов). Определение данной ф-ции находится в файле wingdi.h и выглядит следующим образом: WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR);
Но может быть такое, что этой ф-ции или заголовочного файла у вас просто не окажется. В этом случае ее нужно подключить подобно нашим расширениям, но используя ф-цию GetProcAddress (подробнее про эту ф-цию Вы сможете прочитать в MSDN).

Ну вот мы практически подошли к завершению. Все, что нам осталось сделать это применить на практике наши новоиспеченные расширения. Для этого мы загрузим две текстуры и наложим их на три квадрата: 1й – одна текстура, 2й – вторая текстура, 3й – обе текстуры.
Загружать текстуры мы будем при помощи ф-ции auxDIBImageLoad из библиотеки GLAUX, но можно обойтись и без нее путем создания собственной ф-ции загрузки .bmp файлов (о том как это сделать вы можете прочесть в «ЭТОЙ» статье). Код загрузки я приводить не буду, приведу лишь код ОТМУЛЬТИТЕКСТУРЕННОГО квадрата. Остальное Вы сможете сами изучить покопавшись в исходниках прикрепленных в конце статьи.

void renderTex01()
{
glPushMatrix();
// Активизируем первый текстурный модуль,
// но можно этого и не делать т.к он уже активен по-умолчанию.
glActiveTextureARB(GL_TEXTURE0_ARB);
// Включаем текстурирование для 1-го текстурного модуля
glEnable(GL_TEXTURE_2D);
// Привязываем первую текстуру к 1-му текстурному модулю
glBindTexture(GL_TEXTURE_2D, tex0);

// Активизируем второй текстурный модуль
glActiveTextureARB(GL_TEXTURE1_ARB);
// Включаем текстурирование для 2-го текстурного модуля
glEnable(GL_TEXTURE_2D);
// Привязываем вторую текстуру к 2-му текстурному модулю
glBindTexture(GL_TEXTURE_2D, tex1);

// рисуем квадрат
glTranslatef (0.7f, -0.5f, -3.0f);
glBegin(GL_QUADS);
// задаем текстурные координаты для первого текстурного модуля...
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
// и для второго.
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
glVertex2f(0.0f, 0.0f); // рисуем первую вершину...
// тоже самое для оставшихся 3х вершин...
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
glVertex2f(1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();

// деактивизируем текстурирование для 2-го текстурного модуля
glDisable(GL_TEXTURE_2D);
// Активизируем первый текстурный модуль
glActiveTextureARB(GL_TEXTURE0_ARB);
// деактивизируем текстурирование для 1-го текстурного модуля
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}


Ну вот собственно и все! Осталось только удалить созданные текстуры вот так:

void ShutdownTextures()
{
// Подчищаем за собой
glDeleteTextures(1, &tex0);
glDeleteTextures(1, &tex1);
}


Вызвать данную ф-цию при выходе из программы и все.

Надеюсь, данный материал был Вам полезен. Что не понятно спрашивайте…

Исходник тут(http://viledogsoftware.3dn.ru/downloads/articles/Multytexture.zip)!


Виталий Демиденко © 2007


Категория: Графика (OpenGL) | Добавил: viledogsoftware (04.10.2007)
Просмотров: 6471 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]