
Матрицы преобразований
В OpenGL различные преобразования объектов сцены описываются с помощью матриц размера 4x4. Есть три типа матриц: видовая, проекционная и текстурная. Видовая матрица описывает преобразования объекта в мировых координатах: параллельный перенос, масштабирование и поворот. Проекционная матрица задает вид проекции трехмерных объектов на плоскость экрана (в оконные координаты), а текстурная матрица управляет наложением текстуры на объект.
Перед вызовом функций, изменяющих матрицу определенного типа, сначала необходимо установить эту матрицу в качестве текущей с помощью функции:
void glMatrixMode(GLenum mode)
Параметр mode принимает значения GL_MODELVIEW, GL_PROJECTION или GL_TEXTURE.
Значения элементов текущей матрицы можно задать в явном виде функцией:
void glLoadMatrix[f d](GLtype* m)
где m указывает на 16-ти элементный массив типа float или double. В нем сначала хранится первый столбец матрицы, затем второй, третий и четвертый.
Функция
void glLoadIdentity(void)
заменяет текущую матрицу на единичную. Содержимое текущей матрицы часто бывает нужно сохранить для дальнейшего использования. Для этого применяются функции сохранения/восстановления матрицы из служебного стека OpenGL:
void glPushMatrix(void)
void glPopMatrix(void)
Для матриц каждого типа в OpenGL есть отдельный стек. Для видовых матриц его глубина равна, как минимум, 32, для двух других типов матриц – минимум 2.
Для умножения текущей матрицы на другую матрицу справа используется функция:
void glMultMatrix[f d](GLtype* m)
где m является указателем на матрицу размером 4x4. Однако чаще для изменения матриц в OpenGL удобно пользоваться специальными функциями, которые по значениям параметров преобразований создают нужную матрицу и перемножают ее с текущей. Чтобы сделать текущей созданную матрицу, надо перед вызовом этих функций вызывать glLoadIdentity().
Теперь кратко рассмотрим преобразования, применяемые для отображения трехмерных объектов сцены в окно приложения (рис. 1.3).
Видовые и модельные преобразования
Видовые и модельные преобразования задаются одной и той же матрицей – видовой, т.к. изменение местоположения и направления камеры эквивалентно некоторому преобразованию координат объектов сцены (и наоборот).
К видовым преобразованиям относятся перенос, поворот и изменение масштаба вдоль координатных осей. Для выполнения этих операций достаточно умножить координаты каждой вершины объекта на соответствующую матрицу:
(xnew, ynew, znew, 1)T = M ⋅ (xold, yold, zold, 1)T
Матрицу M можно создать с помощью следующих функций:
void glTranslate[f d](GLtype dx, GLtype dy, GLtype dz)
void glRotate[f d](GLtype angle, GLtype x0, GLtype y0, GLtype z0)
void glScale[f d](GLtype x, GLtype y, GLtype z)
После создания матрицы преобразования это преобразование будет применяться ко всем далее рисуемым примитивам. В случае, если надо, например, повернуть один объект сцены, а другой оставить неподвижным, сначала удобно сохранить текущую видовую матрицу в стеке функцией glPushMatrix(), затем вызвать glRotate..() с нужными параметрами, описать примитивы, из которых состоит поворачиваемый объект, а затем восстановить текущую матрицу функцией glPopMatrix().
Кроме изменения местоположения самого объекта, иногда бывает нужно изменить положение точки наблюдения. Для этого есть функция:
void gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
GLdouble centerx, GLdouble centery, GLdouble centerz,
GLdouble upx, GLdouble upy, GLdouble upz)
Координаты (eyex, eyey, eyez) определяют точку наблюдения в мировых координатах, (centerx, centery, centerz) является центральной точкой сцены, которая будет проектироваться в центр области вывода, а вектор (upx, upy, upz) задает положительное направление оси у (т.е. определяет наклон камеры). Например, если камеру не надо поворачивать, то задается значение (0, 1, 0), а со значением (0, -1, 0) сцена будет выглядеть перевернутой.
Фактически, функция gluLookAt() совершает перенос и поворот всех объектов сцены, но в таком виде задавать параметры бывает удобнее.