Руководство по работе с графической библиотекой OpenGL. Руководство разработано с учетом опыта чтения курса Компьютерная графика
Скачать 0.66 Mb.
|
GL_TRIANGLE_STRIP —каждая следующая вершина задаст треугольник вместе с двумя предыдущими. GL_TRIANGLE_FAN — треугольники задаются первой вершиной и каждой следующей парой вершин (пары не пересекаются) . GL QUADS —каждая отдельная четверка вершин определяет четырехугольник; если задано не кратное четырем число вершин, то последние вершины игнорируются. GL QUAD STRIP —четырехугольник с номером п определяется вершинами с номерами 2п — 1, 2п, 2п + 2, 2п + 1. GL POLYGON —последовательно задаются вершины выпуклого многоугольника. 3.3. Операторные скобки GLBEGIN / GLEND 45 Например, чтобы нарисовать треугольник с разными цветами в вершинах, достаточно написать: GLfloat BlueCol[3] = {0,0,1}; glBegin (GL_TRIANGLES); glColor3f(1.0, 0.0, 0.0); /* красный */ glVertex3f (0.0 , 0.0, 0.0); glColor3ub (0 ,255 ,0); /* зеленый */ glVertex3f (1.0 , 0.0, 0.0); glColor3fv (BlueCol) ; /* синий */ glVertex3f (1.0 , 1.0, 0.0); glEnd(); Как правило, разные типы примитивов имеют различную скорость визуализации на разных платформах. Для увеличения производительности предпочтительнее использовать примитивы, требующие меньшее количество информации для передачи на сервер, такие как GL_TRIANGLE_STRIP, GL_QUAD_STRIP, GL_TRIAGLE_FAN. Кроме задания самих многоугольников, можно определить метод их отображения на экране. Однако сначала надо определить понятие лицевых и обратных граней. Под гранью понимается одна из сторон многоугольника, и по умолчанию лицевой считается та сторона, вершины которой обходятся против часовой стрелки. Направление обхода вершин лицевых граней можно изменить вызовом команды void glFrontFace (GLenum mode) со значением параметра mode равным GL_CW (clockwise), а вернуть значение по умолчанию можно, указав GL_CCW (counterclockwise). Чтобы изменить метод отображения многоугольника используется команда void glPolygonMode (GLenum face , Glenum mode) 46 Глава 3. Рисование геометрических объектов Параметр mode определяет как будут отображаться многоугольники, а параметр face устанавливает тип многоугольников, к которым будет применяться эта команда и может принимать следующие значения: GL FRONT —для лицевых граней; GL BACK —для обратных граней; GL_FRONT_AND_BACK —для всех граней. Параметр mode может быть равен: GL POINT —отображение только вершин многоугольников; GL LINE — многоугольники будут представляться набором отрезков; GL FILL — многоугольники будут закрашиваться текущим цветом с учетом освещения, и этот режим установлен по умолчанию. Также можно указывать какой тип граней отображать на экране. Для этого сначала надо установить соответствующий режим вызовом команды glEnable (GL_CULL_FACE), а затем выбрать тип отображаемых граней с помощью команды void glCullFace (GLenum mode) Вызов с параметром GL_FRONT приводит к удалению из изображения всех лицевых граней, а с параметром GL_BACK — обратных (установка по умолчанию). Кроме рассмотренных стандартных примитивов в библиотеках GLU и GLUT описаны более сложные фигуры, такие как сфера, цилиндр, диск (в GLU) и сфера, куб, конус, тор, тетраэдр, додекаэдр, икосаэдр, октаэдр и чайник (в GLUT). Автоматическое наложение текстуры предусмотрено только для фигур из библиотеки GLU (создание текстур в OpenGL будет рассматриваться в главе 6). 3.4- Дисплейные списки 47 Например, чтобы нарисовать сферу или цилиндр, надо сначала создать объект специального типа GLUquadricObj с помощью команды GLUquadricObj * gluNewQuadric (void ) ; а затем вызвать соответствующую команду: void gluSphere (GLUquadricObj * qobj , GLdouble radius , GLint slices , GLint stacks) void gluCylinder (GLUquadricObj * qobj , GLdouble baseRadius , GLdouble topRadius , GLdouble height , GLint slices , GLint stacks) где параметр slices задает количество разбиений вокруг оси z, a stacks — вдоль оси ъ. Более подробную информацию об этих и других командах построения примитивов можно найти в приложении А. 3.4. Дисплейные списки Если мы несколько раз обращаемся к одной и той же группе команд, то их можно объединить в так называемый дисплейный список (display list) и вызывать его при необходимости. Для того, чтобы создать новый дисплейный список, надо поместить все команды, которые должны в него войти, между следующими операторными скобками: void glNewList (GLuint list , GLenum mode) void glEndList () 48 Глава 3. Рисование геометрических объектов Для различения списков используются целые положительные числа, задаваемые при создании списка значением параметра list. Параметр mode определяет режим обработки команд, входящих в список: GL COMPILE —команды записываются в список без выполнения; GL_COMPILE_AND_EXECUTE —команды выполняются, а затем записываются в список. После того, как список создан, его можно вызвать командой void glCallList (GLuint list) указав в параметре list идентификатор нужного списка. Чтобы вызвать сразу несколько списков, можно воспользоваться командой void glCallLists ( GLsizei n, GLenum type, const GLvoid * lists) вызывающей п списков с идентификаторами из массива lists, тип элементов которого указывается в параметре type. Это могут быть типы GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_INT, GL_UNSIGNED_INT и некоторые другие. Для удаления списков используется команда void glDeleteLists (GLint list , GLsizei range) которая удаляет списки с идентификаторами ID из диапазона list < ID < list + range — 1. Пример: glNewList(l, GL_COMPILE); glBegin (GLJTRIANGLES); glVertex3f (l.Of , l.Of, l.Of); glVertex3f (10.Of , l.Of, l.Of); glVertex3f (10-Of , 10.Of, l.Of); 3.5. Массивы вершин 49 glEnd(); glEndList () glCallList (1); Дисплейные списки в оптимальном (скомпилированном) виде хранятся в памяти сервера, что позволяет рисовать примитивы в такой форме максимально быстро. В то же время большие объемы данных занимают много памяти, что влечет, в свою очередь, падение производительности. Такие большие объемы (больше нескольких десятков тысяч примитивов) лучше рисовать с помощью массивов вершин. 3.5. Массивы вершин Если вершин много, то, чтобы не вызывать для каждой команду glVertex, удобно объединять вершины в массивы, используя команду void glVertexPointer (GLint size , GLenum type, GLsizei stride , void* ptr) которая определяет способ хранения и координаты вершин. При этом size определяет число координат вершины (может быть равен 2, 3, 4), type определяет тип данных (может быть равен GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE). Иногда удобно хранить в одном массиве другие атрибуты вершины, тогда параметр stride задает смещение от координат одной вершины до координат следующей; если stride равен нулю, это значит, что координаты расположены последовательно. В параметре ptr указывается адрес, где находятся данные. Аналогично можно определить массив нормалей, цветов и некоторых других атрибутов вершины, используя команды void glNormalPointer ( GLenum type , GLsizei stride , 50 Глава 3. Рисование геометрических объектов void ^pointer ) void glColorPointer ( GLint size , GLenum type , GLsizei stride , |