Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2633

.pdf
Скачиваний:
6
Добавлен:
07.01.2021
Размер:
54.26 Mб
Скачать

Е.Ю. Андиева

КОМПЬЮТЕРНАЯ

ГРАФИКА:

ПРОГРАММИРОВАНИЕ

C ИСПОЛЬЗОВАНИЕМ

OPENGL

Омск • 2012

3

Министерство образования и науки РФ Федеральное государственное бюджетное образовательное

учреждение высшего профессионального образования «Сибирская государственная автомобильно-дорожная академия (СибАДИ)»

Е. Ю. Андиева

КОМПЬЮТЕРНАЯ ГРАФИКА:

ПРОГРАММИРОВАНИЕ

С ИСПОЛЬЗОВАНИЕМ OPENGL

Учебное пособие

Омск

СибАДИ

2012

4

УДК 004. 92

ББК 73

А65

Рецензенты:

д-р техн. наук, проф. кафедры КИАС С.Н. Чуканов (Сибирская автомобильно-дорожная академия); канд. техн. наук, доцент кафедры ИБ И.И. Семенова (Сибирская автомобильно-дорожная академия);

Работа одобрена редакционно-издательским советом академии в качестве учебного пособия.

Андиева Е.Ю.

А65 Компьютерная графика: программирование с использованием

OpenGL: учебное пособие / Е.Ю. Андиева Омск: СибАДИ, 2012. 208 с.

Учебное пособие содержит теоретический материал с примерами и подробными пояснениями, а так же темы курсового проекта и краткие методические указания к его выполнению. Учебное пособие рекомендовано для изучения дисциплины «Компьютерная графика» в учебном процессе для специальностей и направлений: 230100, 230277, 080801, 090100, 090900, 090300.

Табл. 1 . Ил. 36 . Библиогр.: 14 назв.

ФГБОУ ВПО «СибАДИ»,

2012

5

Введение

История OpenGL ведется с 1992 года. Компания Silicon Graphics создала его как открытый стандарт. Отсюда и первая часть названия, а GL означает Graphic Library (графическая библиотека). На данный момент OpenGL находится под контролем комитета Architectural Review Board (ARB), куда входят представители наиболее влиятельных в 3D-секторе корпораций – nVidia, ATI, SGI, Apple, Intel, id Software.

OpenGL разработан как аппаратно-независимый интерфейс для работы на различных аппаратных платформах.

Эффективные реализации OpenGL существуют для Windows, Unix-платформ, PlayStation 3 и Mac OS. Эти реализации обычно предоставляются изготовителями видеоадаптеров и активно используют возможности последних. Спецификация OpenGL

пересматривается Консорциумом ARB (Architecture Review Board),

который был сформирован в 1992 году. Консорциум состоит из компаний, заинтересованных в создании широко распространённого и доступного API. Согласно официальному сайту OpenGL, членами ARB с решающим голосом на ноябрь 2004 года являются производители профессиональных графических аппаратных средств

SGI, 3Dlabs, Matrox и Evans & Sutherland (военные приложения),

производители потребительских графических аппаратных средств ATI и NVIDIA, производитель процессоров Intel, и изготовители компьютеров и компьютерного оборудования IBM, Apple, Dell, Hewlett-Packard и Sun Microsystems, а также один из лидеров компьютерной игровой индустрии id Software. Microsoft, один из основоположников Консорциума, покинула его в марте 2003 года. Помимо постоянных членов, каждый год приглашается большое количество других компаний, становящихся частью OpenGL ARB в течение одного года. Такое большое число компаний, вовлеченных в разнообразный круг интересов, позволило OpenGL стать прикладным интерфейсом широкого назначения с большим количеством возможностей.

Авторами оригинальной спецификации являются: OpenGL.Курт Экли (Kurt Akeley) и Марк Сигал (Mark Segal).

11 марта 2010 года Khronos Group представила финальный вариант спецификации OpenGL 4.0 и языка описания шейдеров

6

GLSL4.0. OpenGL 4.0 полностью обратно совместим со старыми расширениями OpenGL, используя режим совместимости введенный в OpenGL 3.2.

8 августа 2011 года Khronos Group опубликовала актуальную спецификацию OpenGL 4.2 и языка шейдеров GLSL 4.2

OpenGL, создавался для профессионального сектора и прочно в нем закрепился. На платформе Windows конкурирует с Direct3D.

Иначе, можно сказать, что OpenGL является программным интерфейсом к графическому оборудованию. Этот интерфейс содержит порядка 250 отдельных команд (около 200 в ядре OpenGL и еще 50 в библиотеке OpenGL Utility Library), которые используются для задания объектов и операций, необходимых для создания интерактивных приложений трехмерной графики.

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

Задача OpenGL – дать возможность создать модель из небольшого набора графических примитивов: точек, линий и многоугольников, то есть основным принципом работы OpenGL является получение наборов векторных графических примитивов в виде точек, линий и многоугольников с последующей математической обработкой полученных данных и построением растровой картинки на экране и/или в памяти. Векторные трансформации и растеризация выполняются графическим конвейером (graphics pipeline), который по сути представляет собой дискретный автомат. Абсолютное большинство команд OpenGL попадают в одну из двух групп: либо они добавляют графические примитивы на вход в конвейер, либо конфигурируют конвейер на различное исполнение трансформаций.

Высокоуровневые средства предоставляются библиотеками, являющимися надстройками над OpenGL. Для моделирования кривых и поверхностей предназначена библиотека GLU (OpenGL Utility Library), имеющая множество инструментов, таких как вычислители и NURBS. Библиотека GLU является стандартной составляющей любой реализации OpenGL.

7

I.РАБОТА С OPENGL

1.1.Основные понятия OpenGL

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

Сначала следует определить следующие основные термины:

­рендеринг (rendering) – отображение, иначе воспроизведение изображения на экран на основе моделей из графических примитивов – точек, линий и многоугольников, определяемых вершинами (vertices);

­пиксель (pixel) – минимальный элемент изображения, и информация о пикселях хранится в битовых плоскостях;

­битовая плоскость (bitplane) – область памяти, в которой каждому пикселю соответствует один бит информации. Бит, например, может определять составляющую цвета. В свою очередь, битовые плоскости образуют видеобуфер (буфер кадров), который хранит всю информацию, необходимую графическому дисплею для управления цветом и яркостью всех пикселей на экране.

Окончательное прорисованное изображение состоит из пикселей на экране.

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

Константы в OpenGL начинаются с GL_ ,и записываются прописными буквами, а отдельные слова в них выделяются подчеркиванием, например: GL_COLOR_BUFFER_BIT).

К некоторым именам команд добавляются суффиксы (например, 3f, как в glColor3f () и glVertex3f ()).

Как уже отмечалось, все команды OpenGL начинаются с префикса gl, все константы также начинаются с префикса GL_ .

Например, в команде glColor3f() (Color в имени определяет команду, которая устанавливает текущий цвет) цифра 3 говорит о том, что координат 3, а префикс 'f' говорит о том, что аргумент имеет тип floating-point .

В OpenGL имеется 8 сновных типов Data Type:

­8-bit integer;

­16-bit integer;

­32-bit integer;

8

­32-bit floating-point;

­64-bit floating-point;

­8-bit unsigned integer;

­16-bit unsigned integer;

­32-bit unsigned integer.

Так, две команды glVertex2i(1, 3) и glVertex2f(1.0, 3.0) фактически эквивалентны, но имеют различные типы.

Функции glGetBooleanv(), glGetDoublev(), glGetFloatv(), glGetIntegerv(), glGetPointerv(), glIsEnabled() – устанавливают тип данных.

Некоторые команды имееют последним символом 'v' , что указывает на вектор, определяет массив и дает векторный указатель на него. Доступ к этому массиву определяется с помощью часто употребляемой команды GLvoid(), например:

glColor3f(1.0, 0.0, 0.0);

GLfloat color_array[] = {1.0, 0.0, 0.0}; glColor3fv(color_array);

Как только установлен цвет с помощью glColor3f(), все последующие обьекты будут выводиться именно установленным цветом.

Доступ к переменным можно осуществить с помощью glEnable()

или glDisable().

Функции glPushAttrib() и glPushClientAttrib() пишут в стек, glPopAttrib() и glPopClientAttrib() восстанавливают.

OpenGL очень четко организован в смысле очередности выполнения операций.

Существуют три типа основных графических операций: очистка экрана, рисование геометрических обьектов, рисование растеризованных обьектов (текстур). Например: очистка RGBA mode window в черный цвет:

glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT);

В OpenGL определены такие буферы, как:

Color buffer – буфер цвета;

Depth buffer (Z-buffer) – буфер глубины – двумерный массив данных, дополняющий двумерное изображение, где для каждого пикселя (фрагмента) изображения сопоставляется «глубина» (расстояние от наблюдателя до поверхности изображаемого объекта);

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

9

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

Accumulation buffer – буфер накопления – это дополнительный внутренний буфер OpenGL, в котором можно сохранять визуализированное изображение, применяя при этом попиксельно специальные операции;

Frame buffer – буфер кадра - участок видеопамяти, в котором производится работа по формированию изображения (Обычно используются два (реже три) буфера кадра: один (передний, или frontbuffer) отображается на экране, а во второй (задний, или back-buffer) выполняется рендеринг. Как только очередной кадр изображения будет готов, они поменяются ролями: второй буфер будет показан на экране, а первый перерисован заново);

Index Buffer – буфер индексов – буфер, определяющий порядок следования вершин при построении геометрии. Индексный буфер представляет собой массив индексов — «номеров» вершин в вершинном буфере.

1.2. Графические примитивы OpenGL

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

Точка (point) представляется набором вещественных чисел, называемых вершиной. Все внутренние вычисления выполняются для трехмерных вершин. Определяемые пользователем двухмерные вершины (когда заданы только координаты х и у) также являются трехмерными, но с координатой г, равной 0.

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

Полигон (polygon), иначе многоугольник – площадь, ограниченная одиночным замкнутым контуром, состоящим из отрезков, определяемых вершинами их концов. Обычно полигоны рисуются с закрашенными внутри пикселями, но можно также их рисовать

10

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

OpenGL работает в так называемых гомогенных (приведенных) координатах, поэтому у точки имеется четвернтый дополнительный параметр – (x, y, z, w). Если w не равно нулю, фактически имеем дело с координатой (x/w, y/w, z/w).

Таким образом, под вершиной понимается точка в трехмерном пространстве, координаты которой задаются следующим образом:

void glVertex[2 3 4][s i f d](type coords); void glVertex[2 3 4][s i f d]v(type *coords);

и координаты точки задаются максимум четырьмя значениями: x, y, z, w, при этом можно указывать два (x,y) или три (x,y,z) значения, а для остальных переменных в этих случаях используются значения по умолчанию: z=0, w=1. Как уже было сказано выше, число в названии команды соответствует числу явно задаваемых значений, а последующий символ – их типу.

Координатные оси расположены так, что точка (0,0) находится в левом нижнем углу экрана, ось x направлена влево, ось y- вверх, а ось z- из экрана. Это расположение осей мировой системы координат, в которой задаются координаты вершин объекта.

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

void glBegin(GLenum mode); void glEnd(void);

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

­GL_POINTS каждая вершина задает координаты некоторой

точки;

­GL_LINES каждая отдельная пара вершин определяет отрезок; если задано нечетное число вершин, то последняя вершина игнорируется;

­GL_LINE_STRIP каждая следующая вершина задает отрезок вместе с предыдущей;

­GL_LINE_LOOP отличие от предыдущего примитива только в том, что последний отрезок определяется последней и первой вершиной, образуя замкнутую ломаную;

11

­GL_TRIANGLES каждая отдельная тройка вершин определяет треугольник; если задано не кратное трем число вершин, то последние вершины игнорируются;

­GL_TRIANGLE_STRIP каждая следующая вершина задает треугольник вместе с двумя предыдущими;

­GL_TRIANGLE_FAN треугольники задаются первой и каждой следующей парой вершин (пары не пересекаются);

­GL_QUADS каждая отдельная четверка вершин определяет четырехугольник; если задано не кратное четырем число вершин, то последние вершины игнорируются;

­GL_QUAD_STRIP четырехугольник с номером n определяется вершинами с номерами 2n-1, 2n, 2n+2, 2n+1;

­GL_POLYGON последовательно задаются вершины выпуклого многоугольника.

Таким образом, все геометрические обьекты – примитивы определяются в OpenGL с помощью набора вершин. Вершина задается командой glVertex*(), например:

glVertex2s(2, 3);

glVertex3d(0.0, 0.0, 3.1415926535898); glVertex4f(2.3, 1.0, -2.2, 2.0); GLdouble dvect[3] = {5.0, 9.0, 1992.0}; glVertex3dv(dvect);

Все эти команды представляют 3-мерные вершины в различных форматах.

Аналогично прорисовывается, например, полигон из пяти вершин: glBegin(GL_POLYGON);

glVertex2f(0.0, 0.0); glVertex2f(0.0, 3.0); glVertex2f(4.0, 3.0); glVertex2f(6.0, 1.5); glVertex2f(4.0, 0.0); glEnd();

Корректно работают в цикле glBegin()... glEnd() следующие команды:

glVertex*()

glColor*()

glIndex*()

glNormal*()

glTexCoord*()

glEdgeFlag*()

glMaterial*()

glArrayElement()

12

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]