ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 09.06.2020
Просмотров: 1700
Скачиваний: 4
26
Как
правило
,
разные
типы
примитивов
имеют
различную
скорость
визуализации
на
разных
платформах
.
Для
увеличения
производительности
предпочтительнее
использовать
примитивы
,
требующие
меньшее
количество
информации
для
передачи
на
сервер
,
такие
как
GL_TRIANGLE_STRIP
,
GL_QUAD_STRIP
,
GL_TRIAGLE_FAN.
Кроме
задания
самих
многоугольников
,
можно
определить
метод
их
отображения
на
экране
.
Однако
сначала
надо
определить
понятие
лицевых
и
обратных
граней
.
Под
гранью
понимается
одна
из
сторон
многоугольника
,
и
по
умолчанию
лицевой
считается
та
сторона
,
вершины
которой
обходятся
против
часовой
стрелки
.
Направление
обхода
вершин
лицевых
граней
можно
изменить
вызовом
команды
void
glFrontFace
(GLenum
mode
)
со
значением
параметра
mode
равным
GL_CW
(clockwise),
а
вернуть
значение
по
умолчанию
можно
,
указав
GL_CCW
(counter-clockwise).
Чтобы
изменить
метод
отображения
многоугольника
используется
команда
void
glPolygonMode
(GLenum
face
, Glenum
mode
)
Параметр
mode
определяет
,
как
будут
отображаться
многоугольники
,
а
параметр
face
устанавливает
тип
многоугольников
,
к
которым
будет
применяться
эта
команда
и
может
принимать
следующие
значения
:
GL_FRONT
для
лицевых
граней
GL_BACK
для
обратных
граней
GL_FRONT_AND_BACK
для
всех
граней
Параметр
mode
может
быть
равен
:
GL_POINT
отображение
только
вершин
многоугольников
.
GL_LINE
многоугольники
будут
представляться
набором
отрезков
.
27
GL_FILL
многоугольники
будут
закрашиваться
текущим
цветом
с
учетом
освещения
,
и
этот
режим
установлен
по
умолчанию
.
Также
можно
указывать
,
какой
тип
граней
отображать
на
экране
.
Для
этого
сначала
надо
установить
соответствующий
режим
вызовом
команды
glEnable
(GL_CULL_FACE)
,
а
затем
выбрать
тип
отображаемых
граней
с
помощью
команды
void
glCullFace
(GLenum
mode
)
Вызов
с
параметром
GL_FRONT
приводит
к
удалению
из
изображения
всех
лицевых
граней
,
а
с
параметром
GL_BACK
–
обратных
(
установка
по
умолчанию
).
Кроме
рассмотренных
стандартных
примитивов
в
библиотеках
GLU
и
GLUT
описаны
более
сложные
фигуры
,
такие
как
сфера
,
цилиндр
,
диск
(
в
GLU)
и
сфера
,
куб
,
конус
,
тор
,
тетраэдр
,
додекаэдр
,
икосаэдр
,
октаэдр
и
чайник
(
в
GLUT).
Автоматическое
наложение
текстуры
предусмотрено
только
для
фигур
из
библиотеки
GLU (
создание
текстур
в
OpenGL
будет
рассматриваться
в
главе
5).
Например
,
чтобы
нарисовать
сферу
или
цилиндр
,
надо
сначала
создать
объект
специального
типа
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.
Более
подробную
информацию
об
этих
и
других
командах
построения
примитивов
можно
найти
в
приложении
В
.
28
2.4.
Дисплейные
списки
Если
мы
несколько
раз
обращаемся
к
одной
и
той
же
группе
команд
,
то
их
можно
объединить
в
так
называемый
дисплейный
список
(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.
Пример
:
glNewList(1, GL_COMPILE);
29
glBegin(GL_TRIANGLES);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(10.0f, 1.0f, 1.0f);
glVertex3f(10.0f, 10.0f, 1.0f);
glEnd();
glEndList()
…
glCallList(1);
Дисплейные
списки
в
оптимальном
,
скомпилированном
виде
хранятся
в
памяти
сервера
,
что
позволяет
рисовать
примитивы
в
такой
форме
максимально
быстро
.
В
то
же
время
большие
объемы
данных
занимают
много
памяти
,
что
влечет
,
в
свою
очередь
,
падение
производительности
.
Такие
большие
объемы
(
больше
нескольких
десятков
тысяч
примитивов
)
лучше
рисовать
с
помощью
массивов
вершин
.
2.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
,
void *
pointer
)
void
glColorPointer
( GLint
size
, GLenum
type
,
GLsizei
stride
, void *
pointer
)
30
Для
того
,
чтобы
эти
массивы
можно
было
использовать
в
дальнейшем
,
надо
вызвать
команду
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
glDrawElements
(GLenum
mode
, GLsizei
count
,
GLenum
type
, void *
indices
)
где
indices
–
это
массив
номеров
вершин
,
которые
надо
использовать
для
построения
примитивов
,
type
определяет
тип
элементов
этого