Перед тем, как начать рисовать сцену нужно выполнить видовые преобразования. Для чего они нужны? Видовые преобразования позволяют изменить позиционирование сцены и примитивов относительно точки наблюдения, а так же изменить форму и положение всех примитивов сцены. О том, как это сделать читаем ниже.
Видовая матрица
Для осуществления видовых преобразований в OpenGL существует специальная видовая матрица порядка 4х4, с помощью которой задаются: положение, масштаб и вращение сцены.
В OpenGL видовая матрица имеет вид, показанный на рисунке.
Как видно из рисунка все элементы матрицы расположены вертикально, сверху вниз и с лева на право (по столбцам), в отличии от классической матрицы, где все элементы расположены по строкам. Учитывайте это во время работы с матрицами в OpenGL. Таким образом, если мы хотим, перемножить две матрицы, то мы перемножаем не строку первой матрицы на столбец второй (как в классической алгебре), а, наоборот, столбец первой на строку второй (подробней о перемножении матриц будет описано в следующих публикациях).
Команды для работы с матрицами
Для того чтобы сообщить OpenGL данные матрицы существуют специальные команды glLoadMatrix и glMultMatrix.
procedure glLoadMatrix*(m: PGL*); |
Где m – указатель на матрицу с данными. Данная команда заменяет текущую матрицу матрицей, указатель (m), на которую передается ей в качестве параметра.
procedure glMultMatrix*(m: PGL*); |
Где m – указатель на матрицу с данными. Эта команда перемножает текущую матрицу на заданную ей матрицу в качестве параметра по указателю m.
Следует помнить, что данные команды работают с текущей, а не конкретно с видовой матрицей. Поэтому, для выбора видовой матрицы нужно вызвать команду glMatrixMode c параметром GL_MODELVIEW.
Единичная матрица
Ели не вызывать команд, влияющих на видовую матрицу, то она останется установленной в единичную. Единичная матрица никак не влияет на координаты вершин примитивов сцены. Данное состояние матрицы установлено по умолчанию. Видовая матрица, установленная в единичную выглядит следующим образом.
Подобную матрицу можно задать с помощью массива и передать указатель на него в качестве параметра в процедуру glLoadMatrix. Но есть и более удобный способ – команда glLoadIdentity, которая непосредственно устанавливает текущую матрицу в единичную.
Рассмотрим, как задать масштаб, перенос и вращение с помощью видовой матрицы.
Масштабирование
Чтобы сообщить OpenGL о том, как мы хотим масштабировать сцену нужно сообщить данные масштабирования по осям X, Y и Z. В видовой матрице масштабирование задается следующим образом.
Рассмотрим пример.
Здесь мы задаем матрицу, которая масштабирует сцену, по Х * 2 (увеличиваем в 2 раза), по Y * 1 (размер остается неизменным) и по Z * 0.5 (уменьшаем размер в 2 раза). Сообщить OpenGL подобную матрицу можно с помощью команд glLoadMatrix либо glMultMatrix, которые были рассмотрены выше.
Для непосредственного задания масштабирования существует команда glScale*.
procedure glScale*(x, y, z: GL*); |
Следующий вызов команды задает матрицу с масштабом по X, Y и Z, перемножая на неё текущую матрицу.
Что эквивалентно вызову команды glMultMatrix с указателем на матрицу с соответствующими данными.
Трансляция (перенос)
Для переноса по X, Y и Z параметры нужно задать следующим образом.
Матрица с такими параметрами переносит сцену, по X на 0.5, по Y на 1 и по Z на 0.8 единиц. Эту матрицу, как и предыдущую, можно сообщить с помощью команд glLoadMatrix или glMultMatrix.
Для непосредственного задания переноса существует команда glTranslate.
procedure glTranslate *(x, y, z: GLtype); |
Вот, так это выглядит на примере.
glTranslate (0.5, 1, 0.8); |
Что эквивалентно вызову команды glMultMatrix с указателем на матрицу с соответствующими данными.
Вращение
Для задания вращения нужно, специальным образом поместить данные в матрицу. Как – смотрим ниже.
Вращение вокруг оси X br>
Вращение вокруг оси Y br>
Вращение вокруг оси Z br>
Как видно из рисунков, вращение вокруг осей X, Y и Z задается с помощью синусов и косинусов угла a.
Единственный недостаток данного метода – это невозможность одновременного задания вращения вокруг каждой оси (как в матрице масштабирования или переноса, например). Устранить этот недостаток можно, перемножив друг на друга все три матрицы вращения или воспользовавшись специальным алгоритмом. Как это сделать будет описано в следующих публикациях.
Чтобы сообщить матрицу вращения можно использовать все те же glLoadMatrix или glMultMatrix.
Для непосредственного задания вращения существует команда glRotate*
Procedure glRotate* (angle, x, y, z: Gl*); |
Где angle – угол вращения, x, y, z – вектор, вокруг которого производится вращение. Рассмотрим следующие примеры вращения:
Вращение вокруг оси X.
Вращение вокруг оси Y.
Вращение вокруг оси Z.
Для поворота сцены вокруг любой произвольной оси нужно использовать комбинации значений x, y и z или вычислить соответствующий вектор вращения. Следующий пример демонстрирует поворот вокруг произвольного вектора.
glRotatef(25, 0.1, 0.8, 0.3); |
Следует помнить о том, что все величины вектора вращения должны лежать в диапазоне -1..1, что соответствует единичному вектору.
|