С точки зрения разработчика, OpenGL – это набор команд, которые управляют использованием графической аппаратуры. Если аппаратура состоит только из адресуемого буфера кадра, тогда OpenGL должен быть реализован полностью с использованием ресурсов центрального процессора. Обычно графическая аппаратура предоставляет различные уровни ускорения: от аппаратной реализации вывода линий и полигонов до изощренных графических процессоров с поддержкой различных операций над геометрическими данными.
OpenGL является прослойкой между аппаратурой и пользовательским уровнем. Это дает возможность использовать единый интерфейс для разных платформ, при этом получая оптимальную производительность с использованием аппаратной поддержки.
Вообще, OpenGL можно сравнить с конечным автоматом, состояние которого определяется множеством значений специальных переменных (их имена обычно начинаются с символов GL_) и значениями текущей нормали, цвета и координат текстуры. Все эта информация будет использована при поступлении в систему координат вершины для построения фигуры, в которую она входит. Смена состояний происходит с помощью команд, которые оформляются как вызовы функций.
Характерными особенностями OpenGL, которые обеспечили распространение и развитие этого графического стандарта, являются:
Стабильность
Дополнения и изменения в стандарте реализуются таким образом, чтобы сохранить совместимость с разработанным ранее программным обеспечением.
Надежность и переносимость
Приложения, использующие OpenGL, гарантируют одинаковый визуальный результат вне зависимости от типа используемой операционной системы и организации отображения информации. Кроме того, эти приложения могут выполняться как на персональных компьютерах, так и на рабочих станциях и суперкомпьютерах.
Легкость применения
Стандарт OpenGL имеет продуманную структуру и интуитивно понятный интерфейс, что позволяет с меньшими затратами создавать эффективные приложения, содержащие меньше строк кода, чем с использованием других графических библиотек. Необходимые функции для обеспечения совместимости с различным оборудованием реализованы на уровне библиотеки и значительно упрощают разработку приложений.
Основные возможности
• Набор базовых примитивов: точки, линии, многоугольники и т.п.
• Видовые и координатные преобразования
• Удаление невидимых линий и поверхностей (z-буфер)
• Использование сплайнов для построения линий и поверхностей
• Наложение текстуры и применение освещения
• Добавление специальных эффектов: тумана, изменение прозрачности, смешивание цветов (blending), устранение ступенчатости (anti-aliasing).
Как уже было сказано, существует реализация OpenGL для разных платформ, для чего было удобно разделить базовые функции графической системы и функции для отображения графической информации и взаимодействия с пользователем. Были созданы библиотеки для отображения информации с помощью оконной подсистемы для операционных систем Windows и Unix (WGL и GLX соответственно), а также библиотеки GLAUX и GLUT, которые используются для создания так называемых консольных приложений.
Библиотека GLAUX уступает по популярности написанной несколько позже библиотеке GLUT, хотя они предоставляют примерно одинаковые возможности. В дальнейшем в данном пособии в качестве основной будет рассматриваться библиотека GLUT, предоставляющая широкий набор средств взаимодействия с пользователем.
В состав библиотеки GLU вошла реализация более сложных функций, таких как набор популярных геометрических примитивов (куб, шар, цилиндр, диск), функции построения сплайнов, реализация дополнительных операций над матрицами и т.п. Все они реализованы через базовые функции OpenGL.
Основы OpenGL
С точки зрения архитектуры графическая система OpenGL является конвейером, состоящим из нескольких этапов обработки данных:
• Аппроксимация кривых и поверхностей
• Обработка вершин и сборка примитивов
• Растеризация и обработка фрагментов
• Операции над пикселями
• Подготовка текстуры
• Передача данных в буфер кадра
GL обрабатывает и выводит так называемые примитивы (primitive) с учетом некоторого числа выбранных режимов. Каждый примитив – это точка, отрезок, многоугольник и т.д. Каждый режим может быть изменен независимо от других. Определение примитивов, выбор режимов и другие операции описывается с помощью команд в форме вызовов процедур.
Примитивы определяются набором из одной или более вершин (vertex). Вершина определяет точку, конец грани, угол многоугольника. С каждой вершиной ассоциируются некоторые данные (координаты, цвет, нормаль, текстурные координаты). В подавляющем большинстве случаев каждая вершина обрабатывается независимо от других.
Команды OpenGL всегда обрабатываются в том порядке, в котором они поступают, хотя могут происходить задержки перед тем, как проявится эффект от их выполнения.
Синтаксис командДля обеспечения интуитивно понятных названий в OpenGL полное имя команды имеет вид:
type glCommand_name[1 2 3 4][b s i f d ub us ui][v](type1 arg1,:,typeN argN)
Таким образом, имя состоит из нескольких частей:
Gl это имя библиотеки, в которой описана эта функция: для базовых функций OpenGL, функций из библиотек GLU, GLUT, GLAUX это gl, glu, glut, glaux соответственно
Command_name имя команды
[1 2 3 4] число аргументов команды
[b s i f d ub us ui] тип аргумента: символ b означает тип GLbyte (аналог char в СC++), символ f – тип GLfloat (аналог float), символ i – тип GLint (аналог int) и так далее. Полный список типов и их описание можно посмотреть в файле gl.h
[v] наличие этого символа показывает, что в качестве параметров функции используется указатель на массив значений
Символы в квадратных скобках в некоторых названиях не используются. Например, команда glVertex2i() описана как базовая в библиотеке OpenGL, и использует в качестве параметров два целых числа, а команда glColor3fv() использует в качестве параметра указатель на массив из трех вещественных чисел.
Структура консольного приложенияБудем рассматривать построение консольного приложения при помощи библиотеки GLUT или GL Utility Toolkit, получившей в последнее время широкое распространение. Эта библиотека обеспечивает единый интерфейс для работы с окнами вне зависимости от платформы, поэтому описываемая ниже структура приложения остается неизменной для операционных систем Windows, Linux и многих других.
Функции GLUT могут быть классифицированы на несколько групп по своему назначению:
• Инициализация
• Начало обработки событий
• Управление окнами
• Управление меню
• Регистрация вызываемых (callback) функций
• Управление индексированной палитрой цветов
• Отображение шрифтов
• Отображение дополнительных геометрических фигур (тор, конус и др.)
Инициализация проводится с помощью функции
glutInit(int *argcp, char **argv)
Переменная argcp есть указатель на стандартную переменную argc описываемую в функции main(), а argv – указатель на параметры, передаваемые программе при запуске, который описывается там же. Эта функция проводит необходимые начальные действия для построения окна приложения, и только несколько функций GLUT могут быть вызваны до нее. К ним относятся:
glutInitWindowPosition(int x, int y)
glutInitWindowSize(int width, int height)
glutInitDisplayMode(unsigned int mode)
Первые две функции задают соответственно положение и размер окна, а последняя функция определяет различные режимы отображения информации, которые могут совместно задаваться с использованием операции побитового "или" ("|"):
GLUT_RGBA Режим RGBA. Используется по умолчанию, если не указаны явно режимы GLUT_RGBA или GLUT_INDEX.
GLUT_RGB То же, что и GLUT_RGBA.
GLUT_INDEX Режим индексированных цветов (использование палитры). Отменяет GLUT_RGBA.
GLUT_SINGLE Окно с одиночным буфером. Используется по умолчанию.
GLUT_DOUBLE Окно с двойным буфером. Отменяет GLUT_SINGLE.
GLUT_STENCIL Окно с трафаретным буфером.
GLUT_ACCUM Окно с буфером накопления.
GLUT_DEPTH Окно с буфером глубины.
Это неполный список параметров для данной функции, однако, для большинства случаев этого бывает достаточно.