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

q  В-третьих, здесь понадобился сдвиг начального индекса, так как алгоритм не расчитывает выводить первые 32 символа. Вы знаете, что они расцениваются Windows как непечатаемые.

Создайте новый файл Text2D.cpp, скопируйте в него старый и введите изменения, как показано ниже.

UINT base[2];         // Base Display Lists For The Font Set

void BuildFont (int list)

{

HFONT font, old;

base[list] = glGenLists(96); // Storage identifier for 96 characters

int height = list==0 ? -28 : -16;

char* name = list==0 ? "Courier New" : "Times New Roman";

int weight = list==0 ? FW_BOLD : FW_MEDIUM;

font = CreateFont (height,0,0,0,weight,FALSE,FALSE,FALSE,ANSI_CHARSET,

OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,

FF_DONTCARE|DEFAULT_PITCH, name);       // Font Name

old = (HFONT)SelectObject (gInfo.hDC, font); // Selects The Font We Want

//====== Builds 96 Characters Starting At Character 32

wglUseFontBitmaps (gInfo.hDC, 32, 96, base[list]);

SelectObject (gInfo.hDC, old);   // Selects The Old Font

DeleteObject (font);        // Delete The Font

}

void glPrint (int list, const char *fmt, ...)

{

if (fmt == NULL)

return;

char text[256];

va_list p;

va_start (p, fmt);

vsprintf (text, fmt, p);

va_end (p);

glPushAttrib (GL_LIST_BIT);

glListBase (base[list] - 32);

glCallLists (int(strlen(text)), GL_UNSIGNED_BYTE, text); // Draws The Display List Text

glPopAttrib ();

}

bool Init ()

{

glClearColor (0, 0, 0, 0);

glShadeModel (GL_SMOOTH);

glEnable (GL_DEPTH_TEST);

glClearDepth (1);

glDepthFunc(GL_LEQUAL);

glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

BuildFont (0);     // Build The Courier Font

BuildFont (1);     // Build The Times New Roman Font

return true;

}

void Draw ()

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

glTranslatef (0, 0, -1);

static float xc, yc; // Two Counters Used To Move Text & Change Coloring

float              // Pulsing Colors Based On Counters

red = 0.5f * (1 + cos(xc)),    // Text Position Based On Counters

green = 0.5f * (1 + sin(yc)),

blue = 1 - red,

x = -0.5f + 0.05f * cos(xc),

y = 0.32f * sin(yc);

glColor3f (red, green, blue);

glRasterPos2f (x, y);       // Print GL Text To The Screen

glPrint (0, "Active Text with NeHe");

glRasterPos2f (x+0.75f, y);

glPrint (1, "(X:%5.2f, Y:%5.2f)", x, y);

x = -0.4f;  y = -0.39f;

glColor3f (0,0,blue); glRasterPos2f (x, y);

glPrint (1, "Blue: %4.2f", blue);

x += 0.29f;

glColor3f (0,green,0);  glRasterPos2f (x, y);

glPrint (1, "Green: %4.2f", green);

x += 0.31f;

glColor3f (red, 0, 0);  glRasterPos2f (x, y);

glPrint (1, "Red: %4.2f", red);

xc += 0.03f;  yc += 0.005f; // Increase The Counters

}

Обратите внимание на то, что для позиционирования текста (точнее, bitmap-изображения глифа) используется функция glRasterPos2f. Вообще-то в мировом координатном пространстве (именно в нем обычно создается изображение) используются 3 координаты (x, y, z), и масштабирующая (clip- координата) w, Функция glRasterPos4* задает все 4 координаты, функция glRasterPos3* задает координаты x, y, z, а координата w (по умолчанию) принимает значение 1, функция glRasterPos2* задает координаты x, y, а координаты z и w (по умолчанию) принимают значения 0 и 1. Таким образом, координаты, задаваемые функцией glRasterPos, обрабатываются так же, как и координаты, задаваемые функцией glVertex.

Отличие состоит в том, что растровая позиция используется функциями: glBitmap, glDrawPixels, and glCopyPixels. Первая (glBitmap) неявно используется при отображении текста. При использовании команды glRasterPos OpenGL отслеживает состояния нескольких флагов, таких как:

GL_CURRENT_RASTER_POSITION_VALID

GL_CURRENT_RASTER_COLOR

GL_CURRENT_RASTER_TEXTURE_COORDS

GL_CURRENT_RASTER_DISTANCE

Функцию Update оставьте без изменения, но добавьте код в функцию Deinitialize.

void Deinitialize ()

{

glDeleteLists (base[0], 96);   // Delete All 96 Characters

glDeleteLists (base[1], 96);

}