Программирование на Visual C++. Архив рассылки
Шрифт:
С точки зрения архитектуры графическая система OpenGL является конвейером, состоящим из нескольких этапов обработки данных:
• Аппроксимация кривых и поверхностей
• Обработка вершин и сборка примитивов
• Растеризация и обработка фрагментов
• Операции над пикселями
• Подготовка текстуры
• Передача данных в буфер кадра
GL обрабатывает и выводит так называемые примитивы (primitive) с учетом некоторого числа выбранных режимов. Каждый примитив – это точка, отрезок, многоугольник и т.д. Каждый режим может быть изменен независимо от других. Определение примитивов, выбор режимов и другие операции описывается с помощью команд в форме вызовов процедур.
Примитивы определяются
Команды OpenGL всегда обрабатываются в том порядке, в котором они поступают, хотя могут происходить задержки перед тем, как проявится эффект от их выполнения.
Для обеспечения интуитивно понятных названий в OpenGL полное имя команды имеет вид:
Таким образом, имя состоит из нескольких частей:
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) функций
• Управление индексированной палитрой цветов
• Отображение шрифтов
• Отображение дополнительных геометрических фигур (тор, конус и др.)
Инициализация проводится с помощью функции
Переменная argcp есть указатель на стандартную переменную argc описываемую в функции main, а argv – указатель на параметры, передаваемые программе при запуске, который описывается там же. Эта функция проводит необходимые начальные действия для построения окна приложения, и только несколько функций GLUT могут быть вызваны до нее. К ним относятся:
Первые две функции задают соответственно положение и размер
окна, а последняя функция определяет различные режимы отображения информации, которые могут совместно задаваться с использованием операции побитового "или" ("|"):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 | Окно с буфером глубины. |
Это неполный список параметров для данной функции, однако, для большинства случаев этого бывает достаточно.
Двойной буфер обычно используют для анимации, сначала рисуя что-нибудь в одном буфере, а затем, меняя их местами, что позволяет избежать мерцания. Буфер глубины или z-буфер используется для удаления невидимых линий и поверхностей.
Работа с трафаретным буфером и буфером накопления описана в разделе Спецэффекты.
Функции библиотеки GLUT реализуют так называемый событийно-управляемый механизм. Это означает, что есть некоторый внутренний цикл, который запускается после соответствующей инициализации и обрабатывает, один за другим, все события, объявленные во время инициализации. К событиям относятся: щелчок мыши, закрытие окна, изменение свойств окна, передвижение курсора, нажатие клавиши, и "пустое" (idle) событие, когда ничего не происходит. Для проведения периодической проверки совершения того или иного события надо зарегистрировать функцию, которая будет его обрабатывать. Для этого используются функции вида:
То есть параметром для них является имя соответствующей функции заданного типа. С помощью glutDisplayFunc задается функция рисования для окна приложения, которая вызывается при необходимости создания или восстановления изображения. Для явного указания, что окно надо обновить, иногда удобно использовать функцию
Через glutReshapeFunc устанавливается функция обработки изменения размеров окна пользователем, которой передаются новые размеры.
glutMouseFunc определяет обработчика команд от мыши, а glutIdleFunc задает функцию, которая будет вызываться каждый раз, когда нет событий от пользователя.
Контроль всех событий происходит внутри бесконечного цикла в функции
которая обычно вызывается в конце любой программы, использующей GLUT. Структура приложения, использующего анимацию, будет следующей: