04 - Программирование компьютерной графики с использованием OpenGL

0

No comments posted yet

Comments

Slide 3

Промышленный стандарт В течение многих лет экспертная комиссия по архитектуре OpenGL (OpenGL Architecture Review Board (ARB)) поддерживает данный графический API. OpenGL, оставаясь нейтральным по отношению к различным производителям графических устройств, двигается в ногу с техническим прогрессом вбирая в себя самые лучшие достижения сегодняшнего дня Крупнейшие производители графического аппаратного и программного обеспечения участвуют в развитии данного стандарта Стабильность Реализации стандарта OpenGL доступны на протяжении более 10 лет на большом количестве платформ Добавления к спецификации стандарта строго контролируются и заранее объявляются Сохраняется обратная совместимость – старые приложения, использующие OpenGL не станут устаревшими Надежность и переносимость Стандарт гарантирует получение одинакового визуального результата на различных OpenGL-совместимых платформах Современность Благодаря механизму расширений OpenGL, производители железа могут предоставлять разработчикам ПО API к самым последним из имеющихся достижений Самые лучшие из расширений в последствии могут впоследствии войти в состав Стандарта Масштабируемость Приложения OpenGL могут работать как на мобильных системах, так и на персональных ЭВМ и суперкомпьютерах Разработчики ПО могут «прицелиться» на ту или иную программно-аппаратную платформу Легкость в изучении и использовании API хорошо структурирован и легок в изучении (достаточно знать язык программирования Си) Для получения результата требует написания, как правило, меньшего количества кода, нежели при использовании других API Хорошо документирован Программированию с использованием OpenGL посвящено много книг и статей в Интернет Независим от языка программирования Для OpenGL разработаны различные привязки функций OpenGL на другиеязыки программирования

Slide 5

Ориентированность на построение изображения в буфере кадра (Frame Buffer) Библиотека OpenGL предназначена исключительно для рендеринга в буфер экрана (Frame Buffer) и для чтения значений пикселей из буфера кадра Поддержка мыши и других периферийных устройств находится вне компетенции OpenGL. Программисту приходится полагаться на другие механизмы и API получения пользовательского ввода Основное назначение OpenGL - интерактивная визуализация трехмерных моделей Наиболее ярко OpenGL проявляет свои возможности при визуализации изображений сложных 3D-сцен Унифицированный подход к построению изображений позволяет OpenGL строить и двухмерные изображения

Slide 9

Прило

Slide 12

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

Slide 14

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

Slide 15

OpenGL работает с определенными типами данных int double float Размерность этих типов данных в разных системах может варьироваться Для гарантии того, что функции OpenGL получают нужные типы данных, полезно использовать встроенные имена типов OpenGL: GLfloat GLdouble Glint

Slide 35

В ходе работы с OpenGL могут возникать ошибочные ситуации В функцию переданы неверные параметры Произошла нехватка памяти Использование команды недопустимо в данном состоянии

Slide 1

Программирование компьютерной графики с использованием OpenGL

Slide 2

Что такое OpenGL (Open Graphics Library) Широко распространенный графический API для программирования 2D и 3D графики Разработан в 1992 году фирмой Silicon Graphics Выступает в качестве стандартного и стабильного API на многих программно-аппаратных платформах Спецификация, описывающая набор функций и их точное поведение Производители оборудования создают реализации библиотеки согласно данной спецификации

Slide 3

Достоинства Промышленный стандарт Стабильность Надежность и переносимость Современность Масштабируемость Легкость в изучении и использовании Хорошо документирован Независим от языка программирования

Slide 4

Базовые возможности Рисование геометрических примитивов (точки, линии, многоугольники) Рисование сложных объектов реализуется силами программиста либо сторонними библиотеками Работа с растровыми примитивами Цветовые режимы RGBA / Index Видовые и модельные преобразования Прозрачность Удаление невидимых линий и поверхностей B-сплайны Наложение текстуры Интерполяция цветов, Anti-aliasing, туман Использование списков изображений (display lists)

Slide 5

Основы Ориентированность главным образом на построение изображения в буфере кадра (Frame Buffer) и чтение из него Основное назначение OpenGL - интерактивная визуализация трехмерных сцен

Slide 6

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

Slide 7

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

Slide 8

Пример 1 2 3

Slide 9

Команды OpenGL Взаимодействие приложения с OpenGL происходит посредством отдачи команд Команда – вызов определенной функции библиотеки Команды всегда выполняются в порядке их получения Возможна некоторая задержка между вызовом команды и отображением результата Команда glFinish() вызывает немедленное выполнение команд и дожидается завершения их выполнения Команда glFlush() вызывает немедленное выполнение команд, но не дожидается завершения их выполнения Выборка данных, необходимых для выполнения команды происходит в момент вызова команды Актуально при передаче массивов в качестве аргументов команд

Slide 10

Пример: рисование линий float x0 = 0; float y0 = 0; glBegin(GL_LINES); for (int angle = 0; angle < 360; angle += 3) { float angleInRadians = (float)(angle * M_PI / 180.0f); float x1 = cosf(angleInRadians); float y1 = sinf(angleInRadians); glVertex2f(x0, y0); glVertex2f(x1, y1); } glEnd();

Slide 11

Результат

Slide 12

Клиент-серверная интерпретация команд Приложение (Клиент) вызывает команды, обрабатываемые OpenGL (Сервер) Сетевая прозрачность Сервер может работать с несколькими различными контекстами Контекст хранит состояние OpenGL Команды в один момент времени работают с текущим контекстом Клиент может переключаться с одного контекста на другой при помощи специальных команд

Slide 13

Низкоуровневой доступ OpenGL предоставляет доступ к низкоуровневым графическим операциям Изменить режим Установить заданный параметр Нарисовать группу примитивов Описание сложных 3d и 2d-объектов и сцен – забота программиста, а не библиотеки

Slide 14

Оконная система OpenGL осуществляет графический вывод в буфер кадра Отображение буфера кадра на экране монитора не входит в обязанности OpenGL Изначально OpenGL был спроектирован как аппаратно-независимая графическая библиотека Управлением буфером кадра и его отображением на экране монитора занимается оконная система WGL – Microsoft Windows GLX – Unix/Linux GLUT – мультиплатформенная библиотека Скрывает особенности различных оконных систем за единым API (пусть даже с ограниченным функционалом)

Slide 15

Типы данных OpenGL Функции OpenGL работают с аргументами определенного типа Целые, числа с плавающей точкой Размер одного и того же типа в различных системах может варьироваться Рекомендуется использовать встроенные типы OpenGL Функции OpenGL, способные работать с несколькими типами данных имеют в составе своего имени суффиксы

Slide 16

Суффиксы команд и типы данных аргументов

Slide 18

Пример void DrawDot(GLint x, GLint y) { glBegin(GL_POINTS); glVertex2i(x, y); glEnd(); }

Slide 19

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

Slide 20

Два типа состояния OpenGL Состояние сервера С каждым контекстом OpenGL связан полный набор переменных состояния сервера К данному типу относится бОльшая часть переменных OpenGL Состояние клиента Определяется набором переменных состояния клиента Каждое соединение клиента с сервером заключает в себе полный набор переменных состояния клиента и сервера

Slide 21

Синтаксис команд OpenGL Команды OpenGL – функции или процедуры Группы команд выполняют одну операцию, однако используют разные типы и количество аргументов, например: glVertex* glColor* glTranslate*

Slide 22

Форма записи команд OpenGL Команды OpenGL имеют следующий синтаксис: rtype CommandName[1 2 3 4][b s i f d ub us ui][v] ( [args ,] T arg1 , . . . , T argN [, args] ); rtype - тип, возвращаемый функцией OpenGL CommandName - имя функции, например glVertex [1 2 3 4] – количество аргументов команды, например, разрядность координатного вектора [b s i f d ub us ui] - тип аргументов команды [v] - если присутствует, то в качестве аргумента команды выступает указатель на массив значений

Slide 23

Примеры: glVertex2f(GLfloat x, GLfloat y) glNormald(GLdouble x, GLdouble y, GLdouble z) glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) glClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) glVertex3fv(GLfloat *v) glTranslatef(GLfloat x, GLfloat y, GLfloat z) glFlush() glClear(GLbitfield mask) glScalefv(GLfloat *v)

Slide 24

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

Slide 25

Графический конвейекр OpenGL

Slide 26

Передача вершин, заданных в системе координат модели на вход графического конвейера OpenGL 1 2 3 4 5 6

Slide 27

Преобразование моделирования-вида

Slide 28

Расчет освещения и цвета вершин 2 3 4 5 6 1

Slide 29

Сборка примитивов 2 3 4 5 6 1

Slide 30

Отсечение плоскостями отсечения, задаваемыми пользователем 2 3 4 5 6 1

Slide 31

Умножение на матрицу проецирования и перспективное деление -1 +1 -1 +1 -1 -1 +1

Slide 32

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

Slide 33

Операции над фрагментами Тест принадлежности контексту рендеринга Тест «ножниц» Альфа-тест Тест трафарета Тест глубины Смешивание цветов Dithering Логические операции (для индексированных Цветов)

Slide 34

Запись значений в буфер кадра

Slide 35

Обработка ошибок В ходе работы с OpenGL могут возникать ошибочные ситуации В целях обеспечения производительности OpenGL обрабатывает только некоторое подмножество таких ситуаций Узнать о наличии ошибки позволяет функция: GLenum glGetError()

Slide 36

Коды ошибок OpenGL

Slide 37

Парадигма glBegin()/glEnd() Большинство геометрических примитивов OpenGL отображаются при помощи перечисления их вершин между «командными скобками» glBegin() и glEnd() При выполнении команды glVertex* происходит создание новой вершины внутри примитива с текущими атрибутами вершины на момент выполнения команды glVertex* Данная парадигма объявлена устаревшей из за своей низкой производительности в версии OpenGL 3.0 и более не поддерживается

Slide 39

Преобразования координат Координаты вершин, передаваемых при помощи функций glVertex* и ей подобных обычно задаются в системе координат объекта В ходе обработки вершин OpenGL выполняет последовательность обязательных преобразований каждой вершины Использование вершинных шейдеров позволяет изменить часть этапов на свои собственные

Slide 40

Матрица моделирования-вида (Model-View Matrix) OpenGL преобразовывает координаты каждой вершины из системы координат объекта в систему координат наблюдателя при помощи Матрицы моделирования-вида

Slide 41

Матрица проецирования (Projection matrix) Матрица проецирования применяется к системе координат наблюдателя, преобразуя вершины в систему координат отсечения (clip coordinates)

Slide 42

Перспективное деление Перспективное деление переводит вершину в нормализованную систему координат устройства Отображаемый объем при этом трансформируется в куб со сторонами, параллельными осям координат, располагающийся в диапазоне от -1 до +1

Slide 43

Преобразование в порт просмотра (viewport transformation) Порт просмотра – прямоугольная область окна, в которой происходит отображение видового объема сцены Преобразование в порт просмотра позволяет получить координаты вершин в оконных координатах устройства (в пикселях) Значение глубины фрагмента приводится к диапазону [0;1] (или к задаваемому пользователем)

Slide 44

Система координат frame buffer’а x y z +1 -1 -1 +1 Видовой порт Видимый объем

Slide 45

Матрицы в OpenGL OpenGL в ходе своей работы использует следующие типы матриц: Матрица моделирования/вида (ModelView matrix) Матрица проецирования (Projection matrix) Матрица текстуры (Texture matrix) Значения данных матриц могут быть заданы при помощи определенных команд OpenGL

Slide 46

Выбор текущей матрицы OpenGL в один момент времени работает только с одной текущей матрицей Для выбора текущей матрицы служит команда void glMatrixMode(GLenum mode) где mode – одно из значений GL_MODELVIEW GL_PROJECTION GL_TEXTURE

Slide 47

Загрузка и изменение текущей матрицы glLoadMatrix Заменяет текущую матрицу на определенную пользователем glMultMatrix Заменяет текущую матрицу С результатом ее умножения на матрицу M С’ = C ∙ M OpenGL хранит элементы матриц не построчно, а по столбцам:

Slide 48

Загрузка единичной матрицы glLoadIdentity() заменяет текущую матрицу на единичную

Slide 49

Применение аффинных преобразований Данные функции позволяют осуществлять аффинные преобразования в трехмерном пространстве Результатом вызова данных команд будет умножение текущей матрицы на матрицу одного из аффинных преобразований glTranslate* glScale* glRotate* В OpenGL 3.0 данные функции объявлены устаревшими

Slide 50

Матрицы проецирования Умножают текущую матрицу на матрицу проецирования glOrtho – ортографическое преобразование glFrustum – перспективное преобразование См. также: gluPerspective gluOrtho2D

Slide 51

Стек матриц Стек матриц позволяет запомнить и в последствии восстановить текущую матрицу void glPushMatrix() – запомнить текущую матрицу в стеке void glPopMatrix() – восстановить запомненную матрицу из стека Матрицы каждого типа имеют свой собственный стек определенной глубины

Slide 52

Вершины Вершины используются для задания основных примитивов OpenGL. Могут иметь размерность от 1 до 4 координат Задаются при помощи glVertex* В момент обработки команды glVertex OpenGL создает вершину с текущими атрибутами вершины

Slide 53

Нормаль Одним из атрибутов вершины в OpenGL является вектор нормали к поверхности в точке вершины Направлен перпендикулярно поверхности, проходящей через текущую вершину OpenGL использует нормали для расчета освещенности граней Текущий вектор нормали задается при помощи функций glNormal

Slide 54

Задание нормалей вершин для объекта с плоскими гранями

Slide 55

Задание нормалей вершин примитивов, аппроксимирующих криволинейную поверхность

Slide 56

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

Slide 57

Атрибуты вершин Текущий цвет вместе с условиями освещения определяет результирующий цвет вершины Текущая позиция растра (при работе с пикселями и битовыми массивами) Текущая нормаль Вектор нормали, ассоциированный с вершиной, задает ориентацию содержащей ее поверхности в трехмерном пространстве Текущие координаты текстуры Местоположение в карте текстуры (texture map), ассоциированное с вершиной В OpenGL 3.0 встроенные атрибуты вершин объявлены устаревшими

Slide 58

Рисование примитивов Примитив, или группа однотипных примитивов определяются путем объявления их вершин внутри командных скобок glBegin/glEnd void glBegin(GLenum mode) void glEnd() mode – тип примитивов glBegin(GL_TRIANGLES); glVertex2f(3.0f, 0.0f); glVertex2f(0.0f, 0.0f); glVertex2f(2.2f, 3.0f); … glEnd();

Slide 59

Типы геометрических примитивов OpenGL GL_TRIANGLE_STRIP 0 1 2 3 4 5 0 1 2 3 4 5 6 7 8 GL_POINTS 0 1 2 3 GL_LINES 0 1 2 3 0 1 2 3 4 5 0 1 2 3 4 5 0 GL_POLYGON 1 2 3 4 GL_QUADS 0 1 2 3 4 5 6 7 GL_TRIANGLE_FAN 0 1 2 3 4 5 GL_QUAD_STRIP 0 1 2 3 4 5 6 7 *Убран в версии 3.0

URL: