Руководство по работе с графической библиотекой OpenGL. Руководство разработано с учетом опыта чтения курса Компьютерная графика
Скачать 0.66 Mb.
|
void *pointer ) Для того, чтобы эти массивы можно было использовать в дальнейшем, надо вызвать команду void glEnableClientState (GLenum array) с параметрами GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, GL_COLOR_ARRAY соответственно. После окончания работы с массивом желательно вызвать команду void glDisableClientState (GLenum array) с соответствующим значением параметра array. Для отображения содержимого массивов используется команда void glArrayElement (GLint index) которая передает OpenGL атрибуты вершины, используя элементы массива с номером index. Это аналогично последовательному применению команд вида glColor, glNormal, glVertex с соответствующими параметрами. Однако вместо нее обычно вызывается команда void glDrawArrays (GLenum mode, GLint first , GLsizei count) рисующая count примитивов, определяемых параметром mode, используя элементы из массивов с индексами от first до first + count — 1. Это эквивалентно вызову последовательности команд glArrayElement() с соответствующими индексами. В случае, если одна вершина входит в несколько примитивов, вместо дублирования ее координат в массиве удобно использовать ее индекс. Для этого надо вызвать команду 3.6. Контрольные вопросы 51 void glDrawElements (GLenum mode, GLsizei count, GLenum type, void* indices) где indices—это массив номеров вершин, которые надо использовать для построения примитивов, type определяет тип элементов этого массива: GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, a count задает их количество. Важно отметить, что использование массивов вершин позволяет оптимизировать передачу данных на сервер OpenGL, и, как следствие, повысить скорость рисования трехмерной сцены. Такой метод определения примитивов является одним из самых быстрых и хорошо подходит для визуализации больших объемов данных. 3.6. Контрольные вопросы Что такое функция обратного вызова и как функции обратного вызова могут быть использованы для работы с OpenGL? Для чего нужна функция обновления изображения и что она делает? Что такое примитив в OpenGL? Что такое атрибут? Перечислите известные вам атрибуты вершин в OpenGL. Что в OpenGL является атомарным примитивом? Какие типы примитивов вы знаете? Для чего в OpenGL используются команды glEnable и glDisable ? 52 Глава 3. Рисование геометрических объектов Что такое операторные скобки и для чего они используются в OpenGL? Что такое дисплейные списки? Как определить список и как вызвать его отображение? Поясните организацию работы с массивами вершин и их отличие от дисплейных списков. 10) Поясните работу команды glDrawElementsQ. 3.6. Контрольные вопросы 53 i • •о •. з • 1 GL POINTS 3 4 GL LINES M. GL LINE STRIP 5 C* GL LINE LOOP GL POLYGON GL_QUADS A>± GL_QUAD_STRIP GL TRIANGLES .25^ GL TRIANGLE FAN GL TRIANGLE STRIP Рис. З.1. Примитивы OpenGL. Глава 4. Преобразования объектов В OpenGL используются как основные три системы координат: левосторонняя, правосторонняя и оконная. Первые две системы являются трехмерными и отличаются друг от друга направлением оси z: в правосторонней она направлена на наблюдателя, в левосторонней — в глубину экрана. Ось х направлена вправо относительно наблюдателя, ось у — вверх. Левосторонняя система используется для задания значений параметрам команды gluPerspectiveQ, glOrtho(), которые будут рассмотрены в пункте 4.3. Правосторонняя система координат используется во всех остальных случаях. Отображение трехмерной информации происходит в двухмерную оконную систему координат. Строго говоря, OpenGL позволяет путем манипуляций с матрицами моделировать как правую, так и левую систему координат. Но на данном этапе лучше пойти простым путем и запомнить: основной системой координат OpenGL является правосторонняя система. 55 56 Глава 4- Преобразования объектов (в) Рис. 4.1. Системы координат в OpenGL. (a) — правосторонняя, (б) — левосторонняя, (в) — оконная. 4.1. Работа с матрицами Для задания различных преобразований объектов сцены в OpenGL используются операции над матрицами, при этом различают три типа матриц: модельно-видовая, матрица проекций и матрица текстуры. Все они имеют размер 4x4. Видовая матрица определяет преобразования объекта в мировых координатах, такие как параллельный перенос, изменение масштаба и поворот. Матрица проекций определяет, как будут проецироваться трехмерные объекты на плоскость экрана (в оконные координаты), а матрица текстуры определяет наложение текстуры на объект. Умножение координат на матрицы происходит в момент вызова соответствующей команды OpenGL, определяющей координату (как правило, это команда glVertex.) Для того чтобы выбрать, какую матрицу надо изменить, используется команда: 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 мененные координаты этой вершины:
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. Кроме изменения положения самого объекта, часто бывает необходимо изменить положение наблюдателя, что также приводит к изменению модельно-видовой матрицы. Это можно сделать с помощью команды |