Робота з розширеннями opengl і мультитекстурирование - графіка (opengl) - каталог статей - viledog

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

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

У даній статті мова піде про те, як працювати з розширеннями графічної бібліотеки OpenGL.
Я постараюся, як можна більш детально розповісти про те, як перевірити наявність того чи іншого розширення і як його підключити до вашій програмі для подальшого використання. Все це я продемонструю на прикладі найбільш поширеного розширення - GL_ARB_multitexture відповідає за мультитекстурирование, тобто за можливість накладати на об'єкт кілька текстур за один прохід.

#ifndef GL_EXTENSIONS_H
#define GL_EXTENSIONS_H

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

Далі слід прототип функції призначеної для визначення того, підтримується наше розширення чи ні. Опис ф-ції знаходиться в файлі 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 і буде розглянуто нижче.

Власне те, про що я говорив вище :)

Тепер розглянемо 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");
>

Ну ось ми практично підійшли до завершення. Все, що нам залишилося зробити це застосувати на практиці наші новоспечені розширення. Для цього ми завантажимо дві текстури і накладемо їх на три квадрата: 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);
>

Викликати цю ф-цію при виході з програми і все.

Сподіваюся, даний матеріал був Вам корисний. Що не зрозуміло запитуйте ...