Пятница, 25.05.2018, 19:41
Приветствую Вас Гость | RSS

VistaMEDIA

Главная | Регистрация | Вход

Главная » Статьи » Мои статьи

OpenGL часть 2
Преобразования координат и проекций в OpenGL

  • Преобразования координат и проекции

    Преобразования координат и проекции

    В OpenGL используются как основные три системы координат: левосторонняя, правосторонняя и оконная. Первые две системы являются трехмерными и отличаются друг от друга направлением оси z: в правосторонней она направлена на наблюдателя, а в левосторонней – в глубь экрана. Расположение осей x и y аналогично описанному выше. Левосторонняя система используется для задания значений параметрам команды gluPerspective(), glOrtho(), которые будут рассмотрены ниже, а правосторонняя или мировая система координат во всех остальных случаях. Отображение трехмерной информации происходит в двумерную оконную систему координат.

    Для задания различных преобразований объектов сцены в 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)

    заменяет текущую матрицу на единичную. Часто нужно сохранить содержимое текущей матрицы для дальнейшего использования, для чего используют команды

    • void glPushMatrix(void)
    • void glPopMatrix(void)

    Они записывают и восстанавливают текущую матрицу из стека, причем для каждого типа матриц стек свой. Для видовых матриц его глубина равна как минимум 32, а для двух оставшихся типов как минимум 2.

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

    void glMultMatrix[f d](GLtype *m)

    где m должен задавать матрицу размером 4x4 в виде массива с описанным расположением данных. Однако обычно для изменения матрицы того или иного типа удобно использовать специальные команды, которые по значениям своих параметров создают нужную матрицу и перемножают ее с текущей. Чтобы сделать текущей созданную матрицу, надо перед вызовом этой команды вызвать glLoadIdentity().

    В целом, для отображения трехмерных объектов сцены в окно приложения используется следующая последовательность действий:

    Коорди- наты объекта => Видовые коорди- наты => Усеченные коорди- наты => Нормали- зованные коорди- наты => Оконные координаты
    Рассмотрим каждое из этих преобразований отдельно. Видовое преобразование

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

    (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..() производит масштабирование объекта (сжатие или растяжение), домножая соответствующие координаты его вершин на значения своих параметров.

    Все эти преобразования будут применяться к примитивам, описания которых будут находиться ниже в программе. В случае если надо, например, повернуть один объект сцены, а другой оставить неподвижным, удобно сначала сохранить текущую видовую матрицу в стеке командой 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) сцена будет перевернута.

    Фактически, эта команда совершает перенос и поворот объектов сцены, но в таком виде задавать параметры бывает удобнее.

    Проекции

    В 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)

    Первая команда создает матрицу проекции в усеченный объем видимости (параллелограмм видимости) в левосторонней системе координат. Параметры команды задают точки (left, bottom, -near) и (right, top, -near), которые отвечают левому нижнему и правому верхнему углам окна вывода. Параметры near и far задают расстояние до ближней и дальней плоскостей отсечения по дальности от точки (0,0,0) и могут быть отрицательными.

    Во второй команде, в отличие от первой, значения near и far устанавливаются равными –1 и 1 соответственно.

    Перспективная проекция определяется командой

    void gluPerspective(GLdouble angley, GLdouble aspect, GLdouble znear, GLdouble zfar)

    которая задает усеченный конус видимости в левосторонней системе координат. Параметр angley определяет угол видимости в градусах по оси у и должен находиться в диапазоне от 0 до 180. Угол видимости вдоль оси x задается параметром aspect, который обычно задается как отношение сторон области вывода. Параметры zfar и znear задают расстояние от наблюдателя до плоскостей отсечения по глубине и должны быть положительными. Чем больше отношение zfar/znear, тем хуже в буфере глубины будут различаться расположенные рядом поверхности, так как по умолчанию в него будет записываться ‘сжатая’ глубина в диапазоне от 0 до 1 (см. следующий пункт).

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

    После применения матрицы проекций на вход следующего преобразования подаются так называемые усеченные (clip) координаты, для которых значения всех компонент (xc, yc, zc, wc)T находятся в отрезке [-1,1]. После этого находятся нормализованные координаты вершин по формуле:

    (xn, yn, zn)T=(xc/wc, yc/wc, zc/wc)T

    Область вывода представляет из себя прямоугольник в оконной системе координат, размеры которого задаются командой:

    void glViewPort(GLint x, GLint y, GLint width, GLint height)

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

    Используя параметры команды glViewPort(), вычисляются оконные координаты центра области вывода (ox, oy) по формулам ox=x+width/2, oy=y+height/2.

    Пусть px=width, py=height, тогда можно найти оконные координаты каждой вершины:

    (xw, yw, zw)T = ( (px/2) xn+ ox , (py/2) yn+ oy , [(f-n)/2] zn+(n+f)/2 )T

    При этом целые положительные величины n и f задают минимальную и максимальную глубину точки в окне и по умолчанию равны 0 и 1 соответственно. Глубина каждой точки записывается в специальный буфер глубины (z-буфер), который используется для удаления невидимых линий и поверхностей. Установить значения n и f можно вызовом функции

    void glDepthRange(GLclampd n, GLclampd f)

    Команда glViewPort() обычно используется в функции, зарегистрированной с помощью команды glutReshapeFunc(), которая вызывается, если пользователь изменяет размеры окна приложения, изменяя соответсвующим образом область вывода.

  • Материалы и освещение в OpenGL

  • Материалы и освещение Материалы и освещение

    Для создания реалистических изображений необходимо определить как свойства самого объекта, так и свойства среды, в которой он находится. Первая группа свойств включает в себя параметры материла, из которого сделан объект, способы нанесения текстуры на его поверхность, степень прозрачности объекта. Ко второй группе можно отнести количество и свойства источников света, уровень прозрачности среды. Все эти свойства можно задавать, используя соответствующие команды OpenGL.

    Свойства материала

    Для задания параметров текущего материала используются команды

    • void glMaterial[i f](GLenum face, GLenum pname, GLtype param)
    • void glMaterial[i f]v(GLenum face, GLenum pname, GLtype *params)

    С их помощью можно определить рассеянный, диффузный и зеркальный цвета материала, а также цвет степень зеркального отражения и интенсивность излучения света, если объект должен светиться. Какой именно параметр будет определяться значением param, зависит от значения pname:

    GL_AMBIENT параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют рассеянный цвет материала (цвет материала в тени).

    Значение по умолчанию: (0.2, 0.2, 0.2, 1.0).

    GL_DIFFUSE параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют цвет диффузного отражения материала.

    Значение по умолчанию:(0.8, 0.8, 0.8, 1.0).

    GL_SPECULAR параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют цвет зеркального отражения материала.

    Значение по умолчанию: (0.0, 0.0, 0.0, 1.0).

    GL_SHININESS параметр params должен содержать одно целое или вещественное значение в диапазоне от 0 до 128, которое определяет степень зеркального отражения материала.

    Значение по умолчанию: 0.

    GL_EMISSION параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют интенсивность излучаемого света материала.

    Значение по умолчанию: (0.0, 0.0, 0.0, 1.0).

    GL_AMBIENT_AND_DIFFUSE эквивалентно двум вызовам команды glMaterial..() со значением pname GL_AMBIENT и GL_DIFFUSE и одинаковыми значениями params.

    Из этого следует, что вызов команды glMaterial[i f]() возможен только для установки степени зеркального отражения материала. В большинстве моделей учитывается диффузный и зеркальный отраженный свет; первый определяет естественный цвет объекта, а второй – размер и форму бликов на его поверхности.

    Параметр face определяет тип граней, для которых задается этот материал и может принимать значения GL_FRONT, GL_BACK или GL_FRONT_AND_BACK.

    Если в сцене материалы объектов различаются лишь одним параметром, рекомендуется сначала установить нужный режим, вызвав glEnable() c параметром GL_COLOR_MATERIAL, а затем использовать команду

    void glColorMaterial(GLenum face, GLenum pname)

    где параметр face имеет аналогичный смысл, а параметр pname может принимать все перечисленные значения. После этого, значения выбранного с помощью pname свойства материала для конкретного объекта (или вершины) устанавливается вызовом команды glColor..(), что позволяет избежать вызовов более ресурсоемкой команды glMaterial..() и повышает эффективность программы.

    Источники света

    Добавить в сцену источник света можно с помощью команд

    • void glLight[i f](GLenum light, GLenum pname, GLfloat param)
    • void glLight[i f](GLenum light, GLenum pname, GLfloat *params)

    Параметр light однозначно определяет источник,и выбирается из набора специальных символических имен вида GL_LIGHTi, где i должно лежать в диапазоне от 0 до GL_MAX_LIGHT, которое не превосходит восьми.

    Оставшиеся два параметра имеют аналогичный смысл, что и в команде glMaterial..(). Рассмотрим их назначение (вначале описываются параметры для первой команды, затем для второй):

    GL_SPOT_EXPONENT параметр param должен содержать целое или вещественное число от 0 до 128, задающее распределение интенсивности света. Этот параметр описывает уровень сфокусированности источника света.

    Значение по умолчанию: 0 (рассеянный свет).

    GL_SPOT_CUTOFF параметр param должен содержать целое или вещественное число между 0 и 90 или равное 180, которое определяет максимальный угол разброса света. Значение этого параметра есть половина угла в вершине конусовидного светового потока, создаваемого источником.

    Значение по умолчанию: 180 (рассеянный свет).

    GL_AMBIENT параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют цвет фонового освещения.

    Значение по умолчанию: (0.0, 0.0, 0.0, 1.0).

    GL_DIFFUSE параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют цвет диффузного освещения.

    Значение по умолчанию: (1.0, 1.0, 1.0, 1.0)для LIGHT0 и (0.0, 0.0, 0.0, 1.0) для остальных.

    GL_SPECULAR параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют цвет зеркального отражения.

    Значение по умолчанию: (1.0, 1.0, 1.0, 1.0)для LIGHT0 и (0.0, 0.0, 0.0, 1.0) для остальных.

    GL_POSITION параметр params должен содержать четыре целых или вещественных, которые определяют положение источника света. Если значение компоненты w равно 0.0, то источник считается бесконечно удаленным и при расчете освещенности учитывается только направление на точку (x,y,z), в противном случае считается, что источник расположен в точке (x,y,z,w).

    Значение по умолчанию: (0.0, 0.0, 1.0, 0.0).

    GL_SPOT_DIRECTION параметр params должен содержать четыре целых или вещественных числа, которые определяют направление света.

    Значение по умолчанию: (0.0, 0.0, -1.0, 1.0).

    При изменении положения источника света следует учитывать следующие факты: если положение задается командой glLight..() перед определением ориентации взгляда (командой glLookAt() ), то будет считаться, что источник находится в точке наблюдения. Если положение устанавливается между заданием ориентации и преобразованиями видовой матрицы, то оно фиксируется и не зависит от видовых преобразований. В последнем случае, когда положение задано после ориентации и видовой матрицы, его положение можно менять, устанавливая как новую ориентацию наблюдателя, так и меняя видовую матрицу.

    Для использования освещения сначала надо установить соответствующий режим вызовом команды glEnable (GL_LIGHTNING), а затем включить нужный источник командой glEnable(GL_LIGHTn).

    Модель освещения

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

    Для задания глобальных параметров освещения используются команды

    • void glLightModel[i f](GLenum pname, GLenum param)
    • void glLightModel[i f]v(GLenum pname, const GLtype *params)

    Аргумент pname определяет, какой параметр модели освещения будет настраиваться и может принимать следующие значения:

    GL_LIGHT_MODEL_LOCAL_VIEWER параметр param должен быть булевским и задает положение наблюдателя. Если он равен FALSE, то направление обзора считается параллельным оси –z, вне зависимости от положения в видовыx координатах. Если же он равен TRUE, то наблюдатель находится в начале видовой системы координат. Это может улучшить качество освещения, но усложняет его расчет.

    Значение по умолчанию: FALSE.

    GL_LIGHT_MODEL_TWO_SIDE параметр param должен быть булевским и управляет режимом расчета освещенности как для лицевых, так и для обратных граней. Если он равен FALSE, то освещенность рассчитывается только для лицевых граней. Если же он равен TRUE, расчет проводится и для обратных граней. Значение по умолчанию: FALSE .

    GL_LIGHT_MODEL_AMBIENT параметр params должен содержать четыре целых или вещественных числа, которые определяют цвет фонового освещения даже в случае отсутствия определенных источников света.

    Значение по умолчанию:(0.2, 0.2, 0.2,1.0).



  • Источник: http://docs.com.ru
    Категория: Мои статьи | Добавил: vistamedia (06.10.2007) | Автор: Вячеслав
    Просмотров: 1392 | Рейтинг: 4.0/1 |
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]

    Категории каталога

    Форма входа

    Поиск

    Статистика

    Наш опрос

    Оцените мой сайт
    Всего ответов: 52

    Мини-чат

    200
    Бесплатный хостинг uCoz