Глава 1. Введение в OpenGL 1
1.1 Что такое OpenGL? 1
1.2 Немного OpenGL кода 2
1.3 Синтаксис команд OpenGL 4
1.4 OpenGL как машина состояния (state machine) 5
1.5 Конвейер визуализации OpenGL 5
1.5.1 Списки 6
1.5.2 Вычислители 6
1.5.3 Повершинные операции 7
1.5.4 Сборка примитивов 7
1.5.5 Операции над пикселями 7
1.5.6 Наложение текстуры 7
1.5.7 Растеризация 8
1.5.8 Операции над фрагментами 8
1.6 Библиотеки, связанные с OpenGL 8
1.7 Заголовочные файлы 9
1.8 Сборка проекта 9
1.9 GLUT 10
1.9.1 Управление окном 10
1.9.2 Функции управления событиями 11
1.9.3 Загрузка палитры 12
1.9.4 Рисование трехмерных объектов 12
1.9.5 Управление фоновым процессом 13
1.9.6 Запуск программы 13
1.9.7 Типы проектов 14
1.10 Анимация 15
1.11 Частота обновления экрана 16
1.12 Движение = Перерисовка + Переключение 17
1.13 Ссылки на примеры главы 19
Глава 1. Введение в OpenGL
Автор: Максим Каверин
Версия для печати
1.1 Что такое OpenGL?
OpenGL – это программный интерфейс к графической аппаратуре. Этот интерфейс состоит приблизительно из 250 отдельных команд (около 200 команд в самой OpenGL и еще 50 в библиотеке утилит), которые используются для указания объектов и операций, которые необходимо выполнить, чтобы получить интерактивное приложение, работающее с трехмерной графикой.
Библиотека OpenGL разработана как обобщенный, независимый интерфейс, который может быть реализован для различного аппаратного обеспечения. По этой причине сама OpenGL не включает функций для создания окон или для захвата пользовательского ввода; для этих операций вы должны использовать средства той операционной системы, в которой вы работаете. По тем же причинам в OpenGL нет высокоуровневых функций для описания моделей трехмерных объектов. Такие команды позволили бы вам описывать относительно сложные фигуры, такие как автомобили, части человеческого тела или молекулы. При использовании библиотеки OpenGL вы должны строить необходимые модели при помощи небольшого набора геометрических примитивов – точек, линий и многоугольников (полигонов).
Тем не менее, библиотека, предоставляющая описанные возможности может быть построена поверх OpenGL. Библиотека утилит OpenGL (OpenGL Utility Library -- GLU) предоставляет множество средств для моделирования, например, квадрические поверхности, кривые и поверхности типа NURBS. GLU – стандартная часть любой реализации OpenGL. Существуют также и более высокоуровневые библиотеки, например, Fahrenheit Scene Graph (FSG), которые построены с использованием OpenGL и распространяются отдельно для многих ее реализаций.
В следующем списке коротко описаны основные графические операции, которые выполняет OpenGL для вывода изображения на экран.
1. Конструирует фигуры из геометрических примитивов, создавая математическое описание объектов (примитивами в OpenGL считаются точки, линии, полигоны, битовые карты и изображения).
2. Позиционирует объекты в трехмерном пространстве и выбирает точку наблюдения для осмотра полученной композиции.
3. Вычисляет цвета для всех объектов. Цвета могут быть определены приложением, получены из расчета условий освещенности, вычислены при помощи текстур, наложенных на объекты или из любой комбинации этих факторов.
4. Преобразует математическое описание объектов и ассоциированной с ними цветовой информации в пиксели на экране. Этот процесс называется растеризацией (или растровой разверткой).
В течение всех этих этапов OpenGL может производить и другие операции, например, удаление частей объектов, скрытых другими объектами. В дополнение к этому, после того, как сцена растеризована, но до того, как она выводится на экран, вы можете производить некоторые операции с пиксельными данными, если это необходимо.
В некоторых реализациях (например, в реализации для системы X Window), OpenGL разработана таким образом, чтобы работать даже в том случае, если компьютер, которые отображает графику не то же самый, на котором запущена ваша графическая программа. Это может происходить в случае, если работа происходит в сетевом окружении, состоящем из множества компьютеров, соединенных между собой. В данной ситуации компьютер, на котором функционирует программа, и вызываются команды OpenGL, является клиентом, в то время как компьютер, осуществляющий отображение, является сервером. Формат пересылки команд OpenGL от клиента серверу (или протокол) всегда один и тот же, так что программа может работать по сети даже в том случае, если клиент и сервер – совершенно различные компьютеры. В несетевом случае один и тот же компьютер является и клиентом, и сервером.
1.2 Немного OpenGL кода
Поскольку при помощи библиотеки OpenGL можно делать так много вещей, программа, использующая ее, может быть весьма сложна. Однако базовая структура полезной программы может быть достаточно простой: ее задачами являются инициализация нескольких переменных или переключателей, контролирующих, как OpenGL осуществляет визуализацию изображения и, далее, указание объектов для отображения.
До того, как будет приведен небольшой пример, определимся с некоторыми терминами. Визуализация (rendering) – это процесс, с помощью которого компьютер создает изображения из моделей. Эти модели или объекты строятся из геометрических примитивов – точек, линий и полигонов, которые в свою очередь, определяются своими вершинами (vertices).
Результирующее изображение состоит из пикселей отображенных на экране. Пиксель – это самый маленький видимый элемент, который монитор может поместить на свой экран.
Информация о пикселях (например, какого цвета они должны быть) организована в памяти в виде битовых поверхностей (bitplanes). Битовая плоскость – это область памяти, содержащая один бит информации на каждый пиксель экрана. Этот бит может определять, например, насколько красным должен быть конкретный пиксель. Сами битовые плоскости организованы в буфер кадра, который содержит всю информацию необходимую монитору, чтобы контролировать цвет и интенсивность всех пикселей на экране.
Теперь посмотрим, на что может быть похожа OpenGL – программа. Пример 1-1 отображает белый квадрат на черном фоне, показанный на рисунке 1.
Рисунок 1.1. Белый квадрат на черном фоне
Пример 1-1. Фрагмент OpenGL – кода
#include <все_что_необходимо.h>
main()
{
ИнициализироватьОкно();
glClearColor(0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0);
glBegin(GL_POLYGON);
glVertex3f(0.25,0.25,0.0);
glVertex3f(0.75,0.25,0.0);
glVertex3f(0.75,0.75,0.0);
glVertex3f(0.25,0.75,0.0);
glEnd();
glFlush();
ОбновитьОкно();
}
|
Первая строка функции main() инициализирует окно на экране. ИнициализироватьОкно() обозначает то место в тексте, куда надо поместить функции создания окна, зависимые от оконной системы, в которой вы работаете и не являющиеся командами OpenGL. Две следующих строки являются командами OpenGL, окрашивающими окно в черный цвет: glClearColor() задает цвет, в который окно будет окрашиваться при его очистке, glClear() как раз и очищает окно. После того, как «очищающий цвет» задан, окно всегда будет окрашиваться именно в него при вызовах glClear(). Этот цвет может быть изменен повторным вызовом glClearColor(). Похожим же образом glColor3f() задает цвет, который будет использоваться для рисования объектов – в данном случае белый. Начиная с этого момента, все объекты будут рисоваться белыми до тех пор, пока не последует замена этого цвета на другой при помощи одной из команд OpenGL.
Следующая OpenGL – команда, использованная в программе, glOrtho(), определяет координатную систему, на которую полагается OpenGL при отрисовке финального изображения и проецировании изображения на экран. Вызовы, заключенные в команды glBegin() и glEnd(), определяют объект, который следует нарисовать – в данном случае полигон с 4 вершинами. «Углы» полигона определяются командами glVertex3f(). Как можно догадаться по значениям аргументов, которые являются координатами (x, y, z), полигон представляет собой квадрат в плоскости z=0.
Наконец, вызов glFlush() позволяет быть уверенным в том, что команды OpenGL действительно выполнились, а не были сохранены в буфере в ожидании дальнейших команд. ОбновитьОкно() – это опять-таки метка для функций, зависящих от оконной системы.
На самом деле этот фрагмент кода не слишком хорошо структурирован. Могут возникнуть вопросы: «Что если мы попытаемся изменить размер окна или переместить его?» «Необходимо ли устанавливать координатную систему каждый раз при отрисовке квадрата?» Позже ИнициализироватьОкно() и ОбновитьОкно() будут заменены на реально работающие вызовы, которые, однако, требуют реструктуризации кода, что сделает его более эффективным.
Достарыңызбен бөлісу: |