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

Запустите приложение и убедитесь в том, что оно работает в режиме выполнения (Ctrl+F5). Замечу, что в моей системе функция wglUseFontOutlines по неизвестной мне причине отказывается работать (зависает) в режиме отладки (F5).

Текстурированный текст

Текст, как и любой другой объект сцены OpenGL, можно текстурировать, управляя текстурными координатами, фильтрацией, а кроме того и возможностями генерировать текстуру. Любопытно взглянуть на трехмерные изображения специальных символов, которые имеются в таких экзотических фонтах, как Wingdings. Следующий пример, позволяет это сделать. Создайте новый файл Text3DTex.cpp, скопируйте в него старый и введите изменения, как показано ниже. Набор глобальных переменных будет таким.

TCHAR *pFile = 0; // Bitmap file name

UINT texture;  // One Texture Map

UINT c;      // Character code counter

bool up, dn; // Upm Down Pressed?

Кроме возможности изменить текстуру, пользователь сможет перемещаться по спискам  изображений с помощью клавиш VK_UP и VK_DOWN. Теперь добавьте функцию FileDlg, которую мы использовали ранее. Затем вставьте код функции LoadTexture, она должна быть такой же простой, как и в файле Wave.cpp. Далее приведены изменения, которые в основном касаются работы с текстом и анимации изображения.

void BuildFont ()

{

GLYPHMETRICSFLOAT gmf[256];

HFONT font = CreateFont(-12, 0,0,0, FW_BOLD,FALSE,FALSE,FALSE,SYMBOL_CHARSET,

OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,

FF_DONTCARE | DEFAULT_PITCH, "Wingdings");   // Font Name

SelectObject (gInfo.hDC, font);

wglUseFontOutlines (gInfo.hDC,0,255,1,0.1f,0.2f, WGL_FONT_POLYGONS, gmf);

}

void glPrint (char *text)    // Custom GL "Print" Routine

{

if (!text)

return;

glPushAttrib (GL_LIST_BIT); // Pushes The Display List Bits

glListBase (1);

glCallLists (int(strlen(text)), GL_UNSIGNED_BYTE, text);

glPopAttrib ();         // Pops The Display List Bits

}

bool Init ()

{

if (pFile == 0)

pFile = gInfo.bFull ?

strcpy (new TCHAR[128],"Data/Lights.bmp") : FileDlg (true);

if (!LoadTexture (pFile))

return false;

BuildFont();

glClearColor (0, 0, 0, 0.5f);

glShadeModel (GL_SMOOTH);

glClearDepth (1);

glEnable (GL_DEPTH_TEST);

glDepthFunc (GL_LEQUAL);

glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

glEnable (GL_LIGHT0);

glEnable (GL_LIGHTING);

glEnable(GL_TEXTURE_2D);

glEnable (GL_TEXTURE_GEN_S);

glEnable (GL_TEXTURE_GEN_T);

glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

return true;

}

void Draw ()

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

static float a;

float y = -0.3f + 0.2f * sin (a / 30);

glTranslatef (-0.55f, y, -2.5f);

glRotatef (180 * (y + 0.3f), 0, 1, 0);

if (-0.302f < y && y < -0.298f)

c = (c+1) % 224;

char ch = char(31 + c);

char s[] = { ch, 0 };

glPrint (s);

a += 1;

}

void Update (DWORD ms)

{

if (gInfo.keys[VK_ESCAPE])

{

gInfo.bQuit = true;

PostMessage (gInfo.hWnd, WM_QUIT, 0, 0);

}

if (gInfo.keys[VK_F1])

PostMessage (gInfo.hWnd, WM_TOGGLEFULLSCREEN, 0, 0);

if (gInfo.keys[VK_UP] && !up)

{

up = true;

c = (c+1) % 224;

}

if (!gInfo.keys[VK_UP])

up = false;

if (gInfo.keys[VK_DOWN] && !dn)

{

dn = true;

if (c > 0)

c = (c-1) % 224;

else

c = 223;

}

if (!gInfo.keys[VK_DOWN])

dn = false;

}

Код символа изменяется в функции Draw после того как прошел весь цикл проективных трансформаций текущего изображения. Смотрите строку кода:

c = (c+1) % 224;

Ограничение вызвано особенностями используемого фонта.

Изображение двухмерного текста

Следующий пример иллюстрирует возможности изображения двухмерного текста. Мы приводим его после трехмерного, так как здесь использован более сложный сценарий использования массива списков (глифов).

q  Во-первых, алгоритм использует 2 массива для создания двух множеств глифов, соответствующих двум фонтам,

q  Во-вторых, здесь создаются bitmap-изображения не всех символов, а только 96 из них.