|
|
Промышленный стандарт В течение многих лет экспертная комиссия по архитектуре OpenGL (OpenGL Architecture Review Board (ARB)) поддерживает данный графический API. OpenGL, оставаясь нейтральным по отношению к различным производителям графических устройств, двигается в ногу с техническим прогрессом вбирая в себя самые лучшие достижения сегодняшнего дня Крупнейшие производители графического аппаратного и программного обеспечения участвуют в развитии данного стандарта Стабильность Реализации стандарта OpenGL доступны на протяжении более 10 лет на большом количестве платформ Добавления к спецификации стандарта строго контролируются и заранее объявляются Сохраняется обратная совместимость – старые приложения, использующие OpenGL не станут устаревшими Надежность и переносимость Стандарт гарантирует получение одинакового визуального результата на различных OpenGL-совместимых платформах Современность Благодаря механизму расширений OpenGL, производители железа могут предоставлять разработчикам ПО API к самым последним из имеющихся достижений Самые лучшие из расширений в последствии могут впоследствии войти в состав Стандарта Масштабируемость Приложения OpenGL могут работать как на мобильных системах, так и на персональных ЭВМ и суперкомпьютерах Разработчики ПО могут «прицелиться» на ту или иную программно-аппаратную платформу Легкость в изучении и использовании API хорошо структурирован и легок в изучении (достаточно знать язык программирования Си) Для получения результата требует написания, как правило, меньшего количества кода, нежели при использовании других API Хорошо документирован Программированию с использованием OpenGL посвящено много книг и статей в Интернет Независим от языка программирования Для OpenGL разработаны различные привязки функций OpenGL на другиеязыки программирования
Ориентированность на построение изображения в буфере кадра (Frame Buffer) Библиотека OpenGL предназначена исключительно для рендеринга в буфер экрана (Frame Buffer) и для чтения значений пикселей из буфера кадра Поддержка мыши и других периферийных устройств находится вне компетенции OpenGL. Программисту приходится полагаться на другие механизмы и API получения пользовательского ввода Основное назначение OpenGL - интерактивная визуализация трехмерных моделей Наиболее ярко OpenGL проявляет свои возможности при визуализации изображений сложных 3D-сцен Унифицированный подход к построению изображений позволяет OpenGL строить и двухмерные изображения
Прило
Приложение (Клиент) вызывает команды, обрабатываемые OpenGL (Сервер) В роли Сервера может выступать драйвер видеокарты, а может и суперкомпьютер в сети Сетевая прозрачность Сервер может быть расположен как на локальном, так и на другом компьютере в сети Работа с сервером происходит полностью прозрачно для приложения Работа с различными контекстами. Сервер может поддерживать несколько контекстов, в которых инкапсулируется состояние OpenGL. Клиент может выбрать один из контекстов на сервере (подключиться к контексту). Вызов команд при невыбранном контексте приводит к неопределенному поведению
Многие графические системы являются оконными и позволяют работать с несколькими окнами одновременно Функции OpenGL являются аппаратно независимыми, поэтому OpenGL не предоставляет никаких функций для работы с буфером кадра. Это входит в обязанность оконной системы.
OpenGL работает с определенными типами данных int double float Размерность этих типов данных в разных системах может варьироваться Для гарантии того, что функции OpenGL получают нужные типы данных, полезно использовать встроенные имена типов OpenGL: GLfloat GLdouble Glint
В ходе работы с OpenGL могут возникать ошибочные ситуации В функцию переданы неверные параметры Произошла нехватка памяти Использование команды недопустимо в данном состоянии
Программирование компьютерной графики с использованием OpenGL
Что такое OpenGL (Open Graphics Library) Широко распространенный графический API для программирования 2D и 3D графики Разработан в 1992 году фирмой Silicon Graphics Выступает в качестве стандартного и стабильного API на многих программно-аппаратных платформах Спецификация, описывающая набор функций и их точное поведение Производители оборудования создают реализации библиотеки согласно данной спецификации
Достоинства Промышленный стандарт Стабильность Надежность и переносимость Современность Масштабируемость Легкость в изучении и использовании Хорошо документирован Независим от языка программирования
Базовые возможности Рисование геометрических примитивов (точки, линии, многоугольники) Рисование сложных объектов реализуется силами программиста либо сторонними библиотеками Работа с растровыми примитивами Цветовые режимы RGBA / Index Видовые и модельные преобразования Прозрачность Удаление невидимых линий и поверхностей B-сплайны Наложение текстуры Интерполяция цветов, Anti-aliasing, туман Использование списков изображений (display lists)
Основы Ориентированность главным образом на построение изображения в буфере кадра (Frame Buffer) и чтение из него Основное назначение OpenGL - интерактивная визуализация трехмерных сцен
Библиотека OpenGL Графическая библиотека OpenGL позволяет рисовать графические примитивы в различных режимах Примитивами являются точки, отрезки прямых, многоугольники или растровые прямоугольники Переключение режимов рисования, отображение примитивов и другие операции GL описываются при помощи вызовов процедур и функций
Примитивы OpenGL Примитивы задаются при помощи групп из одной или более вершин Каждая вершина определяет точку, конец отрезка прямой или вершину многоугольника Атрибуты вершины (позиция, нормаль, цвет, текстурные координаты и т.п.) – набор свойств, ассоциированных с вершиной В версии OpenGL 3.0 убраны все встроенные атрибуты вершин и функции по их установке Каждая вершина обрабатывается независимо от других и одним и тем же образом. При отсечении примитивов могут создаваться дополнительные вершины Значения атрибутов при этом интерполируются с учетом перспективы
Пример 1 2 3
Команды OpenGL Взаимодействие приложения с OpenGL происходит посредством отдачи команд Команда – вызов определенной функции библиотеки Команды всегда выполняются в порядке их получения Возможна некоторая задержка между вызовом команды и отображением результата Команда glFinish() вызывает немедленное выполнение команд и дожидается завершения их выполнения Команда glFlush() вызывает немедленное выполнение команд, но не дожидается завершения их выполнения Выборка данных, необходимых для выполнения команды происходит в момент вызова команды Актуально при передаче массивов в качестве аргументов команд
Пример: рисование линий 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();
Результат
Клиент-серверная интерпретация команд Приложение (Клиент) вызывает команды, обрабатываемые OpenGL (Сервер) Сетевая прозрачность Сервер может работать с несколькими различными контекстами Контекст хранит состояние OpenGL Команды в один момент времени работают с текущим контекстом Клиент может переключаться с одного контекста на другой при помощи специальных команд
Низкоуровневой доступ OpenGL предоставляет доступ к низкоуровневым графическим операциям Изменить режим Установить заданный параметр Нарисовать группу примитивов Описание сложных 3d и 2d-объектов и сцен – забота программиста, а не библиотеки
Оконная система OpenGL осуществляет графический вывод в буфер кадра Отображение буфера кадра на экране монитора не входит в обязанности OpenGL Изначально OpenGL был спроектирован как аппаратно-независимая графическая библиотека Управлением буфером кадра и его отображением на экране монитора занимается оконная система WGL – Microsoft Windows GLX – Unix/Linux GLUT – мультиплатформенная библиотека Скрывает особенности различных оконных систем за единым API (пусть даже с ограниченным функционалом)
Типы данных OpenGL Функции OpenGL работают с аргументами определенного типа Целые, числа с плавающей точкой Размер одного и того же типа в различных системах может варьироваться Рекомендуется использовать встроенные типы OpenGL Функции OpenGL, способные работать с несколькими типами данных имеют в составе своего имени суффиксы
Суффиксы команд и типы данных аргументов
Пример void DrawDot(GLint x, GLint y) { glBegin(GL_POINTS); glVertex2i(x, y); glEnd(); }
Состояние OpenGL (OpenGL state) OpenGL с точки зрения спецификации – конечный автомат, управляющий набором определенных графических операций Состояние OpenGL описывается множеством переменных состояния (state variables) Текущий цвет Текущая нормаль Текущий размер точки Текущие координаты текстуры и т.п. Значения переменных состояния изменяются при помощи команд OpenGL В версии OpenGL 3.0 произошел практически полный отказ от архитектуры конечного автомата
Два типа состояния OpenGL Состояние сервера С каждым контекстом OpenGL связан полный набор переменных состояния сервера К данному типу относится бОльшая часть переменных OpenGL Состояние клиента Определяется набором переменных состояния клиента Каждое соединение клиента с сервером заключает в себе полный набор переменных состояния клиента и сервера
Синтаксис команд OpenGL Команды OpenGL – функции или процедуры Группы команд выполняют одну операцию, однако используют разные типы и количество аргументов, например: glVertex* glColor* glTranslate*
Форма записи команд 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] - если присутствует, то в качестве аргумента команды выступает указатель на массив значений
Примеры: 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)
Буфер кадра OpenGL Буфер кадра состоит из нескольких буферов, каждый из которых хранит определенную информацию о фрагментах изображения: Буфер цвета Буфер глубины Буфер трафарета
Графический конвейекр OpenGL
Передача вершин, заданных в системе координат модели на вход графического конвейера OpenGL 1 2 3 4 5 6
Преобразование моделирования-вида
Расчет освещения и цвета вершин 2 3 4 5 6 1
Сборка примитивов 2 3 4 5 6 1
Отсечение плоскостями отсечения, задаваемыми пользователем 2 3 4 5 6 1
Умножение на матрицу проецирования и перспективное деление -1 +1 -1 +1 -1 -1 +1
Растеризация Процесс преобразования примитива в двухмерное изображение. Каждая точка такого примитива содержит информацию о цвете, глубине, и текстуре Точка и связанная с ней информация называется фрагментом
Операции над фрагментами Тест принадлежности контексту рендеринга Тест «ножниц» Альфа-тест Тест трафарета Тест глубины Смешивание цветов Dithering Логические операции (для индексированных Цветов)
Запись значений в буфер кадра
Обработка ошибок В ходе работы с OpenGL могут возникать ошибочные ситуации В целях обеспечения производительности OpenGL обрабатывает только некоторое подмножество таких ситуаций Узнать о наличии ошибки позволяет функция: GLenum glGetError()
Коды ошибок OpenGL
Парадигма glBegin()/glEnd() Большинство геометрических примитивов OpenGL отображаются при помощи перечисления их вершин между «командными скобками» glBegin() и glEnd() При выполнении команды glVertex* происходит создание новой вершины внутри примитива с текущими атрибутами вершины на момент выполнения команды glVertex* Данная парадигма объявлена устаревшей из за своей низкой производительности в версии OpenGL 3.0 и более не поддерживается
Преобразования координат Координаты вершин, передаваемых при помощи функций glVertex* и ей подобных обычно задаются в системе координат объекта В ходе обработки вершин OpenGL выполняет последовательность обязательных преобразований каждой вершины Использование вершинных шейдеров позволяет изменить часть этапов на свои собственные
Матрица моделирования-вида (Model-View Matrix) OpenGL преобразовывает координаты каждой вершины из системы координат объекта в систему координат наблюдателя при помощи Матрицы моделирования-вида
Матрица проецирования (Projection matrix) Матрица проецирования применяется к системе координат наблюдателя, преобразуя вершины в систему координат отсечения (clip coordinates)
Перспективное деление Перспективное деление переводит вершину в нормализованную систему координат устройства Отображаемый объем при этом трансформируется в куб со сторонами, параллельными осям координат, располагающийся в диапазоне от -1 до +1
Преобразование в порт просмотра (viewport transformation) Порт просмотра – прямоугольная область окна, в которой происходит отображение видового объема сцены Преобразование в порт просмотра позволяет получить координаты вершин в оконных координатах устройства (в пикселях) Значение глубины фрагмента приводится к диапазону [0;1] (или к задаваемому пользователем)
Система координат frame buffer’а x y z +1 -1 -1 +1 Видовой порт Видимый объем
Матрицы в OpenGL OpenGL в ходе своей работы использует следующие типы матриц: Матрица моделирования/вида (ModelView matrix) Матрица проецирования (Projection matrix) Матрица текстуры (Texture matrix) Значения данных матриц могут быть заданы при помощи определенных команд OpenGL
Выбор текущей матрицы OpenGL в один момент времени работает только с одной текущей матрицей Для выбора текущей матрицы служит команда void glMatrixMode(GLenum mode) где mode – одно из значений GL_MODELVIEW GL_PROJECTION GL_TEXTURE
Загрузка и изменение текущей матрицы glLoadMatrix Заменяет текущую матрицу на определенную пользователем glMultMatrix Заменяет текущую матрицу С результатом ее умножения на матрицу M С’ = C ∙ M OpenGL хранит элементы матриц не построчно, а по столбцам:
Загрузка единичной матрицы glLoadIdentity() заменяет текущую матрицу на единичную
Применение аффинных преобразований Данные функции позволяют осуществлять аффинные преобразования в трехмерном пространстве Результатом вызова данных команд будет умножение текущей матрицы на матрицу одного из аффинных преобразований glTranslate* glScale* glRotate* В OpenGL 3.0 данные функции объявлены устаревшими
Матрицы проецирования Умножают текущую матрицу на матрицу проецирования glOrtho – ортографическое преобразование glFrustum – перспективное преобразование См. также: gluPerspective gluOrtho2D
Стек матриц Стек матриц позволяет запомнить и в последствии восстановить текущую матрицу void glPushMatrix() – запомнить текущую матрицу в стеке void glPopMatrix() – восстановить запомненную матрицу из стека Матрицы каждого типа имеют свой собственный стек определенной глубины
Вершины Вершины используются для задания основных примитивов OpenGL. Могут иметь размерность от 1 до 4 координат Задаются при помощи glVertex* В момент обработки команды glVertex OpenGL создает вершину с текущими атрибутами вершины
Нормаль Одним из атрибутов вершины в OpenGL является вектор нормали к поверхности в точке вершины Направлен перпендикулярно поверхности, проходящей через текущую вершину OpenGL использует нормали для расчета освещенности граней Текущий вектор нормали задается при помощи функций glNormal
Задание нормалей вершин для объекта с плоскими гранями
Задание нормалей вершин примитивов, аппроксимирующих криволинейную поверхность
Примитивы OpenGL Примитив – это фигура (точка, линия, многоугольник, прямоугольник пикселей, или битовый массив), которая рисуется, хранится и которой манипулируют как единой дискретной сущностью Из примитивов строятся геометрические объекты любой степени сложности Примитивы определяются группами из одной или нескольких вершин, с каждой из которых ассоциирован определенный набор атрибутов
Атрибуты вершин Текущий цвет вместе с условиями освещения определяет результирующий цвет вершины Текущая позиция растра (при работе с пикселями и битовыми массивами) Текущая нормаль Вектор нормали, ассоциированный с вершиной, задает ориентацию содержащей ее поверхности в трехмерном пространстве Текущие координаты текстуры Местоположение в карте текстуры (texture map), ассоциированное с вершиной В OpenGL 3.0 встроенные атрибуты вершин объявлены устаревшими
Рисование примитивов Примитив, или группа однотипных примитивов определяются путем объявления их вершин внутри командных скобок 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();
Типы геометрических примитивов 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: |
No comments posted yet
Comments