ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 09.06.2020
Просмотров: 1689
Скачиваний: 4
121
3.
Приветствуется
выполнение
задания
в
виде
демонстрации
,
т
.
е
. c
возможностью
работы
в
полноэкранном
режиме
и
немедленным
выходом
по
клавише
Escape.
Можно
написать
программу
как
Screen Saver.
4.
Постарайтесь
использовать
максимум
возможностей
OpenGL.
Блики
,
отражения
,
спецэффекты
-
за
все
это
обязательно
даются
дополнительные
баллы
.
5.
Проявите
вкус
-
сделайте
так
,
чтобы
нравилось
прежде
всего
Вам
.
Но
не
увлекайтесь
-
оставайтесь
реалистами
.
Максимальная
оценка
- 20
баллов
.
За
минимальную
реализацию
требований
ставиться
10
баллов
.
Еще
до
10
баллов
можно
получить
за
использование
в
работе
возможностей
OpenGL (
текстур
,
прозрачности
,
environment mapping
и
пр
.),
оригинальных
и
продвинутых
алгоритмов
,
количество
настроек
,
а
также
за
эстетичность
и
красоту
сцены
.
E.3.
Интерактивный
ландшафт
Целью
данного
задания
является
генерация
и
вывод
с
помощью
OpenGL
поверхности
ландшафта
,
а
также
обеспечение
интерактивного
передвижения
над
ней
.
Обязательная
часть
задания
Для
выполнения
обязательной
части
задания
необходимы
:
1.
генерация
трехмерного
ландшафта
2.
раскраска
для
придания
реалистичности
3.
эффект
тумана
4.
возможность
"
полета
"
над
ландшафтом
(
управление
)
Более
подробное
описание
:
Генерация
ландшафта
Один
из
вариантов
задания
поверхности
ландшафта
-
задание
так
называемого
"
поля
высот
" -
функции
вида
z=f(x, y),
которая
сопоставляет
каждой
точке
(x, y)
плоскости
OXY
число
z -
высоту
поверхности
ландшафта
в
этой
точке
.
Один
из
способов
задания
функции
f -
табличный
,
когда
функция
f
представляется
матрицей
T
размера
M x N,
и
для
целых
x
и
y f=T[x, y],
а
для
дробных
x
и
y
из
диапазонов
[0..M-1]
и
[0..N-1]
соответственно
f
вычисляется
интерполяцией
значений
f
в
ближайших
точках
плоскости
OXY
с
122
целыми
x
и
y,
а
вне
указанных
диапазонов
x
и
y
значение
функции
считается
неопределенным
.
Допустим
,
в
памяти
лежит
двухмерный
массив
со
значениями
матрицы
T.
Пусть
N=M.
Если
теперь
для
каждого
квадрата
[x, x+1] x [y,
y+1],
где
x
и
y
принадлежат
диапазону
[0..N-2]
построить
две
грани
: ((x,
y, T[x, y]), (x+1, y, T[x+1, y]), (x+1, y+1, T[x+1, y+1]))
и
((x, y, T[x, y]),
(x+1, y+1, T[x+1, y+1]), (x, y+1, T[x, y+1])),
то
мы
получим
трехмерную
модель
поверхности
,
описываемой
матрицей
Т
.
Но
каким
образом
задать
массив
значений
матрицы
Т
?
Один
из
способов
-
сгенерировать
псевдослучайную
поверхность
с
помощью
фрактального
разбиения
.
Для
этого
положим
размерность
матрицы
T
равной
2^N+1,
где
N -
натуральное
число
.
Зададим
некоторые
произвольные
(
псевдослучайные
)
значения
для
четырех
угловых
элементов
матрицы
Т
.
Теперь
для
каждого
из
четырех
ребер
матрицы
Т
(
это
столбцы
или
строки
элементов
,
соединяющие
угловые
элементы
)
вычислим
значение
элемента
матрицы
Т
,
соответствующего
середине
ребра
.
Для
этого
возьмем
среднее
арифметическое
значений
элементов
матрицы
Т
в
вершинах
ребра
и
прибавим
к
получившемуся
значению
некоторое
псевдослучайное
число
,
пропорциональное
длине
ребра
.
Значение
центрального
элемента
матрицы
Т
вычислим
аналогично
,
только
будем
брать
среднее
арифметическое
четырех
значений
элементов
матрицы
в
серединах
ее
ребер
.
Теперь
разобьем
матрицу
Т
на
четыре
квадратные
подматрицы
.
Значения
их
угловых
элементов
уже
определены
и
мы
можем
рекурсивно
применить
к
подматрицам
Т
описанную
выше
процедуру
.
Будем
спускаться
рекурсивно
по
дереву
подматриц
,
пока
все
элементы
Т
не
будут
определены
.
С
помощью
подбора
коэффициентов
генерации
псевдослучайной
добавки
можно
регулировать
"
изрезанность
"
поверхности
.
Для
реалистичности
поверхности
важно
сделать
величину
псевдослучайной
добавки
зависящей
от
длины
текущего
ребра
-
с
уменьшением
размера
ребра
должно
уменьшаться
и
возможное
отклонение
высоты
его
середины
от
среднего
арифметического
высот
его
вершин
.
Один
из
других
вариантов
-
использовать
изображения
в
градациях
серого
для
карты
высот
. (
В
этом
случае
ландшафт
можно
оттекстурировать
с
помощью
соответствующей
цветной
картинки
и
линейной
генерации
текстурных
координат
)
Внимание
:
использование
NURBS
возможно
,
но
не
приветствуется
в
силу
ограниченности
использования
NURBS
для
реальных
приложений
.
123
Раскраска
ландшафта
Чтобы
сделать
получившуюся
модель
немного
более
напоминающей
ландшафт
,
ее
можно
раскрасить
.
Каждой
вершине
можно
сопоставить
свой
цвет
,
зависящий
от
высоты
этой
вершины
.
Например
,
вершины
выше
определенного
уровня
можно
покрасить
в
белый
цвет
в
попытке
сымитировать
шапки
гор
,
вершины
пониже
-
в
коричневый
цвет
скал
,
а
вершины
уровнем
еще
ниже
-
в
зеленый
цвет
травы
.
Значения
"
уровней
"
раскраски
поверхности
следует
подобрать
из
эстетических
соображений
.
Освещение
ландшафта
Для
еще
большего
реализма
и
для
подчеркивания
рельефа
осветить
модель
ландшафта
бесконечно
удаленным
источником
света
(
как
бы
солнцем
).
Цвет
вершин
можно
задавать
через
glColor*()
совместно
с
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE)
;
Туман
Чтобы
усилить
(
или
хотя
бы
создать
)
иллюзию
больших
размеров
модели
и
ее
протяженности
,
можно
воспользоваться
эффектом
тумана
.
Тип
тумана
(
линейный
или
экспоненциальный
)
следует
выбрать
из
индивидуальных
эстетических
предпочтений
.
Способ
создания
тумана
описан
в
разделе
4.4.
Управление
Элементарное
управление
движением
камеры
по
клавиатурным
"
стрелочкам
".
Нажатие
на
стрелку
"
вверх
" -
передвижение
по
направлению
взгляда
вперед
. "
Назад
" -
по
направлению
взгляда
назад
.
"
Влево
", "
Вправо
"
по
аналогии
, "Page Up", "Page Down" -
вверх
,
вниз
,
соответственно
.
В
GLUT'
е
получать
нажатия
не
алфавитно
-
цифровых
клавиш
можно
через
функцию
glutSpecialFunc(void (*)(int key, int x, int
y))
,
где
key -
константа
,
обозначающая
клавишу
(
см
.
в
glut.h -
GLUT_KEY_
).
Функция
используется
аналогично
glutKeyboardFunc()
.
Дополнительная
часть
Управление
мышью
:
124
Движение
мыши
в
горизонтальной
плоскости
(
смещение
по
оси
X)
управляет
углом
поворота
направления
взгляда
в
горизонтальной
плоскости
(
альфа
,
от
0
до
2*PI).
Движение
мыши
в
вертикальной
плоскости
(
смещение
по
оси
Y)
управляет
углом
поворота
направления
взгляда
в
вертикальной
плоскости
относительно
горизонта
(
бета
,
от
-PI
до
PI).
Зная
оба
угла
,
вектор
направления
взгляда
в
мировых
координатах
вычисляется
следующим
образом
:
direction_z = sin(
бета
);
direction_x = cos(
альфа
) * cos(
бета
);
direction_y = sin(
альфа
) * cos(
бета
),
а
затем
нормализуется
.
Вектор
направления
"
вбок
"
вычисляется
как
векторное
произведение
вектора
направления
вертикально
вверх
,
то
есть
вектора
(0, 0, 1)
и
уже
известного
вектора
направления
взгляда
.
Вектор
направления
"
вверх
"
вычисляется
как
векторное
произведение
вектора
направления
взгляда
и
вектора
направления
"
вбок
".
Положение
камеры
в
OpenGL
можно
передать
через
gluLookAt()
.
Подсказка
:
параметр
target
можно
положить
равным
position
+
direction
Смещение
позиции
камеры
должно
происходить
не
на
фиксированное
расстояние
за
один
кадр
,
а
вычисляться
,
исходя
из
скорости
передвижения
камеры
,
и
времени
,
ушедшего
на
обсчет
последнего
кадра
.
Передвижение
камеры
должно
осуществляться
в
направлении
взгляда
.
Скажем
,
по
левой
кнопке
мыши
-
вперед
,
а
по
правой
-
назад
.
Для
того
,
чтобы
засечь
время
,
можно
воспользоваться
функцией
timeGetTime()
,
описанной
в
"mmsystem.h",
и
реализованной
в
библиотеке
"winmm.lib" (
только
для
Windows)
#include "mmsystem.h"
...
void Display()
{
...
int system_time_before_rendering;
system_time_before_rendering = timeGetTime();
RenderFrame();
int time_spent_rendering_msec =
timeGetTime() -system_time_before_rendering;
...
}
125
В
GLUT'
е
для
этого
есть
специальный
вызов
time =
glutGet(GLUT_ELAPSED_TIME)
(
аналогично
timeGetTime()
)
Вода
,
или
нечто
на
нее
похожее
При
раскраске
ландшафта
можно
добавить
еще
один
,
самый
нижний
"
уровень
" -
уровень
воды
.
Вершины
,
располагающиеся
на
этом
уровне
можно
покрасить
в
цвет
воды
-
предположительно
,
синий
.
Для
того
,
чтобы
получившиеся
"
водоемы
"
не
выглядели
продолжением
поверхности
ландшафта
просто
покрашенным
в
синий
цвет
,
а
имели
плоскую
поверхность
,
при
генерации
поля
высот
можно
установить
порог
высоты
,
ниже
которого
"
опускаться
"
вершинам
запрещается
.
Если
для
элемента
матрицы
генерируется
значение
высоты
ниже
этого
порога
,
элемент
инициализируется
пороговым
значением
.
Объекты
По
ландшафту
можно
раскидать
в
художественном
беспорядке
от
пятидесяти
(50)
объектов
,
встречающихся
на
ландшафте
в
обычной
жизни
,
например
домов
или
деревьев
.
При
этом
ель
считается
деревом
,
а
две
равнобедренные
вытянутые
вертикально
грани
,
поставленные
на
ландшафт
крест
накрест
и
покрашенные
в
зеленый
цвет
,
считаются
елью
.
Отражения
в
воде
Сделать
так
,
чтобы
ландшафт
отражался
в
воде
,
которая
уже
должна
присутствовать
на
ландшафте
(
то
есть
подразумевается
,
что
это
дополнительное
задание
является
развитием
дополнительного
задания
2).
Один
из
вариантов
реализации
:
рассчитав
текущую
матрицу
камеры
,
отразить
ее
относительно
плоскости
воды
и
изображение
ландшафта
,
не
выводя
при
этом
грани
поверхности
воды
.
Затем
,
пользуясь
еще
не
отраженной
матрицей
камеры
,
визуализировать
грани
поверхности
воды
полупрозрачными
.
Это
создаст
иллюзию
поверхности
воды
,
сквозь
которую
видно
отражение
.
Затем
,
опять
же
с
неотраженной
матрицей
камеры
,
нужно
нарисовать
сам
ландшафт
. (
этот
подход
является
частным
случаем
описанного
в
разделе
7.3.)
Тени
На
этапе
раскраски
вершин
ландшафта
(
то
есть
это
надо
сделать
один
раз
,
а
не
каждый
кадр
)
из
каждой
вершины
можно
выпустить
луч
,
противоположный
направлению
солнца
.
Если
луч
не
пересекся
с
поверхностью
ландшафта
-
раскрашивать
как
запланировано
,
если
пересекся
-
значит
данная
вершина
ландшафта
находится
в
тени
и
для