Отчет по практике: Трехмерная графика OpenGL

Кафедра: Информационные технологии

Трехмерная графика OpenGL

1. Теоретическая часть

1.1 Подключение графической библиотеки OpenGL к интерфейсу Windows

Стандарт реализации OpenGL для Windows требует выполнения некоторых настроек, связанных с особенностями операционной системы. Для того чтобы оконная система могла работать с OpenGL, необходимо провести ее инициализацию и сконфигурировать буфер фрейма.

Система OpenGL, как и любое другое приложение Windows, нуждается в ссылке на окно, на котором будет осуществляться воспроизведение. Ссылка на контекст воспроизведения – величина типа HGLRC (Handle to OpenGL Rendering Context) – связывает OpenGL с оконными системами Windows.

Для получения этого контекста OpenGL нуждается в величине типа HDC (контекст устройства) окна, на который будет осуществляться вывод.

Таким образом, чтобы начать работать с командами OpenGL, приложение должно создать один или несколько контекстов воспроизведения для потока, и сделать текущим один из них. Каждый поток при этом может иметь один и только один текущий контекст воспроизведения, который ассоциирован с определённым контекстом устройства.

Прежде чем получить контекст воспроизведения, сервер OpenGL должен получить детальные характеристики используемого оборудования. Эти характеристики хранятся в специальной структуре, тип которой TPixelFormatDescriptor (описание формата пикселей). Формат пикселей определяет число бит на пиксел, конфигурацию буфера цвета и вспомогательных буферов используемых для вывода изображения.

Для установки формата пикселей необходимо написать соответствующую процедуру, типичный пример которой приведён в приложении 2.

Для работы с контекстом воспроизведения в Win32 API реализованы следующие функции.

wglCreateContext(dc);

Функция создаёт контекст воспроизведения OpenGL, который подходит для рисования на устройстве, определённом дескриптором dc. При успешном завершении функция возвращает дескриптор созданного контекста воспроизведения OpenGL, и NULL – в случае неудачи.

Текущий контекст воспроизведения потока должен быть единственным. Следующая функция позволяет определить контекст воспроизведения для контекста устройства.

wglMakeCurrent (dc, hrc);

При завершении работы, необходимо, чтобы контекст никем не использовался. Для этого достаточно выполнить вызов функции:

wglMakeCurrent (0,0);

Завершая работу с OpenGL необходимо удалить контекст воспроизведения. Для этой цели используется функция:

wglDeleteContext(hrc);

После того как удалён контекст воспроизведения, следует удалить и ассоциированный с ним контекст устройства.

Структуру приложения, использующего OpenGL, можно изобразить в виде схемы (рис. 1)

1.2 Синтаксис команд OpenGL

Для того чтобы команды OpenGL были доступны в проекте, необходимо указать библиотеку в списке используемых модулей.

Все команды начинаются с префикса gl, затем идёт имя команды, цифра и суффикс. Цифра в окончании соответствует количеству аргументов, буква показывает требуемый тип аргумента.

Если имя команды заканчивается на v (векторная форма), то аргументом её служит указатель на массив значений.

Например: Если последние три символа в имени команды 3fv, то её аргумент – адрес массива трёх вещественных чисел.

В общем виде команду можно представить:

glCommandName {1,2,3,4} {b, s, i, f, d, ub, us, ui} {v} (arguments)

Таблица 1.1. Возможные типы аргументов

Символ

Обозначение типа в OpenGL

Расшифровка

b

GLbyte

Байтовый

s

GLshort

Короткий целый

i

GLint

Целый

d

GLdouble

Вещественный двойной точности

f

GLfloat

Вещественный

ub

GLubyte

Байтовый, беззнаковый

us

GLushort

Короткий целый, беззнаковый

ui

GLuint

Целый, беззнаковый

Почти всегда предпочтительно использовать команду в вещественной форме, поскольку хранит данные OpenGL именно в вещественном формате.

1.3 Рисование примитивов

Процедура рисования заключается в командные скобки

glBegin(mode)

… // команды, указывающие вершины фигуры

glEnd;

Главное назначение командных скобок – это задание режима, определяющего как соединять точки (вершины). Вершины задаются своими координатами (количество координат зависит от пространства изображения) с помощью команд glVertex {2,3,4} {s, i, f, d} (arg).

Режим ( mode ), задающий правило соединения точек, определяет примитив. К примитивам относятся точки, линии, связанные линии, замкнутые линии, треугольники, связанные треугольники, четырёхугольники, связанные четырёхугольники и многоугольники.

Пример: задание стороны куба

glBegin (GL_POLYGON);

glNormal3f (0.0, 0.0, 1.0);

glVertex3f (1.0, 1.0, 1.0);

glVertex3f (-1.0, 1.0, 1.0);

glVertex3f (-1.0, -1.0, 1.0);

glVertex3f (1.0, -1.0, 1.0);

glEnd;

Таблица 1.2. Значение параметра mode

mode

Описание

GL_POINTS

Каждый вызов glVertex задает отдельную точку. Рисует N точек

GL_LINES

Каждая пара вершин задает отрезок. Рисует N/2 линий

GL_LINE_STRIP

Рисуется ломанная. Элементы n и n+1 определяют отрезок n. рисуется N – 1 отрезков

GL_LINE_LOOP

Рисуется ломанная, причем ее последняя точка соединяется с первой. элементы n и n+1 определяют отрезок n. последняя линия определяется элементом N и 1. рисуется N отрезков

GL_TRIANGLES

Каждые три вызова glVertex задают треугольник. элементы 3n – 2, 3n‑1, и 3n определяют треугольник n. Рисуется N/3 треугольников.

GL_TRIANGLE_STRIP

Рисуются треугольники с общей стороной. Для нечетного n, элементы n, n+1, n+2 определяют треугольник n. Для нечетного n элементы n+1, n, n+2 определяют треугольник n. Рисуется N‑1 треугольников.

GL_TRIANGLE_FAN

Рисует группу соединенных треугольников. Один треугольник определяется для каждого элемента после двух предыдущих. Два последних элемента соединяются с первым. рисуется N – 2 треугольников.

GL_QUADS

Каждые четыре вызова glVertex задают четырехугольник. рисуется N/4 четырехугольника.

GL_QUAD_STRIP

Четырехугольники с общей стороной. соединяя чётные элементы с чётными, а нечётные с нечётными.

GL_POLYGON

Полигон. Элементы с 1 по N определяют этот полигон.

(при этом точки полигона сортируются так, чтобы грани у получившегося многоугольника не пересекались)

1.4 Визуализация сцены

Для создания сцены необходимо задать область вывода объектов и задать способ проецирования.

Если область вывода не задана явно, то в OpenGL используется установленная по умолчанию зона в виде куба видимости 2x2x2 с началом координат в центре куба (рис. 2).

Рис. 2. Вид системы координат Oxyz

Система координат в OpenGL Oxyz (рис. 2) расположена таким образом, что ось Oz направлена в сторону противоположную направления зрения. Окно видимости (Windows) масштабируется в пределах [-1; 1] по осям Ox, Oy. Изображение по умолчанию воспроизводится на плоскости z=0.

Существует два типа проецирования: параллельная проекция и перспективная. Ортогональная проекция – это частный случай параллельной проекции, при которой проецирующие лучи ортогональны картинной плоскости.

При ортогональном проецировании точка (x, y, z) на объекте проецируется в точку (x, y, 0) на плоскости проекции. В OpenGL ортогональная проекция, характеризуемая параллелепипедом видимости, задаётся функцией glOrtho(), объявленной следующим образом:

glOrtho (left, right, bottom, top, near, far)

Таким образом, видны все объекты, которые попали внутрь параллелепипеда видимости.

При проецировании, преобразование координат включает в себя этапы, изображённые на рис. 3. Сначала мировые координаты (система координат, в которой определяется положение объекта, положение точки наблюдения и экрана) преобразовываются в видовые координаты. При этом точки изображения остаются на своих местах, но система мировых координат переходит в систему видовых координат. Затем выполняется перспективное преобразование, добавляющее эффект перспективы в зависимости от расстояния от объекта до экрана и расстояние от точки наблюдения до экрана. Система трёхмерных видовых координат переходит в систему двухмерных экранных координат. При построении параллельной проекции перспективное преобразование не выполняется, и видовые координаты используются в качестве экранных координат (X, Y).



Рис. 3. Схема преобразования координат

1.5 Видовые преобразования

Видовые преобразования осуществляются с помощью матричных преобразований. В OpenGL текущая матрица преобразований является произведением двух матриц – матрицы модели и матрицы проецирования, при этом формируется единая матрица преобразования, которая применяется ко всем вершинам всех геометрических объектов.

Матрица модели – glMatrixMode (GL_MODELVIEW) связана с координатами объектов. Это матрица в базисе видовых координат, она используется для построения картинки в том виде как её видит наблюдатель.

Матрица проецирования – glMatrixMode (GL_PROJECTION). Матрица в системе координат устройства. Вычисляет нормализованные координаты, которые преобразуются в экранные после трансформаций, связанных с областью вывода.

Команда glLoadIdentity заменяет текущую матрицуединичной матрицей (матрицей с единицами по главной диагонали и равными нулю всеми остальными элементами).


1.6 Аффинные преобразования

1.6.1 Масштабирование

Преобразование масштабирования увеличивает или уменьшает размеры объекта.

Команда масштабирования glScale (arg1, arg2, arg3) с тремя аргументами – коэффициентами масштабирования по каждой из осей.

Если масштабные множители больше единицы объект растягивается в заданном направлении, если меньше объект сжимается. Масштабные множители могут иметь отрицательные значения, при этом изображение переворачивается по соответствующей оси. При двумерных построениях значение коэффициента по оси Z игнорируется.

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

1.6.2 Поворот

Для поворота изображения используется команда

glRotate (arg1, arg2, arg3, arg4)

с четырьмя аргументами:

arg1 – угол поворота (в градусах),

arg2, arg3, arg4 – вектор поворота.

1.6.3 Сдвиг

Преобразование сдвига смещает точки в новые позиции в соответствии с заданным вектором смещения. Перенос системы координат осуществляется командой

glTranslate (arg1, arg2, arg3)

arg1, arg2, arg3 – величины переноса по каждой из осей.

Для поворота вокруг произвольной фиксированной точки сначала нужно выполнить преобразование сдвига, совмещающую заданную фиксированную точку с началом координат, потом выполнить преобразование поворота вокруг начала координат, а затем обратное преобразование сдвига. Порядок манипуляции с системой координат: вначале перенос, затем поворот, по окончании рисования – в обратном порядке: поворот, затем перенос.

1.7 Закрашивание объектов сцены

В трёхмерном пространстве поверхность объектов характеризуется материалом. Материал может отражать, поглощать и пропускать свет различной длины волн. В зависимости от характеристик материала и от свойств источника света мы видим объекты различными. Свойства материала задаются с помощью команды glMaterialfv(). Характеристики свойств материала, определяют соответствующие им символьные константы, которые представлены в таблице 1.3.

Таблица 1.3. Характеристики свойств материала

GL_AMBIENT

рассеянный свет

GL_DIFFUSE

Параметр, указывающий насколько сильно этот цвет отражается поверхностью при её освещении

GL_EMISSION

излучаемый свет

GL_SHININESS

степень отраженного света

Зеркальный цвет задаёт цветовую гамму бликов материала, степень зеркального отражения определяет, насколько близка поверхность к идеальному зеркалу (определяется числом из интервала [0,128]).

Свойства материала задаются для внешней и внутренней стороны фигуры.

glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE,@MaterialFront);

glMaterialfv (GL_BACK, GL_AMBIENT_AND_DIFFUSE,@MaterialBack);

Существует несколько режимов рисования многоугольников.

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

glPolygonMode (GLenum face, Glenum mode)

Параметр mode определяет, как будут отображаться многоугольники, а параметр face устанавливает тип многоугольников, к которым будет применяться эта команда и могут принимать следующие значения:

Таблица 1.4. Значения параметров face и mode

GLenum face

GL_FRONT

для лицевых граней

GL_BACK

для обратных граней

GL_FRONT_AND_BACK

для всех граней

Glenum mode

GL_POINT

Отображаются вершины многоугольников

GL_LINE

представляется набором отрезков

GL_FILL

закрашиваются текущим цветом с учетом освещения и этот режим установлен по умолчанию.

Пример:

GlPolygonMode (GL_FRONT, GL_POINT);

GlPolygonMode (GL_ BACK, GL_LINE);

GlPolygonMode (GL_FRONT_AND_BACK, GL_FILL);

1.8 Источники света

Без источника света изображения не видно. По умолчанию освещение отключено. Что бы инициализировать источник, и включить обработчик расчёта воздействия источника на объекты достаточно выполнить команды:

glEnable (gl_lighting);

glEnable (gl_light0);

Источник света по умолчанию располагается в пространстве с координатами (0,0,¥ ), можно создавать источник света в любой точке пространства изображений.

Параметры источника света задаются с помощью команды,

glLightfv (source, parameter, pointer_to_array).

Первый параметр команды – идентификатор источника

Второй аргумент – символическая константа, задающая атрибут

Третий – ссылка на структуру, содержащую задаваемые значения для данного атрибута.

Таблица 1.5. Константы, задающие свойства окружающей среды и позицию источника света

GL_Position

задаёт позицию источника света, источник света не перемещается за системой координат (x, y, z, cos J)

GL_AMBIENT

рассеянный свет

GL_DIFFUSE

Параметр, указывающий насколько сильно этот цвет отражается поверхностью при её освещении

GL_SPECULAR

отраженный свет

GL_EMISSION

излучаемый свет

GL_SHININESS

степень отраженного света

GL_AMBIENT_AND_DIFFUSE

задаёт поглощение цвета поверхностью в рассеивающей составляющей

GL_SPOT_direction

направление света (x, y, z)

GL_SPOT_Cutoff

задаёт максимальный угол излучения источника света [0,90] и 180.


Для того чтобы внутренняя сторона объекта была видна необходимо включить освещенность для внутренней стороны многоугольника. Световая модель с освещением внутренней части многоугольника включается или выключается соответствующей функцией

glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, 1).

Второй аргумент 0 или 1 (вкл. или выкл.).

1.9 Наложение текстуры

Создание текстуры в памяти

После того как образ подготовлен, можно создавать текстуру в памяти. Для этого в OpenGL предусмотрены две команды: одна для одномерного и вторая для двумерного вариантов образа (обе работают только в режиме RGBA).

glTexlmage1D (void glTexlmage2D (

GLenum target, GLenum target,

GLint level, GLint level,

GLint components, GLint components,

GLsizei width, GLsizei width,

GLint border, GLsizei height,

GLenum format, GLint border,

GLenum type, GLenum format,

const GLvoid* pixels) GLenum type,

const GLvoid* pixels)

При создании текстуры можно определить несколько образов с различным разрешением. Если текстура имеет размер 2n x2m, то можно определить max {n, m} + 1 уменьшенных массивов. Первый имеет размер 2n x2m, второй – 2n-1 x2m-1, и т.д., пока последний не будет иметь размер 1x1. Команды glTexImage * D предоставляют возможность определить р = max {n, m} таких массивов, в каждом из которых хранится уменьшенный образ исходного изображения. Наличие таких массивов позволит OpenGL использовать меньший образ для меньшего объекта, а больший для большего. Другими словами, чем меньше объект, тем меньше его деталей удается рассмотреть.

Параметры текстуры

Один элемент на экране может покрывать несколько элементов массива образа, и, чтобы избежать проблем, связанных с лестничным эффектом, необходимо учитывать все затрагивающие этот массив элементы.

Для этого определяются четыре точки в массиве образа, которые отображаются в четыре угла элемента на экране. Эти точки соединяются, и образуется четырехугольник. Значения попадающих в него элементов взвешиваются с учетом доли каждого элемента, содержащейся в многоугольнике, и затем суммируются.

Для учета особенностей текстуры необходимо настроить параметры текстуры, что можно сделать с помощью команды

glTexParameter [i ,f, v ] (target, pname, param)

target определяет, с какой текстурой предполагается работать, – одномерной или двумерной

pname определяет символическое имя параметра текстуры:

ра r ат определяет значение для параметра рпа me

1.10 Использование дополнительных библиотек

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

Библиотека GLU

Библиотека GLU уже стала стандартом и поставляется вместе с главной библиотекой OpenGL. В состав этой библиотеки вошли более сложные функции, например для того чтобы определить цилиндр или диск потребуется всего одна команда. Также в библиотеку вошли функции для работы со сплайнами, реализованы дополнительные операции над матрицами и дополнительные виды проекций.

Библиотека GLUT

Это независимая от платформы библиотека. Она реализует не только дополнительные функции OpenGL, но и предоставляет функции для работы с окнами, клавиатурой и мышкой. Для того чтобы работать с OpenGL в конкретной операционной системе, надо провести некоторую предварительную настройку и эта предварительная настройка зависит от конкретной операционной системы. С библиотекой GLUT всё намного упрощается, буквально несколькими командами можно определить окно, в котором будет работать OpenGL, определить прерывание от клавиатуры или мышки и всё это не будет зависеть от операционной системы.

Библиотека предоставляет функции, с помощью которых можно определять сложные правильные многогранники: куб, сфера, тор, конус, тетраэдр и додекаэдр, и даже можно с помощью одной команды определить сложный объект, типа чайник. Например, для воспроизведения куба достаточно выполнить команду: glutSolidCube(N), где N‑задаёт величину стороны грани куба. Перечень возможных функций приведен в приложении 3.

2. Практическая часть

2.1 Моделирование двумерных графических объектов и анимации с использованием графического стандарта OpenGL

Создать двумерную сцену. Изобразить две синусоиды в декартовой системе координат, используя примитивы OpenGL. Задать вращение в плоскости экрана вокруг произвольно выбранного центра таким образом, чтобы разные синусоиды имели различные скорости вращения.

2.2 Моделирование трёхмерных графических объектов и источников света с использованием OpenGL

Создать трёхмерную сцену. Пользуясь графическими объектами библиотеки GLUT (шар, конус, куб, тор, чайник и т.д.), создать в пространстве графические образы. Для элементов, из которых собраны объекты, задать различные свойства материала и различные режимы воспроизведения полигонов (точками, линиями, сплошное заполнение).

Расположить в произвольных точках пространства несколько источников света. Задать характеристики источникам света: один источник должен быть точечный, один направленный (типа «прожектор»). Цвет источников подбирается из эстетических соображений.

Задать движение каким-либо объектам сцены. Движение желательно описывать некоторым периодическим законом, чтобы перемещение объектов носило циклический характер и не требовало перезапуска программы для демонстрации.

Библиографический список

1. Эйнджел Эдвард. Интерактивная компьютерная графика. Вводный курс на базе OpenGL, 2 изд.: Пер. с англ. – М.: Издательский дом «Вильямс», 2001.–592 с.: ил.

2. Ву Мейсон, Нейдер Джеки, Девис Том, Шрайнер Дейв. OpenGL. Официальное руководство программиста: Пер. с англ. СПб: ООО «ДиаСофтЮП», 2002. – 592 с.

3. Тихомиров Ю. Программирование трёхмерной графики – СПб.:BHV – Санкт-Петербург, 1998. – 256 с., ил.

4. Краснов М. OpenGL. Графика в проектах Delphi.–СПб.: БХВ – Санкт-Петербург, 2000.–352 с.: ил.

5. Роджерс Д. Алгоритмические основы машинной графики: Пер. с англ. – М.: Мир, 1989. – 512 с., ил

еще рефераты
Еще работы по информатике