Файл: графическая библиотека opengl.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 09.06.2020

Просмотров: 1689

Скачиваний: 4

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 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 

с

 


background image

 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 

для

 

реальных

 

приложений


background image

 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()

Дополнительная

 

часть

 

Управление

 

мышью

:

 


background image

 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; 
... 


background image

 125

В

 GLUT'

е

 

для

 

этого

 

есть

 

специальный

 

вызов

  

time =

 

glutGet(GLUT_ELAPSED_TIME)

 (

аналогично

 

timeGetTime()

Вода

или

 

нечто

 

на

 

нее

 

похожее

 

При

 

раскраске

 

ландшафта

 

можно

 

добавить

 

еще

 

один

самый

 

нижний

 

"

уровень

" - 

уровень

 

воды

Вершины

располагающиеся

 

на

 

этом

 

уровне

 

можно

 

покрасить

 

в

 

цвет

 

воды

 - 

предположительно

синий

Для

 

того

чтобы

 

получившиеся

  "

водоемы

не

 

выглядели

 

продолжением

 

поверхности

 

ландшафта

 

просто

 

покрашенным

 

в

 

синий

 

цвет

а

 

имели

 

плоскую

 

поверхность

при

 

генерации

 

поля

 

высот

 

можно

 

установить

 

порог

 

высоты

ниже

 

которого

  "

опускаться

вершинам

 

запрещается

Если

 

для

 

элемента

 

матрицы

 

генерируется

 

значение

 

высоты

 

ниже

 

этого

 

порога

элемент

 

инициализируется

 

пороговым

 

значением

Объекты

 

По

 

ландшафту

 

можно

 

раскидать

 

в

 

художественном

 

беспорядке

 

от

 

пятидесяти

 (50) 

объектов

встречающихся

 

на

 

ландшафте

 

в

 

обычной

 

жизни

например

 

домов

 

или

 

деревьев

При

 

этом

 

ель

 

считается

 

деревом

а

 

две

 

равнобедренные

 

вытянутые

 

вертикально

 

грани

поставленные

 

на

 

ландшафт

 

крест

 

накрест

 

и

 

покрашенные

 

в

 

зеленый

 

цвет

считаются

 

елью

Отражения

 

в

 

воде

 

Сделать

 

так

чтобы

 

ландшафт

 

отражался

 

в

 

воде

которая

 

уже

 

должна

 

присутствовать

 

на

 

ландшафте

  (

то

 

есть

 

подразумевается

что

 

это

 

дополнительное

 

задание

 

является

 

развитием

 

дополнительного

 

задания

 

2). 

Один

 

из

 

вариантов

 

реализации

рассчитав

 

текущую

 

матрицу

 

камеры

отразить

 

ее

 

относительно

 

плоскости

 

воды

 

и

   

изображение

 

ландшафта

не

 

выводя

 

при

 

этом

 

грани

 

поверхности

 

воды

Затем

пользуясь

 

еще

 

не

 

отраженной

 

матрицей

 

камеры

визуализировать

 

грани

 

поверхности

 

воды

 

полупрозрачными

Это

 

создаст

 

иллюзию

 

поверхности

 

воды

сквозь

 

которую

 

видно

 

отражение

Затем

опять

 

же

 

с

 

неотраженной

 

матрицей

 

камеры

нужно

 

нарисовать

 

сам

 

ландшафт

. (

этот

 

подход

 

является

 

частным

 

случаем

 

описанного

 

в

 

разделе

 7.3.) 

Тени

 

На

 

этапе

 

раскраски

 

вершин

 

ландшафта

  (

то

 

есть

 

это

 

надо

 

сделать

 

один

 

раз

а

 

не

 

каждый

 

кадр

из

 

каждой

 

вершины

 

можно

 

выпустить

 

луч

противоположный

 

направлению

 

солнца

Если

 

луч

 

не

 

пересекся

 

с

 

поверхностью

 

ландшафта

 - 

раскрашивать

 

как

 

запланировано

если

 

пересекся

 - 

значит

 

данная

 

вершина

 

ландшафта

 

находится

 

в

 

тени

 

и

 

для