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

Функция glClipPlane с помощью коэффициентов уравнения плоскости задает полупространство отсечения. Объекты, попавшие в него не изображаются. Коэффициенты уравнения плоскости определяют вектор, на который затем воздействует инвертированная (обратная) матрица моделирования. Результат сохраняется и дальнейшие преобразования матрицы моделирования уже не влияют на вектор, определивший плоскость отсечения.

Вершина считается вне (out) полупространства отсечения, если скалярное произведение вектора, направленного из позиции глаза в вершину, и вектора, определяющего плоскость отсечения, отрицательно. В противном случае вершина считается внутри (in) полупространства отсечения. Следующий фрагмент включает режим и задает уравнение плоскости отсечения. Вставьте его перед началом фрагмента, который создает отражение мяча.

glEnable (GL_CLIP_PLANE0);  // Enable clip plane for removing artifacts (when balt crosses the floor)

double eq[] = {0, -1, 0, 0}; // Clip plane equation to use for the reflected objects

glClipPlane (GL_CLIP_PLANE0, eq);  // Set the equation

Следующую строку необходимо вставить после фрагмента, создающего отражение. После этого запустите приложение и убедитесь, что поведение мяча стало более реалистичным.

glDisable (GL_CLIP_PLANE0);

В качестве упражнения добейтесь того, чтобы мяч отскакивал от пола и прыгал по нему бесконечно. Если чувствуете силы, то реализуйте затухающие колебания вертикальной позиции мяча.

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

OpenGL использует двойную буферизацию, что делает невозможным вызов функций GDI для вывода текста в окно, где текущим является контекст передачи OpenGL. Для обхода препятствий такого рода было разработано семейство функций с префиксом wgl (Windows-GL). Две из них позволяют выводить двухмерные и трехмерные изображения текстовых символов.

Оба подхода имеют общие черты, главной из которых является необходимость предварительной подготовки списков изображений (знакомых вам display lists) для всех используемых символов. Очертания символов (outlines), или, проще, изображения, часто называют глифами — glyphs. Изображения (glyph outlines) зависят от выбранного шрифта, поэтому предварительно следует создать Windows фонт (переменную типа HFONT) и выбрать его в контекст устройства.

Для идентификации списков (и отведения памяти для них) используют функцию glGenLists, которая возвращает идентификатор первого из n запрошенных списков изображений. После этого для работы с двухмерным текстом следует воспользоваться услугами функции wglUseFontBitmaps, а для работы с трехмерным текстом надо вызвать функцию wglUseFontOutlines. Обе создают множество изображений, соответствующих заданному диапазону таблицы символов.

q  Первая функция создает плоские bitmap-изображения с учетом текущего фонта, то есть того, который в данный момент выбран в контекст устройства HDC.

q  Вторая — создает трехмерные изображения, также учитывая текущий фонт.

Далее работа со списками изображений идет точно так же, как и со всеми другими, то есть мы просто вызываем нужный список glCallList(i);. Вызывать эту функцию для каждого выводимого символа неудобно, поэтому лучше использовать другую — glCallLists. Она позволяет отобразить множество списков, последовательность, которых задается обычной строкой текста.

Для удобства работы с текстовыми строками (например, для преобразования числовых данных и их форматирования) Jeff Molofee разработал вспомогательную функцию glPrint, которая принимает переменное количество аргументов и работает по принципу легендарной printf.

Следующий пример демонстрирует рассмотренную технику для работы с текстом в трехмерном варианте. Функция wglUseFontOutlines последним параметром возвращает структуру типа GLYPHMETRICSFLOAT, которая содержит информацию о расположении и ориентации каждого глифа в так называемой ячейке символа (character cell) воображаемой сетки (notional grid) текста. Рельеф текста (extrusion), то есть его размер вдоль z-координаты, также управляется одним из параметров этой функции. Создайте новый файл Text3D.cpp, скопируйте в него старый и введите изменения, как показано ниже.