void glCullFace(GLenum mode)
Вызов с параметром GLfront приводит к удалению из изображения всех лицевых граней, а с параметром GLback – обратных (установка по умолчанию).
Кроме рассмотренных стандартных примитивов в библиотеках GLU и GLUT описаны более сложные фигуры, такие как сфера, цилиндр, диск (в GLU) и сфера, куб, конус, тор, тетраэдр, додекаэдр, икосаэдр, октаэдр и чайник (в GLUT). Автоматическое наложение текстуры предусмотрено только для фигур из библиотеки GLU (создание текстур в OpenGL будет рассматриваться ниже).
Например, чтобы нарисовать сферу или цилиндр, надо сначала создать объект специального типа 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, а stacks – вдоль оси z.
Более подробную информацию об этих и других командах построения примитивов можно найти в приложении.
ПРИМЕЧАНИЕ
Для корректного построения перечисленных примитивов необходимо удалять невидимые линии и поверхности, для чего надо включить соответствующий режим вызовом команды glEnable(GL_DEPTH_TEST).
Массивы вершин
Если вершин много, то чтобы не вызывать для каждой команду 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 NormalPointer(GLenum type, GLsizei stride, void *pointer)
void ColorPointer(GLint size, GLenum type, GLsizei stride, 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..(:) c соответствующими параметрами. Однако вместо нее обычно вызывается команда
void glDrawArrays(GLenum mode, GLint first, GLsizei count)
рисующая count примитивов, определяемых параметром mode , используя элементы из массивов с индексами от first до first + count –1. Это эквивалентно вызову команды glArrayElement() с соответствующими индексами.
В случае если одна вершина входит в несколько примитивов, то вместо дублирования ее координат в массиве удобно использовать ее индекс.
Для этого надо вызвать команду
void glDrawArrays(GLenum mode, GLsizei count, GLenum type, void *indices)
где indices – это массив номеров вершин, которые надо использовать для построения примитивов, type определяет тип элементов этого массива: GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, а count задает их количество.
ПРИМЕЧАНИЕ
Использование массивов вершин позволяет повысить скорость визуализации трехмерной сцены
Списки отображения
Если нужно несколько раз обращаться к одной и той же группе команд, эти команды можно объединить в так называемый список изображений (display list) и вызывать его при необходимости. Для того чтобы создать новый список изображений надо поместить все команды, которые должны в него войти между командными скобками:
void glNewList(GLuint list, GLenum mode)
void glEndList()
Для различения списков используются целые положительные числа, задаваемые при создании списка значением параметра list , а параметр mode определяет режим обработки команд, входящих в список:
GL_COMPILE |
команды записываются в список без выполнения |
GL_COMPILE_AND_EXECUTE |
команды сначала выполняются, а затем записываются в список |
После того, как список создан, его можно вызвать командой
Читать дальше