Модельно-видовые преобразования

Определение матрицы видового преобразования удобнее осуществлять специальными командами OpenGL: перенос, масштабирование и вращение. Преобразования осуществляются в мировой системе координат. Рассмотрим их подробнее.

void glTranslate[f d] (GLtype Dx, GLtype Dy, GLtype Dz)

Эта команда готовит матрицу преобразования для переноса графического объекта на расстояние Dx по оси х, на расстояние Dy по оси у и на расстояние Dz по оси z.

void glScale[f d] (GLtype Sx, GLtype Sy, GLtype Sz)

При помощи этой команды осуществляется формирование видовой матрицы для масштабирования объекта вдоль осей мировых координат. В Sx раз вдоль оси х, в Sy раз вдоль оси у и в Sz раз вдоль оси z.

void glRotate[f d](GLtype angle, GLtype x, GLtype y, GLtype z)

Эта команда рассчитывает видовую матрицу для выполнения вращения объекта против часовой стрелки на угол angle относительно радиус-вектора, заданного параметрами х, у и z. Внимание'. Угол angle задается в градусах.

Необходимо помнить, что на самом деле преобразования осуществляются не над самим объектом, а над его локальной системой координат. Это очень удобно, когда в одну глобальную систему координат сцены необходимо вставить определенным образом несколько объектов, описанных в своих системах локальных координат. Поясним на примере (все рассматриваем в плоскости z = 0). Пусть требуется объект А (квадрат), заданный в своей системе координат, переместить вдоль оси х на 2 единицы и развернуть на 45° против часовой стрелки относительно оси z (рис. 2). Такая постановка задачи в OpenGL не применима, так как объект определяется только в конце своих геометрических преобразований. Правильнее было сказать: необходимо развернуть на 45° (против часовой стрелки) систему координат относительно вектора (0, 0, 1), после чего переместить ее (относительно старого положения) в новое место вдоль вектора (2, 0, 0) и определить объект А в новом положении системы координат.

Пояснение модельно-видовых преобразований в OpenGL

Рис. 2. Пояснение модельно-видовых преобразований в OpenGL

Для выполнения такой задачи можно использовать следующий фрагмент программы модельно-видового преобразования:

// шаг 1 - устанавливается единичная текущая матрица (оси хОу)

glLoadldentityO;

// шаг 2 - поворачивается система координат хОу на 45°

// против часовой стрелки относительно вектора

// (0, 0, 1) и занимает новое положение х'Оу'

glRotatef(45, 0, 0, 1);

// шаг 3 - система х'Оу' смещается по оси х' на 2 единицы и

// занимает положение х"0у"

glTranslatef(2.0f, O.Of, O.Of);

// шаг 4 - определяем объект и текущая матрица

// модельно-видового преобразования умножается

// на координаты объекта

glBegin(GL_QUADS);

glVertex3f(-l .Of, 1 .Of, O.Of); // левый верхний угол

glVertex3f(1.0f, l.Of, O.Of); // правый верхний угол glVertex3f(1.0f, -1 .Of, O.Of); // правый нижний угол

glVertex3f(-l .Of, -1 .Of, O.Of); // левый нижний угол

glEnd();

Теперь рассмотрим, что произойдет с объектом А, если поменять местами шаг 2 с шагом 3 в приведенном выше фрагменте программы. Получим новый код.

И Устанавливается единичная текущая матрица оси хОу glLoadldentityO;

// Система хОу смещается по оси х на 2 единицы и занимает

И положение х'Оу'

glTranslatef(2.0f, O.Of, O.Of);

// Поворачивается система координат х'Оу' на 45°

// против часовой стрелки относительно вектора (0, 0, 1) и

// занимает новое положение х"0у"

glRotatef(45, 0, 0, 1);

// Определяем объект и текущая матрица модельно-видового

// преобразования умножается на координаты объекта glBegin(GL_QUADS);

glVertex3f(-l.Of, l.Of, O.Of); // левый верхний угол

glVertex3f(l.Of, l.Of, O.Of); // правый верхний угол

glVertex3f(l.Of, -l.Of, O.Of); // правый нижний угол

glVertex3f(-l.Of, -l.Of, O.Of); // левый нижний угол

glEnd();

Конечный результат такого преобразования будет отличаться от предыдущей задачи. Ход преобразований можно проанализировать на рис. 3.

Пример модельно-видовых преобразований

Рис. 3. Пример модельно-видовых преобразований

Если в приведенном примере (рис. 3) рассуждать по геометрическим преобразованиям с точки зрения объекта, то конечную цель можно достичь после следующих шагов: шаг 1 - поворота объекта на 45° относи тельно оси z, после чего шаг 2 - перемещение объекта (повернутого) вдоль оси х на две единицы. Но в OpenGL это осуществляется в обратном порядке.

Совет: приучите себя к рассуждениям о преобразованиях объектов с точки зрения их систем координат, и это вас избавит от возможных геометрических ошибок.

Напоминаем, что текущая матрица умножается на координаты точек объекта только при определении самого объекта. После чего координаты объекта преобразуются в новые значения. А до этого момента формируется текущая матрица преобразования. Любой вызов команды преобразования завершается перемножением текущей матрицы преобразования на сформированную матрицу командой преобразования. Полученная матрица размещается на место текущей.

Изменяя положение самого объекта, создается иллюзия, что перемещается камера наблюдения. В OpenGL существует возможность управлять камерой с одновременным изменением модельно-видовой матрицы. Это можно сделать с помощью команды:

void gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble ex, GLdouble cy, GLdouble cz, GLdouble upx, GLdouble upy, GLdouble upz)

Здесь параметры eyex, eyey, eyez определяют точку наблюдения, ex, cy, cz задают центр сцены, который будет проектироваться в центр области вывода, и параметры upx, upy, upz задают вектор положительного направления оси у сцены, определяя поворот камеры. Обычно параметры ирх, upy, upz имеют значения - (0, 1, 0).

Внимание'. Команду gluLookAt() обычно отрабатывают, когда модельно-видовая матрица равна единичной. Например:

glMatrixMode(GL_MODELVIEW); И текущая матрица - видовая glLoadldentityO; // текущая матрица - единичная

gluLookAt(2.0f, 1 .Of, 3.0f, // положение центра наблюдения

6.0f, O.Of, O.Of, // центр сцены в мировых координатах

O.Of, 1 .Of, O.Of); И вектор "верх" направлен вдоль оси^

Область вывода

В OpenGL готовая для визуализации графическая информация поступает в специально настроенную область вывода, которая определяется шириной (рх), высотой (ру) и положением ее центра на экране х, оу). Эти параметры формируются специальной командой:

void glViewPort (GLint х, GLint у, GLint width, GLint height)

Параметры x и у задают координаты левого нижнего угла (х, у) области вывода в оконной системе координат. Параметры width и height определяют ширину и высоту окна вывода. Все параметры команды задаются в пикселях. Размеры оконной системы координат определяются текущими размерами окна приложения, точка (0, 0) находится в левом нижнем углу окна.

После выполнения команды glViewPort параметры области вывода устанавливаются в значения рх = width, ру = height, ох = х + width/2 и оу = у + height (точка с координатами (0, 0, 0) в оконных координатах будет располагаться в центре окна области вывода), а оконные координаты выводимых вершин определяются соотношением:

f-n ,n+f

Г 2 2

где пи/ определяют допустимый диапазон изменения глубины (z - координата). По умолчанию данные параметры равны 0 и 1 соответственно. Но их можно изменять командой:

void glDepthRange (GLclampd п, GLclampd f)

После отсечения и деления на w координаты z лежат в диапазоне значений от -1 до 1 соответственно для ближней и дальней плоскостей отсечения. Команда glDepthRange определяет линейное отображение нормализованных z-координат из этого диапазона в оконные координаты.

Команду glViewPort часто используют в CAD системах для моделирования четырех видов проектируемого объекта. Это можно реализовать, например, следующим образом: экран разбивается на четыре части и каждая описывается командой glViewPort с соответствующими значениями параметров окна вывода. После каждого такого описания необходимо настроить вид проекции и параметры камеры наблюдения. После чего необходимо вывести сцену. И так четыре раза.

 
Посмотреть оригинал
< Пред   СОДЕРЖАНИЕ   ОРИГИНАЛ   След >