Текстури - мультитекстурирование, уроки і приклади програмування

Пошук фотографій по гео-локації:

* Що таке мультітекстурінг? *
Мультітекстурінг - це 2 і більше шару текстур, накладених один на одного.
Він використовується для створення світлових карт, тіней, і інших графічних технік.
В принципі, ви можете досягти тих же ефектів і без мультітекстурінга, але
вам доведеться перемальовувати одну і ту ж геометрію більш ніж один раз.
Наприклад, ви можете отрисовать стіну, а потім трохи попереду неї намалювати
світлову карту.


Мультітекстурінг був доступний в OpenGL не відразу.
API для мультітекстурінга називається "розширення" (extension).
Щоб включити розширення, ви можете або включити його в ваш проект, або включити
додається "glext.h", що містить всі існуючі розширення. Якщо ви помітили, їх
там тонни. Розширення - це такі штуки, які хоча і знаходяться
поза стандартного API, але додані в його можливості. для мультитекстурирования
вам потрібна остання версія OpenGL. Щоб дізнатися, чи можете ви працювати з
мультитекстурирования, спробуйте використовувати функцію glGetString (GL_EXTENSIONS).
Вона повертає (char *), який містить всі доступні вам розширення.

Код цього уроку узятий з уроку "Завантаження текстур".

Зміни торкнуться лише файлу main.cpp:


// На початку додаємо ще один Хідер:
#include "glext.h"


// Потім збільшуємо кількість завантажених текстур до чотирьох:
TextureImage textures # 91; 4 # 93; ;
// ^


/ *
Ця програма пропонує 2 приклади мультітекстурінга.
Перший - проста карта світу, а другий - статичний бекграунд з повзучої
по ньому картою хмар.
Щоб використовувати розширення, нам потрібно завантажити функції з OpenGL DLL.
Давайте поглянемо на код.

Існують функції, що управляють мультитекстурирования. Вони будуть завантажені
викликом wglGetProcAddress (). Ви повинні включити "glext.h", або дефайніть ці
типи в вашому коді. Якщо ви цього не зробите, у вас не буде прототипів для
функцій мультітекстурінга.
ARB == Architecture Review Board. Подробиці ви можете знайти в інтернеті, але
основне, що вони роблять - допомагають обьявлять стандарти OpenGL.

Наступні покажчики на функції дозволяють нам вказати, які текстури з якими
ми хочемо зв'язати. Сам процес ви побачите в RenderScene ().
* /

// Тепер переходимо до функції ініціалізації (Init ()):
void Init # 40; HWND hWnd # 41;
# 123;
g_hWnd = hWnd;
GetClientRect # 40; g_hWnd. g_rRect # 41; ;
InitializeOpenGL # 40; g_rRect. right. g_rRect. bottom # 41; ;

// ініціалізувавши клас
Texture = new CTexture # 40; # 41; ;

// Нам потрібні оголошення і готові до вживання функції мультітекстурінга,
// давайте переконаємося, що на машині присутній потрібна версія OpenGL.
// Якщо функція розширення не знайдено, покажчики функцій дорівнюватимуть NULL
if # 40 ;. glActiveTextureARB ||. glMultiTexCoord2fARB # 41;
# 123;
// Print a error message and quit.
MessageBox # 40; NULL. "Your version of OpenGL does not support multitexturing". "Error". MB_OK # 41; ;
PostQuitMessage # 40; 0 # 41; ;
# 125;

// У нас буде 4 текстури. Використовуємо клас CTexture для їх завантаження.
Texture -> LoadTexture # 40; IL_BMP. "Bitmap.bmp". textures # 91; 0 # 93; # 41; ;
Texture -> LoadTexture # 40; IL_BMP. "LightMap.bmp". textures # 91; 1 # 93; # 41; ;
Texture -> LoadTexture # 40; IL_BMP. "Cove.bmp". textures # 91; 2 # 93; # 41; ;
Texture -> LoadTexture # 40; IL_BMP. "Fog.bmp". textures # 91; 3 # 93; # 41; ;
# 125;


// Ну і нарешті приступимо до отрисовке.
// Функція RenderScene ():

void RenderScene # 40; # 41;
# 123;
glClear # 40; GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT # 41; ;
glLoadIdentity # 40; # 41; ;

// Перемістимося тому, щоб бачити наш квадрат:
glTranslatef # 40; 0. 0, - 7 # 41; ;

// Встановимо активним ID першої текстури, потім забіндити текстуру цегли до цього ID.
// Перед тим, як биндить текстуру, ви ПОВИННІ викликати: glEnable (GL_TEXTURE_2D);
glActiveTextureARB # 40; GL_TEXTURE0_ARB # 41; ;
glEnable # 40; GL_TEXTURE_2D # 41; ;
glBindTexture # 40; GL_TEXTURE_2D. textures # 91; 0 # 93 ;. texID # 41; ;

// Зробимо id другий текстури активним, і забіндити нашу карту світу на цей ID.
glActiveTextureARB # 40; GL_TEXTURE1_ARB # 41; ;
glEnable # 40; GL_TEXTURE_2D # 41; ;
glBindTexture # 40; GL_TEXTURE_2D. textures # 91; 1 # 93 ;. texID # 41; ;

// Так як ми хочемо переміщати текстуровані квадрати в різні координати,
// ми викликаємо нову матрицю, так що зміни не торкнуться інших квадратів.
glPushMatrix # 40; # 41; ;
// У поточній матриці квадрат переміститься в ліву частину екрану
glTranslatef # 40; - 2. 0. 0 # 41; ;

// Відобразимо мультітекстурірованний квадрат в лівій частині екрана
glBegin # 40; GL_QUADS # 41; ;
// Тепер, замість glTextCoord2f () скористаємося ф-їй glMultiTextCoord2fARB (),
// щоб вказати текстурні координати для кожної текстури. Це дозволить
// нам пересунути нашу текстуру в абсолютно інші координати.
// Чудовий приклад цього - тіні. glMultiTexCoord2fARB () приймає
// ID текстури, який ми вказуємо, з потрібними текстурними координатами.
// Зараз ми використовуємо однакові координати для кожної текстури.

// Лівий верхній кут
glMultiTexCoord2fARB # 40; GL_TEXTURE0_ARB. 0.0f. 1.0f # 41; ;
glMultiTexCoord2fARB # 40; GL_TEXTURE1_ARB. 0.0f. 1.0f # 41; ;
glVertex3f # 40; - 1. 1. 0 # 41; ;

// Нижній лівий кут
glMultiTexCoord2fARB # 40; GL_TEXTURE0_ARB. 0.0f. 0.0f # 41; ;
glMultiTexCoord2fARB # 40; GL_TEXTURE1_ARB. 0.0f. 0.0f # 41; ;
glVertex3f # 40; - 1. - 1. 0 # 41; ;

// Нижній правий кут
glMultiTexCoord2fARB # 40; GL_TEXTURE0_ARB. 1.0f. 0.0f # 41; ;
glMultiTexCoord2fARB # 40; GL_TEXTURE1_ARB. 1.0f. 0.0f # 41; ;
glVertex3f # 40; 1. - 1. 0 # 41; ;

// Верхній правий вугол
glMultiTexCoord2fARB # 40; GL_TEXTURE0_ARB. 1.0f. 1.0f # 41; ;
glMultiTexCoord2fARB # 40; GL_TEXTURE1_ARB. 1.0f. 1.0f # 41; ;
glVertex3f # 40; 1. 1. 0 # 41; ;
glEnd # 40; # 41; ;
// І виходимо з матриці, щоб переміщення не торкнулися наступний квадрат.
glPopMatrix # 40; # 41; ;

// Тепер напишемо другий приклад мультітекстурінга в правій частині екрана.
// Ми можемо переназначать нові текстури до використаним GL_TEXTURE * _ARB.
// Ми могли б використовувати GL_TEXTURE2_ARB і GL_TEXTURE3_ARB, але це не потрібно.

// Активуємо перший ID і забіндити на нього бекграунд:
glActiveTextureARB # 40; GL_TEXTURE0_ARB # 41; ;
glBindTexture # 40; GL_TEXTURE_2D. textures # 91; 2 # 93 ;. texID # 41; ;

// На другий ID забіндити текстуру диму.
glActiveTextureARB # 40; GL_TEXTURE1_ARB # 41; ;
glBindTexture # 40; GL_TEXTURE_2D. textures # 91; 3 # 93 ;. texID # 41; ;

// Щоб зробити дим більш реалістичним, змусимо його плисти над фоном.
// Для цього створимо static float, що містить лічильник переміщення.
// Так як наша текстура - GL_WRAP, буде ефект безперервності.

// Створимо лічильник
static float wrap = 0;

// Зрушимо квадрат направо
glTranslatef # 40; 2. 0. 0 # 41; ;

// І починаємо малювати
glBegin # 40; GL_QUADS # 41; ;
// Малюємо ліву верхню вершину, віднімаючи з координати текстури лічильник,
// щоб добится ефекту скролінгу.
glMultiTexCoord2fARB # 40; GL_TEXTURE0_ARB. 0.0f. 1.0f # 41; ;
glMultiTexCoord2fARB # 40; GL_TEXTURE1_ARB. 0.0f - wrap. 1.0f # 41; ;
glVertex3f # 40; - 1. 1. 0 # 41; ;

// Нижня ліва вершина
glMultiTexCoord2fARB # 40; GL_TEXTURE0_ARB. 0.0f. 0.0f # 41; ;
glMultiTexCoord2fARB # 40; GL_TEXTURE1_ARB. 0.0f - wrap. 0.0f # 41; ;
glVertex3f # 40; - 1. - 1. 0 # 41; ;

// Нижня права вершина
glMultiTexCoord2fARB # 40; GL_TEXTURE0_ARB. 1.0f. 0.0f # 41; ;
glMultiTexCoord2fARB # 40; GL_TEXTURE1_ARB. 1.0f - wrap. 0.0f # 41; ;
glVertex3f # 40; 1. - 1. 0 # 41; ;

// верхня права вершина
glMultiTexCoord2fARB # 40; GL_TEXTURE0_ARB. 1.0f. 1.0f # 41; ;
glMultiTexCoord2fARB # 40; GL_TEXTURE1_ARB. 1.0f - wrap. 1.0f # 41; ;
glVertex3f # 40; 1. 1. 0 # 41; ;
glEnd # 40; # 41; ;

// Збільшимо лічильник переміщення
wrap + = 0.0015f;


SwapBuffers # 40; g_hDC # 41; ;
# 125;


От і все! Б'юся об заклад, ви думали, що доведеться попрацювати більше, чи не так?
У майбутньому ви зможете затінювати будь-які поверхні, робити яскравіше бекграунд, і ще
багато всяких смакоти. Вам знадобиться розширення EXT_texture_env_combine.
Більше інформації про нього буде в майбутніх уроках. Це розширення дозволить вам
здійснювати бамп-маппінг дуже і дуже швидко.

PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = NULL;
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;

glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress ( "glActiveTextureARB");
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress ( "glMultiTexCoord2fARB");

3) Коли все готово до Рендер, нам потрібно прив'язати нашу текстуру до мультітекстурному ID.
Цей ID ми можемо потім використовувати для вказівки, який саме мультітекстуре призначаємо
координати.

glActiveTextureARB (GL_TEXTURE0_ARB);
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, textures [0] .texID);

4) Тепер, щоб задати текстурні координати для нашої текстури, ми просто
передаємо мультітекстурний ID, який нам потрібен.

glMultiTexCoord2fARB (GL_TEXTURE0_ARB, 0.0f, 1.0f);
glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 0.0f - wrap, 1.0f);
glVertex3f (-1, 1, 0);

От і все! Насолоджуйтесь;)

Схожі статті