Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (1124366), страница 3
Текст из файла (страница 3)
Глава 2. Введение в OPENGL
В качестве атрибутов OpenGL позволяет задавать цвет, характеристики материала, текстуры, параметры освещения.
-
Функции визуализации позволяют задать положение наблюдателя в виртуальном пространстве, параметры объектива камеры. Зная эти параметры, система сможет не только правильно построить изображение, но и отсечь объекты, оказавшиеся вне поля зрения.
-
Набор функций геометрических преобразований позволяет программисту выполнять различные преобразования объектов— поворот, перенос, масштабирование.
При этом OpenGL может выполнять дополнительные операции, такие как использование сплайнов для построения линий и поверхностей, удаление невидимых фрагментов изображений, работа с изображениями на уровне пикселей и т.д.
2.2. Интерфейс OpenGL
OpenGL состоит из набора библиотек. Все базовые функции хранятся в основной библиотеке, для обозначения которой в дальнейшем мы будем использовать аббревиатуру GL. Помимо основной, OpenGL включает в себя несколько дополнительных библиотек.
Первая из них — библиотека утилит GL(GLU — GL Utility). Все функции этой библиотеки определены через базовые функции GL. В состав GLU вошла реализация более сложных функций, таких как набор популярных геометрических примитивов (куб, шар, цилиндр, диск), функции построения сплайнов, реализация дополнительных операций над матрицами и т.п.
OpenGL не включает в себя никаких специальных команд для работы с окнами или ввода информации от пользователя. Поэтому были созданы специальные переносимые библиотеки
2.2. Интерфейс OPENGL
27
Прикладная программа
Г]—|
Буфер кадра
Рис. 2.1. Организация библиотеки OpcnGL
для обеспечения часто используемых функций взаимодействия с пользователем и для отображения информации с помощью оконной подсистемы.
Наиболее популярной является библиотека GLUT (GL Utility Toolkit). Формально GLUT не входит в OpenGL, но de facto включается почти во все его дистрибутивы и имеет реализации для различных платформ. GLUT предоставляет только минимально необходимый набор функций для создания OpenGL-приложения. Функционально аналогичная библиотека GLX менее популярна. В дальнейшем в этой книге в качестве основной будет рассматриваться GLUT.
Кроме того, функции, специфичные для конкретной оконной подсистемы, обычно входят в ее прикладной программный интерфейс. Так, функции, поддерживающие выполнение OpenGL, есть в составе Win32 API и X Window. На рисунке 2.1 схематически представлена организация системы библиотек в версии, работающей под управлением системы Windows. Аналогичная организация используется и в других версиях OpenGL.
28
Глава 2. Введение в OPENGL
2.3. Архитектура OpenGL
Функции OpenGL реализованы в модели клиент-сервер. Приложение выступает в роли клиента — оно вырабатывает команды, а сервер OpenGL интерпретирует и выполняет их. Сам сервер может находиться как на том же компьютере, на котором находится клиент (например, в виде динамически загружаемой библиотеки — DLL), так и на другом (при этом может быть использован специальный протокол передачи данных между машинами).
GL обрабатывает и рисует в буфере кадра графические примитивы с учетом некоторого числа выбранных режимов. Каждый примитив — это точка, отрезок, многоугольник и т.д. Каждый режим может быть изменен независимо от других. Определение примитивов, выбор режимов и другие операции описываются с помощью команд в форме вызовов функций прикладной библиотеки.
Примитивы определяются набором из одной или более вершин (vertex). Вершина определяет точку, конец отрезка или угол многоугольника. С каждой вершиной ассоциируются некоторые данные (координаты, цвет, нормаль, текстурные координаты и т.д.), называемые атрибутами. В подавляющем большинстве случаев каждая вершина обрабатывается независимо от других.
С точки зрения архитектуры, графическая система OpenGL является конвейером, состоящим из нескольких последовательных этапов обработки графических данных.
Команды OpenGL всегда обрабатываются в том порядке, в котором они поступают, хотя могут происходить задержки перед тем, как проявится эффект от их выполнения. В большинстве случаев OpenGL предоставляет непосредственный интерфейс, т.е. определение объекта вызывает его визуализацию в буфере кадра.
С точки зрения разработчиков, OpenGL — это набор команд,
2.3. Архитектура OPENGL
29
которые управляют использованием графической аппаратуры. Если аппаратура состоит только из адресуемого буфера кадра, тогда OpenGL должен быть реализован полностью с использованием ресурсов центрального процессора. Обычно графическая аппаратура предоставляет различные уровни ускорения: от аппаратной реализации вывода линий и многоугольников до изощренных графических процессоров с поддержкой различных операций над геометрическими данными.
Рис. 2.2. Функционирование конвейера OpenGL
OpenGL является прослойкой между аппаратурой и пользовательским уровнем, что позволяет предоставлять единый интерфейс на разных платформах, используя возможности аппаратной поддержки.
Кроме того, OpenGL можно рассматривать как конечный ав-
30
Глава 2. Введение в OPENGL
томат, состояние которого определяется множеством значений специальных переменных, значениями текущей нормали, цвета, координат текстуры и других атрибутов и признаков. Вся эта информация будет использована при поступлении в графическую систему координат вершины для построения фигуры, в которую она входит. Смена состояний происходит с помощью команд, которые оформляются как вызовы функций.
2.4. Синтаксис команд
Определения команд GL находятся в файле gl.h, для включения которого нужно написать
^include <gl/gl.h>
Для работы с библиотекой GLU нужно аналогично подключить файл glu.h. Версии этих библиотек, как правило, включаются в дистрибутивы систем программирования, например, Microsoft Visual C++ или Borland C++ Builder. В отличие от стандартных библиотек, пакет GLUT нужно инсталлировать и подключать отдельно. Подробная информация о настройке сред программирования для работы с OpenGL приведена в Части III.
Все команды (процедуры и функции) библиотеки GL начинаются с префикса gl, все константы — с префикса GL_. Соответствующие команды и константы библиотек GLU и GLUT аналогично имеют префиксы glu (GLU_) и glut (GLUT_) Кроме того, в имена команд входят суффиксы, несущие информацию о числе и типе передаваемых параметров. В OpenGL полное имя команды имеет вид:
type glCommand_name[ 1 2 3 4][b s i f d ub us ui][v]
(typel argl ,..., typeN argN)
Имя состоит из нескольких частей:
2.5. Пример приложения
31
gl —имя библиотеки, в которой описана эта функция: для базовых функций OpenGL, функций из библиотек GL, GLU, GLUT, GLAUX это gl, glu, glut, aux соответственно;
Command name —имя команды (процедуры или функции);
[12 3 4 ] — число аргументов команды;
[b s i f d ub us ui ] — тип аргумента: символ b — GLbyte (аналог char в C/C++), символ i — GLint (аналог int), символ f— GLfloat (аналог float) и так далее. Полный список типов и их описание можно посмотреть в файле gl.li;
[v ] — наличие этого символа показывает, что в качестве параметров функции используется указатель на массив значений.
Символы в квадратных скобках в некоторых названиях не используются. Например, команда glVertex2i() описана в библиотеке GL и использует в качестве параметров два целых числа, а команда glColor3fv () использует в качестве параметра указатель на массив из трех вещественных чисел.
Использования нескольких вариантов каждой команды можно частично избежать, применяя перегрузку функций языка C++. Но интерфейс OpenGL не рассчитан на конкретный язык программирования, и, следовательно, должен быть максимально универсален.
2.5. Пример приложения
Типичная программа, использующая OpenGL, начинается с определения окна, в котором будет происходить отображение. Затем создается контекст (клиент) OpenGL и ассоциируется с этим окном. Далее программист может свободно использовать команды OpenGL API.
32
Глава 2. Введение в OPENGL
Ниже приведен текст небольшой программы, написанной с использованием библиотеки GLUT — своеобразный аналог классического примера «Hello, World!».
Все, что делает эта программа — рисует в центре окна красный квадрат. Тем не менее, даже на этом простом примере можно понять принципы программирования с помощью OpenGL.
Программа 2.1. Простейший пример OpenGL.
^include <stdlib.h>
// подключаем библиотеку GLUT
^include <gl/glut.h>
// начальная ширина и высота окна GLint Width = 512, Height = 512;
// размер куба
const int CubeSize = 200;
// эта функция управляет всем выводом на экран void Display (void)
{ _
int left , right , top, bottom;
left = (Width - CubeSize) / 2; right = left + CubeSize; bottom = (Height - CubeSize) / 2; top = bottom + CubeSize ;
glClearColor(0.7, 0.7, 0.7, 1); g 1С1 e ar (GL_COLOR_BUFFTER_Brr);
glColor3ub (255 ,0 ,0); glBegin(GL_QUADS); glVertex2f (left , bottom ) ; glVertex2f (left , top ); glVertex2f( right , top ); glVertex2f( right , bottom ) ;
2.5. Пример приложения
33
glEnd();
glFinish () ; }
// Функция вызывается при изменении размеров окна void Reshape (GLint w, GLint h)
{
Width = w;
Height = h;
/* устанавливаем размеры области отображения */ glViewport (0 , 0, w, h);
/* ортографическая проекция */ glMatrixMode (GL_PROJECTION); glLoadldentity () ; glOrtho(0, w, 0, h, -1.0, 1.0);
glMatrixMode (GL_MODELVIEW); glLoadldentity () ; }
// Функция обрабатывает сообщения от клавиатуры void Keyboard ( unsigned char key, int x, int у )
{
const char ESCAPE = '\033';
if ( key = ESCAPE ) exit(0); }
// Главный цикл приложения
void main (int argc , char *argv[])
{
glutlnit (&argc, argv);
34
Глава 2. Введение в OPENGL
glutlnitDisplayMode (GLUT_RGB) ; glutlnitWindowSize (Width , Height ); glutCreateWindow ("Redwsquare„example " );
glutDisplayFunc( Display ) ; gl ut Re shape Fun с (Reshape ) ; glutKeyboardFunc (Keyboard);
glutMainLoop () ; }
Рис. 2.З. Результат работы программы 2.1.
Несмотря на малый размер, это полностью завершенная программа, которая должна компилироваться и работать на любой системе, поддерживающей OpenGL и GLUT.
Библиотека GLUT поддерживает взаимодействие с пользователем с помощью так называемых функций с обратным вызовом (callback function). Если пользователь подвинул мышь, нажал на кнопку клавиатуры или изменил размеры окна, происходит событие и вызывается соответствующая функция пользователя — обработчик событий (функция с обратным вызовом).
Рассмотрим более подробно функцию main данного примера.
2.5. Пример приложения
35
Она состоит из трех частей: инициализации окна, в котором будет рисовать OpenGL, настройки функций с обратным вызовом и главного цикла обработки событий.
Инициализация окна состоит из настройки соответствующих буферов кадра, начального положения и размеров окна, а также заголовка окна.
Функция glutlnit (&argc, argv) производит начальную инициализацию самой библиотеки GLUT.
Команда glutInitDisplayMode(GLUT_RGB) инициализирует буфер кадра и настраивает полноцветный (непалитровый) режим RGB.
glutlnitWindowSize(Width, Height) используется для задания начальных размеров окна.
Наконец, glutCreateWindow("RedwsquarewexampleM) задает заголовок окна и визуализирует само окно на экране.
Затем команды
glutDisplayFunc( Display); glutReshapeFunc (Reshape ); glutKeyboardFimc (Keyboard ) ;
регистрируют функции Display(), ReshapeQ и Keyboard() как функции, которые будут вызваны, соответственно, при перерисовке окна, изменении размеров окна, нажатии клавиши на клавиатуре.