Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (1124366), страница 6
Текст из файла (страница 6)
void glMatrixMode (GLenum mode)
вызов которой со значением параметра mode, равным GL_MODELVIEW, GL_PROJECTION или GL_TEXTURE, включает режим работы с модельно-видовой матрицей, матрицей проекций, или матрицей текстуры соответственно. Для вызова команд, задающих матрицы того или иного типа, необходимо
4-1- Работа с матрицами
57
сначала установить соответствующий режим.
Для определения элементов матрицы текущего типа вызывается команда
void glLoadMatrix [ f d] (GLtype *m)
где m указывает на массив из 16 элементов типа float или double в соответствии с названием команды, при этом сначала в нем должен быть записан первый столбец матрицы, затем второй, третий и четвертый. Еще раз обратим внимание: в массиве m матрица записана по столбцам. Команда
void glLoadldentity (void)
заменяет текущую матрицу на единичную.
Часто бывает необходимо сохранить содержимое текущей матрицы для дальнейшего использования, для чего применяются команды
void glPushMatrix (void) void glPopMatrix (void)
Они записывают и восстанавливают текущую матрицу из стека, причем для каждого типа матриц стек свой. Для модельно-видовых матриц его глубина равна как минимум 32, для остальных— как минимум 2.
Для умножения текущей матрицы на другую матрицу используется команда
void glMultMatrix[f d] (GLtype *m)
где параметр m должен задавать матрицу размером 4x4. Если обозначить текущую матрицу за М, передаваемую матрицу за Т, то в результате выполнения команды glMultMatrix текущей становится матрица М*Т. Однако обычно для изменения матрицы того или иного типа удобно использовать специальные команды, которые по значениям своих параметров создают нужную матрицу и умножают ее на текущую.
58
Глава 4- Преобразования объектов
В целом, для отображения трехмерных объектов сцены в окно приложения используется последовательность, показанная на рисунке 4.2.
Мировые координаты
Видовые координаты
Нормализованные координаты
Параметры области вывода (gIViewport)
Оконные координаты
Рис. 4.2. Преобразования координат в OpenGL
Запомните: все преобразования объектов и камеры в OpenGL производятся с помощью умножения векторов координат на матрицы. Причем умножение происходит на текущую матрицу в момент определения координаты командой glVertex и некоторыми другими.
4.2. Модельно-видовые преобразования
К модельно-видовым преобразованиям будем относить перенос, поворот и изменение масштаба вдоль координатных осей. Для проведения этих операций достаточно умножить на соответствующую матрицу каждую вершину объекта и получить из-
4-2. Модельно-видовые преобразования
59
мененные координаты этой вершины:
(х'\ | (х\ | |
У' | = М | У |
Z' | Z |
VI/ VI/
где М — матрица модельно-видового преобразования. Перспективное преобразование и проецирование производится аналогично. Сама матрица может быть создана с помощью следующих команд:
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)
glTranslate производит перенос объекта, прибавляя к координатам его вершин значения своих параметров.
glRotate производит поворот объекта против часовой стрелки на угол angle (измеряется в градусах) вокруг вектора(х,у,г).
glScale производит масштабирование объекта (сжатие или растяжение) вдоль вектора(х,у,г), умножая соответствующие координаты его вершин на значения своих параметров.
Все эти преобразования изменяют текущую матрицу, а потому применяются к примитивам, которые определяются позже. В случае, если надо, например, повернуть один объект сцены, а другой оставить неподвижным, удобно сначала сохранить текущую видовую матрицу в стеке командой glPushMatrix, затем вызвать glRotate с нужными параметрами, описать примитивы, из которых состоит этот объект, а затем восстановить текущую матрицу командой glPopMatrix.
Кроме изменения положения самого объекта, часто бывает необходимо изменить положение наблюдателя, что также приводит к изменению модельно-видовой матрицы.
Это можно сделать с помощью команды
60
Глава 4- Преобразования объектов
void gluLookAt (
GLdouble eyex , GLdouble eyey , GLdouble eyez , GLdouble centx , GLdouble centy , GLdouble centz , GLdouble upx, GLdouble upy, GLdouble upz)
где точка (eyex, eyey, eyez) определяет точку наблюдения, (centx, centy, centz) задает центр сцены, который будет проецироваться в центр области вывода, а вектор (upx, upy, upz) задает положительное направление оси у, определяя поворот камеры. Если, например, камеру не надо поворачивать, то задается значение (0,1,0), а со значением (0, —1,0) сцена будет перевернута.
Строго говоря, эта команда совершает перенос и поворот объектов сцены, но в таком виде задавать параметры бывает удобнее. Следует отметить, что вызывать команду gluLookAtQ имеет смысл перед определением преобразований объектов, когда мо-дельно-видовая матрица равна единичной.
Запомните: матричные преобразования в OpenGL нужно записывать в обратном порядке. Например, если вы хотите сначала повернуть объект, а затем передвинуть его, сначала вызовите команду glTranslate (), а только потом —glRotate(). После этого определяйте сам объект.
4.3. Проекции
В OpenGL существуют стандартные команды для задания ортографической (параллельной) и перспективной проекций. Первый тип проекции может быть задан командами
void glOrtho (GLdouble left , GLdouble right , GLdouble bottom , GLdouble top , GLdouble near , GLdouble far)
void gluOrtho2D (GLdouble left , GLdouble right , GLdouble bottom, GLdouble top)
4-3. Проекции
61
Первая команда создает матрицу проекции в усеченный объем видимости (параллелепипед видимости) в левосторонней системе координат.
Параметры команды задают точки (left, bottom, znear) и (right, top, z far), которые отвечают левому нижнему и правому верхнему углам окна вывода. Параметры near и far задают расстояние до ближней и дальней плоскостей отсечения по удалению от точки (0, 0, 0) и могут быть отрицательными.
z = zfar | ||||
/ | z = z | lear | ||
/ | ||||
(left, bottom, znear | у |
(right, top, zfar)
Рис. 4.З. Ортографическая проекция
Во второй команде, в отличие от первой, значения near и far устанавливаются равными —1 и 1 соответственно. Это удобно, если OpenGL используется для рисования двумерных объектов. В этом случае положение вершин можно задавать, используя команды glVertex2.
Перспективная проекция определяется командой
void gluPerspective (GLdouble angley , GLdouble aspect ,
GLdouble znear, GLdouble zfar)
которая задает усеченный конус видимости в левосторонней системе координат. Параметр angley определяет угол видимости в градусах по оси у и должен находиться в диапазоне от 0 до 180.
62
Глава 4- Преобразования объектов
Угол видимости вдоль оси х задается параметром aspect, который обычно задается как отношение сторон области вывода (как правило, размеров окна).
Рис. 4.4. Перспективная проекция
Параметры zfar и znear задают расстояние от наблюдателя до плоскостей отсечения по глубине и должны быть положительными. Чем больше отношение zfar/znear, тем хуже в буфере глубины будут различаться расположенные рядом поверхности, так как по умолчанию в него будет записываться «сжатая» глубина в диапазоне от 0 до 1.
Прежде чем задавать матрицы проекций, не забудьте включить режим работы с нужной матрицей командой glMatrixMode(GL_PROJECTION) и сбросить текущую с помощью вызова glLoadldentityQ.
Пример:
/* ортографическая проекция */ glMatrixMode (GL_PROJECTION); glLoadldentity () ; glOrtho(0, w, 0, h, -1.0, 1.0);
4-4- Область вывода
63
4.4. Область вывода
После применения матрицы проекций на вход следующего преобразования подаются так называемые усеченные (clipped) координаты. Затем находятся нормализованные координаты вершин по формуле:
'xn\ /Xc/Wc
Уп 1 = 1 Ус/Wc
,Zn) \Zc/wc
Область вывода представляет собой прямоугольник в оконной системе координат, размеры которого задаются командой
void glViewPort (GLint x, GLint у,
GLint width, GLint height)
Значения всех параметров задаются в пикселах и определяют ширину и высоту области вывода с координатами левого нижнего угла (х,у) в оконной системе координат. Размеры оконной системы координат определяются текущими размерами окна приложения, точка (0,0) находится в левом нижнем углу окна.
Используя параметры команды glViewPortQ, OpenGL вычисляет оконные координаты центра области вывода (ох,оу) по формулам:
ох = х + width/2 оу = у + height/2
Пусть рх = width, py = height, тогда можно найти оконные координаты каждой вершины:
{рх/2)хп + ох
(Ру/2)Уп + Оу
J(/-n)/2]zra + (n + /)/2,
При этом целые положительные величины пи/ задают минимальную и максимальную глубину точки в окне и по умолчанию равны 0 и 1 соответственно. Глубина каждой точки записывается в специальный буфер глубины (z-буфер), который
64 Глава 4- Преобразования объектов
используется для удаления невидимых линий и поверхностей. Установить значения пи/ можно вызовом функции
void glDepthRange (GLclampd n, GLclampd f)
Команда glViewPortQ обычно используется в функции, зарегистрированной с помощью команды glutReshapeFuncQ, которая вызывается, если пользователь изменяет размеры окна приложения.
4.5. Контрольные вопросы
-
Какие системы координат используются в OpenGL?
-
Перечислите виды матричных преобразований в OpenGL. Каким образом в OpenGL происходят преобразования объектов?
-
Что такое матричный стек?
-
Перечислите способы изменения положения наблюдателя в OpenGL.
-
Какая последовательность вызовов команд glTranslate (), glRotateQ и glScale() соответствует команде gluLookAt(0, 0, -10, 10, 0, 0, 0, -1, 0)?
-
Какие стандартные команды для задания проекций вы знаете?
-
Что такое видовые координаты? Нормализованные координаты?
Глава 5.
Материалы и освещение
Для создания реалистичных изображений необходимо определить как свойства самого объекта, так и свойства среды, в которой он находится. Первая группа свойств включает в себя параметры материала, из которого сделан объект, способы нанесения текстуры на его поверхность, степень прозрачности объекта. Ко второй группе можно отнести количество и свойства источников света, уровень прозрачности среды, а также модель освещения. Все эти свойства можно задавать, вызывая соответствующие команды OpenGL.
5.1. Модель освещения
В OpenGL используется модель освещения, в соответствии с которой цвет точки определяется несколькими факторами: свойствами материала и текстуры, величиной нормали в этой точке, а также положением источника света и наблюдателя. Для корректного расчета освещенности в точке надо использовать единичные нормали, однако команды типа glScale могут изменять длину нормалей. Чтобы это учитывать, используйте уже упоминавшийся режим нормализации векторов нормалей, который
65