
- •Глава 1. Основы OpenGl 8
- •Введение
- •ОсновыOpenGl
- •Основные возможности
- •ИнтерфейсOpenGl
- •АрхитектураOpenGl
- •Синтаксис команд
- •Пример приложения
- •Контрольные вопросы:
- •Рисование геометрических объектов
- •Процесс обновления изображения
- •Вершины и примитивы
- •Положение вершины в пространстве
- •Цвет вершины
- •Нормаль
- •Операторные скобкиglBegin/glEnd
- •Дисплейные списки
- •Массивы вершин
- •Контрольные вопросы
- •Преобразования объектов
- •Работа с матрицами
- •Модельно-Видовые преобразования
- •Проекции
- •Область вывода
- •Контрольные вопросы
- •Материалы и освещение
- •Модель освещения
- •Спецификация материалов
- •Описание источников света
- •Создание эффекта тумана
- •Контрольные вопросы
- •Текстурирование
- •Подготовка текстуры
- •Наложение текстуры на объекты
- •Текстурные координаты
- •Контрольные вопросы
- •Операции с пикселями
- •Смешивание изображений. Прозрачность
- •Буфер-накопитель
- •Буфер маски
- •Управление растеризацией
- •Приемы работы сOpenGl
- •Устранение ступенчатости
- •Построение теней
- •Зеркальные отражения
- •Оптимизация программ
- •Организация приложения
- •Высокоуровневая оптимизация
- •Низкоуровневая оптимизация
- •Оптимизация вызовов OpenGl
- •Передача данных в OpenGl
- •Преобразования
- •Растеризация
- •Текстурирование
- •Очистка буферов
- •СтруктураGlut-приложения
- •Примитивы библиотекGlUиGlut
- •Настройка приложенийOpenGl
- •Демонстрационные программы
- •Пример 1: Простое glut-приложение
- •Пример 2: Модель освещения OpenGl
- •Пример 3: Текстурирование
- •Примеры практических заданий
- •Виртуальные часы
- •Интерактивный ландшафт
- •Литература
- •Предметный указатель
Зеркальные отражения
В этом разделе мы рассмотрим алгоритм построения отражений от плоских объектов. Такие отражения придают бóльшую достоверность построенному изображению и их относительно легко реализовать.
Алгоритм использует интуитивное представление полной сцены с зеркалом как составленной из двух: «настоящей» и «виртуальной» – находящейся за зеркалом. Следовательно, процесс рисования отражений состоит из двух частей: 1) визуализации обычной сцены и 2) построения и визуализации виртуальной. Для каждого объекта «настоящей» сцены строится его отраженный двойник, который наблюдатель и увидит в зеркале.
Рис. 9 Зеркальное
отражение
Для иллюстрации рассмотрим комнату с зеркалом на стене. Комната и объекты, находящиеся в ней, выглядят в зеркале так, как если бы зеркало было окном, а за ним была бы еще одна такая же комната с тем же объектами, но симметрично отраженными относительно плоскости, проведенной через поверхность зеркала.
Упрощенный вариант алгоритма создания плоского отражения состоит из следующих шагов:
Рисуем сцену как обычно, но без объектов-зеркал.
Используя буфер маски, ограничиваем дальнейший вывод проекцией зеркала на экран.
Визуализируем сцену, отраженную относительно плоскости зеркала. При этом буфер маски позволит ограничить вывод формой проекции объекта-зеркала.
Эта последовательность действий позволит получить убедительный эффект отражения.
Рассмотрим этапы более подробно:
Сначала необходимо нарисовать сцену как обычно. Не будем останавливаться на этом этапе подробно. Заметим только, что, очищая буферы OpenGLнепосредственно перед рисованием, нужно не забыть очистить буфер маски:
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT| GL_STENCIL_BUFFER_BIT);
Во время визуализации сцены лучше не рисовать объекты, которые затем станут зеркальными.
На втором этапе необходимо ограничить дальнейший вывод проекцией зеркального объекта на экран.
Для этого настраиваем буфер маски и рисуем зеркало
glEnable(GL_STENCIL_TEST);
/* условие всегда выполнено и значение в буфере будет равно 1*/
glStencilFunc(GL_ALWAYS, 1, 0);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
RenderMirrorObject();
В результате мы получили:
в буфере кадра – корректно нарисованная сцена, за исключением области зеркала;
в области зеркала (там, где мы хотим видеть отражение) значение буфера маски равно 1.
На третьем этапе нужно нарисовать сцену, отраженную относительно плоскости зеркального объекта.
Сначала настраиваем матрицу отражения. Матрица отражения должна зеркально отражать всю геометрию относительно плоскости, в которой лежит объект-зеркало. Ее можно получить, например, с помощью такой функции (попробуйте получить эту матрицу самостоятельно в качестве упражнения):
void
reflectionmatrix(GLfloat reflection_matrix[4][4], GLfloat plane_point[3], Glfloat plane_normal[3])
{
GLfloat* p;
GLfloat* v; float pv;
GLfloat* p = (Glfloat*)plane_point; Glfloat* v = (Glfloat*)plane_normal;
float pv = p[0]*v[0]+p[1]*v[1]+p[2]*v[2];
reflection_matrix[0][0] = 1 - 2 * v[0] * v[0];
reflection_matrix[1][0] = - 2 * v[0] * v[1];
reflection_matrix[2][0] = - 2 * v[0] * v[2];
reflection_matrix[3][0] = 2 * pv * v[0];
reflection_matrix[0][1] = - 2 * v[0] * v[1];
reflection_matrix[1][1] = 1- 2 * v[1] * v[1];
reflection_matrix[2][1] = - 2 * v[1] * v[2];
reflection_matrix[3][1] = 2 * pv * v[1];
reflection_matrix[0][2] = - 2 * v[0] * v[2];
reflection_matrix[1][2] = - 2 * v[1] * v[2];
reflection_matrix[2][2] = 1 - 2 * v[2] * v[2];
reflection_matrix[3][2] = 2 * pv * v[2];
reflection_matrix[0][3] = 0;
reflection_matrix[1][3] = 0;
reflection_matrix[2][3] = 0;
reflection_matrix[3][3] = 1;
}
и рисуем сцену еще раз (без зеркальных объектов)
glPushMatrix();
glMultMatrixf((float *)reflection_matrix);
RenderScene();
GlPopMatrix();
Наконец, отключаем маскирование
glDisable(GL_STENCIL_TEST);
После этого можно опционально еще раз вывести зеркальный объект, например, с альфа-смешением – для создания эффекта замутнения зеркала и т.д.
Существует несколько модификаций этого алгоритма, отличающиеся последовательностью действий, ограничениями на геометрию и т.д.