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

Работая с текстурами, OpenGL обычно строит последовательность текстур, называемую mipmap. Это делается после того как изображение загружено и преобразовано. Функция gluBuild2DMipmaps на основе заданного параметром исходного изображения генерирует mipmap-последовательность. Каждая элемент этой последовательности имеет прогрессивно убывающую разрешающую способность. Все изображения mipmap-уровней имеет размеры, являющиеся степенью двойки. Если исходная текстура нулевого уровня имеет размеры , то текстура следующего уровня имеет размеры , и т.д. Текстура последнего уровня имеет размеры 1 ´ 1.

Технология под названием Mipmapping позволяет эффективно управлять качеством изображения. Если объект расположен близко к наблюдателю, то используется текстура базового (нулевого) уровня. При перемещении (удалении) объекта OpenGL выбирает текстуру одного из следующих уровней. The term mipmap was coined by Lance Williams, when he introduced the idea in his paper, "Pyramidal Parametrics" (SIGGRAPH 1983 Proceedings). Mip stands for the Latin multim im parvo, meaning "many things in a small place."

Второй параметр функции glTexImage2D, которую мы использовали в LoadTexture, позволяет выбрать нужный уровень mipmap. Функция gluBuild2DMipmaps пользуется услугами другой функции gluScaleImage, которая позволяет масштабировать исходное изображение (произвольного размера) так, чтобы получить текстуру нулевого уровня. Ее размеры должны быть степенью двойки. Функция gluScaleImage использует примерно такие выражения

int cx = int(pow (2., double (int(log (p->sizeX) / log(2.)))));

int cy = int(pow (2., double (int(log (p->sizeY) / log(2.)))));

Здесь p — это адрес структуры AUX_RGBImageRec, которую мы рассматривали выше. Вы можете использовать эти выражения для определения размеров базовой текстуры, зная исходные размеры изображения (p->sizeX, p->sizeY).

Диалог по открытию файла

Для того, чтобы имелась возможность выбора текстуры, неплохо бы добавить файловый диалог. Рассмотрим функцию FileDlg, которую можно использовать для выбора bitmap-файлов. В ее теле мы создаем файловый диалог, в контексте которого пользователь выбирает файл с изображением, и возвращаем строку с именем файла. Эта функция может быть вызвана внутри функции Init, а ее результат подан в LoadTexture, которая непосредственно читает файл.

Файловый диалог, создается с помощью функции API. Он не так прост, как хотелось бы, но он более управляем, чем при работе с MFC-классом CFileDialog, и ему можно придать множество сравнительно новых стилей. Так, стиль OFN_EXPLORER работает только в W2K. Из соображений общности сделано так, что функция FileDlg способна открыть диалог как для чтения, так и для записи файла, но мы используем ее только в первом режиме. Он задан параметром bRead = true. Чтобы код заработал надо в PreCompile.h вставить директиву подключения файла заголовков <commdlg.h>.

char* FileDlg (bool bRead) // bRead (true - Open, false - Save)

{

TCHAR *fn = new TCHAR [MAX_PATH];    // File Name to Return

fn[0] = 0;

TCHAR *szFilter =  // File Extension Filters

TEXT("BMP Files (*.bmp)\0*.bmp\0")

TEXT("DIB Files (*.dib)\0*.dib\0");

TCHAR szCurDir[MAX_PATH];

::GetCurrentDirectory (MAX_PATH-1, szCurDir);

TCHAR *szTitle = "Find a bitmap file";

OPENFILENAME ofn =

{

sizeof(OPENFILENAME),

gInfo.hWnd, gInfo.hInst,// Dialog Owner, App Instance 

szFilter, 0, 0, 1, // Filter, Custom Filter and Filter Index

fn, MAX_PATH, 0, 0,  // Recieve File Name, File Name Buffer

szCurDir, szTitle, // InitialDir, Dialog Title

OFN_EXPLORER | OFN_OVERWRITEPROMPT, // Flags

0, 0, "bmp", 0, 0, 0,// Offsets, Default extension, CustData, Hook, TemplateName

#if (_WIN32_WINNT >= 0x0500)

0, 0, 0 // Reserved, Reserved, FlagsEx

#endif

};

//===== Create and Open the dialog (returns 0, if failed)

BOOL b = bRead ? GetOpenFileName(&ofn) : GetSaveFileName(&ofn);

return b ? fn : 0;

}

В функции Init следует изменить всего лишь одну строку.