Каркас Windows-приложения. Особенности нового каркаса. Перемещение в пространстве (с текстурированными стенами), страница 9

pFile = gInfo.bFull ? strcat (pFile, "/Data/Crate.bmp") : FileDlg (true);

При запуске приложения в полноэкранном режиме диалог не в состоянии нормально работать, поэтому в этом режиме мы по умолчанию берем файл Crate.bmp, однако в оконном режиме имеется возможность выбрать другой файл с текстурой (только один раз при запуске, т.к. у нас нет меню).

Далеко не все bitmap-файлы могут быть правильно интерпретированы функцией auxDIBImageLoad, поэтому выбирайте проверенные файлы, которые размещены в папке Data. Однако, вы можете экспериментировать и пытаться загружать другие растровые изображения.

Фильтрация текстур

Двухмерные текстуры — это прямоугольники. При отображении на непрямоугольные и даже прямоугольные поверхности индивидуальные texel'ы редко совпадают с индивидуальными pixel'ами изображения. В зависимости от моделирующих и проективных преобразований, а также от типа текстурных отображений один pixel может соответствовать либо доле texel'а (magnification), либо множеству texel'ов (minification).

В связи с этой неопределенностью OpenGL дает нам возможность указать способ фильтрации, то есть вычисления соответствий между pixel'ами и texel'ами. Говорят также об интерполяции (усреднении) текстуры. Выбирая различные способы фильтрации, мы либо проигрываем в скорости, но выигрываем в качестве, либо наоборот. Способы фильтрации независимо задаются для процедур растягивания (magnification) текстуры и ее сжатия (minification). Обычно вы и не знаете, какая процедура будет использована. Функции типа glTexParameter* позволяют выбрать способы фильтрации. Первый аргумент задает размерность GL_TEXTURE_2D или GL_TEXTURE_1D. Второй — тип процедуры: magnification или minification. Третий — метод фильтрации (GL_NEAREST, GL_LINEAR, и другие, экзотические типа GL_LINEAR_MIPMAP_NEAREST — cм. Help).

Если выбрать GL_NEAREST, то при сжатии или расширении используется texel с ближайшей к центру координатой. Иногда это приводит к увеличению ступенчатости (aliasing artifacts). При выборе линейного метода фильтрации (GL_LINEAR), используется взвешенное линейное усреднение. Оно берется по массиву текселов размерностью 2 × 2, которые являются ближайшими к центру. Этот метод дает более гладкое (smoother) изображение.

Если близка граница текстуры, то в этом подходе возможен выход за ее пределы. Результат усреднения в этом случае зависит от установки wrap-параметра (GL_REPEAT или GL_CLAMP), который определяет поведение текстуры в случаях, когда она отображается на поверхность меньшую, чем bitmap-изображение. Установка GL_REPEAT повторяет текстуру, а GL_CLAMP обрезает ее.

Следующий пример демонстрирует различные способы фильтрации, а также использование освещения и управления вращением с помощью клавиш. Введите новые глобальные переменные и внесите изменения в функции: LoadTexture, Init, Draw и Update.

bool light, lp, fp; // Lighting ON/OFF, L Pressed? F Pressed?

float

angleX, angleY,  // X, Y Rotation angles

xspeed, yspeed,  // X, Y Rotation Speeds

z = -5,     // Depth Into The Screen

ambient[]=  { 0.5f, 0.5f, 0.5f, 1 },

diffuse[]=  { 1, 1, 1, 1 },

position[]= { 0, 0, 2, 1};

UINT filter,      // Which Filter To Use

texture[3]; // Storage For 3 Textures

TCHAR curDir[MAX_PATH], *pFile = 0; // Current dir and bitmap file name

bool LoadTexture (TCHAR *fn, UINT *pTexture)

{

if (fn == 0)

return false;

AUX_RGBImageRec *p = auxDIBImageLoad (fn);

if (p == 0)

return false;

glGenTextures (3, pTexture);   // Create The Texture

glBindTexture (GL_TEXTURE_2D, pTexture[0]); // Create Nearest Filtered Texture

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D (GL_TEXTURE_2D, 0, 3, p->sizeX, p->sizeY, 0,

GL_RGB, GL_UNSIGNED_BYTE, p->data);

glBindTexture (GL_TEXTURE_2D, pTexture[1]); // Create Linear Filtered Texture

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);