Рейтинговые книги
Читем онлайн Программирование на Visual C++. Архив рассылки - Алекс Jenter

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 143 144 145 146 147 148 149 150 151 ... 156

Рис. 1

ПРИМЕЧАНИЕ

Использование GL_TRIANGLE_STRIP и GL_TRIANGLE_FAN позволяет повысить производительность приложения.

Например, чтобы нарисовать треугольник с разными цветами в вершинах, достаточно написать:

GLfloat BlueCol[3] = {0,0,1};

glBegin(GL_TRIANGLE);

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();

Кроме задания самих примитивов можно определить метод их отображения на экране (под примитивами в данном случае понимаются многоугольники).

Однако сначала надо определить понятие лицевых и обратных граней.

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

void glFrontFace(GLenum mode)

со значением параметра mode равным GL_CW, а отменить — с GL_CCW.

Чтобы изменить метод отображения многоугольника используется команда

void glPolygonMode(GLenum face, Glenum mode)

Параметр 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)

Вызов с параметром 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 команды сначала выполняются, а затем записываются в список

После того, как список создан, его можно вызвать командой

void glCallList(GLuint list)

указав в параметре list идентификатор нужного списка. Чтобы вызвать сразу несколько списков, можно воспользоваться командой

void glCallLists(GLsizei n, GLenum type, const GLvoid *lists)

вызывающей n списков с идентификаторами из массива 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.

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

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

Работа с матрицами

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

1 ... 143 144 145 146 147 148 149 150 151 ... 156
На этой странице вы можете бесплатно читать книгу Программирование на Visual C++. Архив рассылки - Алекс Jenter бесплатно.
Похожие на Программирование на Visual C++. Архив рассылки - Алекс Jenter книги

Оставить комментарий