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

glPushMatrix();

glTranslatef (0, -0.6f, z); // Zoom And Raise Camera Above The Floor (0.6 Units)

DrawFloor();

glEnable (GL_LIGHTING);

glTranslatef (0, height, 0); // Position The Ball At Proper Height

glRotatef (angleX, 1, 0, 0);

glRotatef (angleY, 0, 1, 0);

DrawBall();

glDisable (GL_LIGHTING);    // Since we use texture, disable lighting

angleX += xv; angleY += yv;

glPopMatrix();

}

Функцию Update подправьте так, чтобы она не имела лишних деталей и позволяла управлять вращением и позицией мяча (клавиши A и Q).

if (gInfo.keys[VK_PRIOR])

z +=0.05f;

if (gInfo.keys[VK_NEXT])

z -=0.05f;

if (gInfo.keys[VK_DOWN])

xv += 0.01f;

if (gInfo.keys[VK_UP])

xv -= 0.01f;

if (gInfo.keys[VK_RIGHT])

yv += 0.01f;

if (gInfo.keys[VK_LEFT])

yv -= 0.01f;

if (gInfo.keys['Q'])

height +=0.03f;

if (gInfo.keys['A'])

height -=0.03f;

Так как был использован массив строк для трех текстурных файлов, то в функцию Deinitialize вставьте код освобождения памяти. Запустите и исследуйте влияние установки GL_SPHERE_MAP. Она действует только на вторую текстуру (Lights.bmp). Почему?

Использование трафаретов (Stenciling)

Трафареты, как и z-буферизация, включают или выключают режим тестирования каждого пиксела с учетом текущих установок. Обычно они используются в многопроходовых алгоритмах для создания специальных эффектов. Мы рассмотрим, как использовать трафарет для создания эффекта отражения мяча в полированной поверхности пола. Таким образом, вы просто добавите функциональность в предыдущее приложение.

Кроме буфера цвета и буфера глубины, которыми мы давно и успешно пользуемся, OpenGL имеет буфер трафарета (stencil buffer). В этот буфер записываются целые величины типа UINT. Образы, записанные в этот буфер, образуют маску, которая используется для того, чтобы предпринять некоторые действия типа пропускать или не пропускать пиксел в буфер кадра. Маска трафарета используется на последнем этапе работы конвейера OpenGL — работы с фрагментами.

Вспомните, перед тем как пиксел (составная часть фрагмента) попадает в буфер кадра, он проходит серию тестов, каждый из которых может быть включен или отменен. Например, каждый раз при создании трехмерных изображений мы даем установку glEnable(GL_DEPTH_TEST), которая включает тест глубины. Более того, мы задаем функцию, используемую в процедуре тестирования, обычно это: glDepthFunc(GL_LEQUAL). Она означает, что тестируемый пиксел не попадет в буфер кадра, если его координата z меньше или равна координате z того пиксела, который уже присутствует в буфере кадра и имеет те же экранные координаты. Аналогичная процедура используется при работе с трафаретами. Трафаретный тест отбрасывает те пикселы, которые не прошли тестирование — сравнение текущей величины (reference value) с величиной, записанной в буфере трафарета (stencil buffer). С помощью команды glStencilFunc мы определяем как проводить тест. Рассмотрим ее сигнатуру.

glStencilFunc (GLenum func, int ref, UINT mask);

Она имеет три параметра: функцию, которая определяет результат теста, величину, которая подвергается тестированию (reference value) и значение маски. Первый параметр имеет тип перечисления и может принимать одно из 8 значений:

GL_NEVER

Тест никогда не проходит

GL_EQUAL

Тест проходит, if (ref & mask == stencil & mask)

GL_NOTEQUAL

Тест проходит, if (ref & mask != stencil & mask)

GL_LESS

Далее все ясно . . .

GL_LEQUAL

GL_GREATER

GL_GEQUAL

GL_ALWAYS

Тест проходит всегда

Тест может пройти или не пройти. Его результат используется конвейером OpenGL для определения последующих действий. Команда glStencilOp используется для установки тех действий, которые следует предпринять после завершения трафаретного теста. Ее сигнатура выглядит так.

void glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);

q  fail — Перечисление, определяющее действие в случае, если тест провалился.