ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 09.06.2020
Просмотров: 1699
Скачиваний: 4
31
массива
:
GL_UNSIGNED_BYTE
,
GL_UNSIGNED_SHORT
,
GL_UNSIGNED_INT
,
а
count
задает
их
количество
.
Важно
отметить
,
что
использование
массивов
вершин
позволяет
оптимизировать
передачу
данных
на
сервер
OpenGL,
и
,
как
следствие
,
повысить
скорость
рисования
трехмерной
сцены
.
Такой
метод
определения
примитивов
является
одним
из
самых
быстрых
и
хорошо
подходит
для
визуализации
больших
объемов
данных
.
Контрольные
вопросы
1.
Что
такое
функция
обратного
вызова
и
как
функции
обратного
вызова
могут
быть
использованы
для
работы
с
OpenGL?
2.
Для
чего
нужна
функция
обновления
изображения
и
что
она
делает
?
3.
Что
такое
примитив
в
OpenGL?
4.
Что
такое
атрибут
?
Перечислите
известные
вам
атрибуты
вершин
в
OpenGL.
5.
Что
в
OpenGL
является
атомарным
примитивом
?
Какие
типы
примитивов
вы
знаете
?
6.
Для
чего
в
OpenGL
используются
команды
glEnable/glDisable?
7.
Что
такое
операторные
скобки
и
для
чего
они
используются
в
OpenGL?
8.
Что
такое
дисплейные
списки
?
Как
определить
список
и
как
вызвать
его
отображение
?
9.
Поясните
организацию
работы
с
массивами
вершин
и
их
отличие
от
дисплейных
списков
.
10.
Поясните
работу
команды
glDrawElements()
32
Глава
3
Преобразования
объектов
В
OpenGL
используются
как
основные
три
системы
координат
:
левосторонняя
,
правосторонняя
и
оконная
.
Первые
две
системы
являются
трехмерными
и
отличаются
друг
от
друга
направлением
оси
z:
в
правосторонней
она
направлена
на
наблюдателя
,
в
левосторонней
–
в
глубину
экрана
.
Ось
x
направлена
вправо
относительно
наблюдателя
,
ось
y –
вверх
.
Левосторонняя
система
используется
для
задания
значений
параметрам
команды
gluPerspective()
,
glOrtho()
,
которые
будут
рассмотрены
в
пункте
3.3.
Правосторонняя
система
координат
используется
во
всех
остальных
случаях
.
Отображение
трехмерной
информации
происходит
в
двумерную
оконную
систему
координат
.
Строго
говоря
, OpenGL
позволяет
путем
манипуляций
с
матрицами
моделировать
как
правую
,
так
и
левую
систему
координат
.
Но
на
данном
этапе
лучше
пойти
простым
путем
и
запомнить
:
основной
системой
координат
OpenGL
является
правосторонняя
система
.
3.1.
Работа
с
матрицами
Для
задания
различных
преобразований
объектов
сцены
в
OpenGL
используются
операции
над
матрицами
,
при
этом
различают
три
типа
матриц
:
модельно
-
видовая
,
матрица
проекций
и
матрица
текстуры
.
Все
они
имеют
размер
4x4.
Видовая
матрица
определяет
преобразования
Рис
. 4
Системы
координат
в
OpenGL
x
z
y
y
x
z
x
y
a)
правосторонняя
система
б
)
левосторонняя
система
б
)
оконная
система
33
объекта
в
мировых
координатах
,
такие
как
параллельный
перенос
,
изменение
масштаба
и
поворот
.
Матрица
проекций
определяет
,
как
будут
проецироваться
трехмерные
объекты
на
плоскость
экрана
(
в
оконные
координаты
),
а
матрица
текстуры
определяет
наложение
текстуры
на
объект
.
Умножение
координат
на
матрицы
происходит
в
момент
вызова
соответствующей
команды
OpenGL,
определяющей
координату
(
как
правило
,
это
команда
glVertex*
)
Для
того
чтобы
выбрать
,
какую
матрицу
надо
изменить
,
используется
команда
:
void
glMatrixMode
(GLenum
mode
)
вызов
которой
со
значением
параметра
mode
равным
GL_MODELVIEW
,
GL_PROJECTION
,
или
GL_TEXTURE
включает
режим
работы
с
модельно
-
видовой
матрицей
,
матрицей
проекций
,
или
матрицей
текстуры
соответственно
.
Для
вызова
команд
,
задающих
матрицы
того
или
иного
типа
,
необходимо
сначала
установить
соответствующий
режим
.
Для
определения
элементов
матрицы
текущего
типа
вызывается
команда
void
glLoadMatrix[f d]
(GLtype *
m
)
где
m
указывает
на
массив
из
16
элементов
типа
float
или
double
в
соответствии
с
названием
команды
,
при
этом
сначала
в
нем
должен
быть
записан
первый
столбец
матрицы
,
затем
второй
,
третий
и
четвертый
.
Еще
раз
обратим
внимание
:
в
массиве
m
матрица
записана
по
столбцам
.
Команда
void
glLoadIdentity
(void)
заменяет
текущую
матрицу
на
единичную
.
Часто
бывает
необходимо
сохранить
содержимое
текущей
матрицы
для
дальнейшего
использования
,
для
чего
применяются
команды
void
glPushMatrix
(void)
void
glPopMatrix
(void)
34
Они
записывают
и
восстанавливают
текущую
матрицу
из
стека
,
причем
для
каждого
типа
матриц
стек
свой
.
Для
модельно
-
видовых
матриц
его
глубина
равна
как
минимум
32,
для
остальных
–
как
минимум
2.
Для
умножения
текущей
матрицы
на
другую
матрицу
используется
команда
void
glMultMatrix[f d]
(GLtype *
m
)
где
параметр
m
должен
задавать
матрицу
размером
4x4.
Если
обозначить
текущую
матрицу
за
М
,
передаваемую
матрицу
за
T,
то
в
результате
выполнения
команды
glMultMatrix
текущей
становится
матрица
M * T.
Однако
обычно
для
изменения
матрицы
того
или
иного
типа
удобно
использовать
специальные
команды
,
которые
по
значениям
своих
параметров
создают
нужную
матрицу
и
умножают
ее
на
текущую
.
В
целом
,
для
отображения
трехмерных
объектов
сцены
в
окно
приложения
используется
последовательность
,
показанная
на
рисунке
.
Запомните
:
все
преобразования
объектов
и
камеры
в
OpenGL
производятся
с
помощью
умножения
векторов
координат
на
матрицы
.
Причем
умножение
происходит
на
текущую
матрицу
в
момент
определения
координаты
командой
glVertex*
и
некоторыми
другими
.
Рис
. 5.
Преобразования
координат
в
OpenGL
Нормализованные
координаты
Модельно
-
видовое
преобразование
Преобразование
проекции
и
нормализация
Преобразование
к
области
вывода
Модельно
-
видовая
матрица
Матрица
проекции
Параметры
области
вывода
(glViewport)
Видовые
координаты
Оконные
координаты
Мировые
координаты
35
3.2.
Модельно
-
видовые
преобразования
К
модельно
-
видовым
преобразованиям
будем
относить
перенос
,
поворот
и
изменение
масштаба
вдоль
координатных
осей
.
Для
проведения
этих
операций
достаточно
умножить
на
соответствующую
матрицу
каждую
вершину
объекта
и
получить
измененные
координаты
этой
вершины
:
(x’, y’, z’, 1)
T
= M * (x, y, z, 1)
T
где
M –
матрица
модельно
-
видового
преобразования
.
Перспективное
преобразование
и
проектирование
производится
аналогично
.
Сама
матрица
может
быть
создана
с
помощью
следующих
команд
:
void
glTranslate[f d]
(GLtype
x
, GLtype
y
, GLtype
z
)
void
glRotate[f d]
(GLtype
angle
, GLtype
x
, GLtype
y
,
GLtype z)
void
glScale[f d]
(GLtype
x
, GLtype
y
, GLtype
z
)
glTranlsate*()
производит
перенос
объекта
,
прибавляя
к
координатам
его
вершин
значения
своих
параметров
.
glRotate*(
)
производит
поворот
объекта
против
часовой
стрелки
на
угол
angle
(
измеряется
в
градусах
)
вокруг
вектора
(x,y,z).
glScale*()
производит
масштабирование
объекта
(
сжатие
или
растяжение
)
вдоль
вектора
(x,y,z),
умножая
соответствующие
координаты
его
вершин
на
значения
своих
параметров
.
Все
эти
преобразования
изменяют
текущую
матрицу
,
а
поэтому
применяются
к
примитивам
,
которые
определяются
позже
.
В
случае
,
если
надо
,
например
,
повернуть
один
объект
сцены
,
а
другой
оставить
неподвижным
,
удобно
сначала
сохранить
текущую
видовую
матрицу
в
стеке
командой
glPushMatrix(
),
затем
вызвать
glRotate()
с
нужными
параметрами
,
описать
примитивы
,
из
которых
состоит
этот
объект
,
а
затем
восстановить
текущую
матрицу
командой
glPopMatrix().
Кроме
изменения
положения
самого
объекта
,
часто
бывает
необходимо
изменить
положение
наблюдателя
,
что
также
приводит
к
изменению
модельно
-
видовой
матрицы
.
Это
можно
сделать
с
помощью
команды