Главная » Статьи » Графика (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 | |
Просмотров: 6471 | Рейтинг: 0.0/0 |
Всего комментариев: 0 | |