Основы работы с библиотекой OpenGL
Библиотека OpenGL содержит около сотни функций. В OpenGL и вспомогательных библиотках приняты следующие правила именования функций:
<префикс><команда><размерность><тип>(список аргументов);
Например, для установки цвета вывода могут использоваться функции:
glColor3f(1.f, 1.f, 1.f);
glColor4d(1., 0., 0., 1.);
а для установки порта вывода:
glViewport(0, 0, width, height);
Библиотека OpenGL также имеет свою систему типов данных:
|
OpenGL Data Type
| Internal Representation
| Defined as C Type
| C Literal Suffix
|
|
GLbyte
| 8-bit integer
| Signed char
| b
|
GLshort
| 16-bit integer
| Short
| s
|
GLint, GLsizei
| 32-bit integer
| Long
| I
|
GLfloat, GLclampf
| 32-bit floating point
| Float
| f
|
GLdouble, GLclampd
| 64-bit floating point
| Double
| d
|
GLubyte, GLboolean
| 8-bit unsigned integer
| Unsigned char
| ub
|
GLushort
| 16-bit unsigned integer
| Unsigned short
| us
|
GLuint, GLenum, GLbitfield
| 32-bit unsigned integer
| Unsigned long
| ui
|
|
OpenGL не содержит каких-либо функций для управления окнами, пользовательским интерфейсом или вводом/выводом. Каждая операционная система должна предоставлять дополнительную библиотеку для инициализации
и отображения результата выполнения OpenGL-команд в окна.
|
Library Name
|
Library Filename
|
Header File
|
Function Prefix
|
|
OpenGL or gl
|
opengl32.dll
|
gl.h
|
gl
|
Utility library or glu
|
glu32.dll
|
glu.h
|
glu
|
Auxiliary or Toolkit
|
glaux.lib
|
glaux.h
|
aux
|
|
wiggle for Win32 & MFC
|
gdi.dll
|
windows.h
|
wgl
|
|
OpenGL Utility Library (GLUT)
|
glut32.dll
|
glut.h
|
glut
|
|
Работа с OpenGL при помощи GLUT
OpenGL является мультиплатформенной библиотекой, т.е. программы написанные с помощью OpenGL можно легко переносить на различные операционные системы, при этом получая один и тот же визуальный результат.
Единственное что плохо -- это то, что для конкретной операционной системы необходимо по своему производить настройку OpenGL. Операции с окнами, интерфейс управления, операции с устройствами ввода/вывода
нужно заново переписать уже под другую операционную систему. Существуют специальные мультиплатформенные библиотеки, позволяющая решить эти проблемы. Одна из таких библиотек называется GLUT.
Процедцра создания и подготовки окна к OpenGL-визуализации состоит из нескольких этапов. Прежде всего необходимо научиться самому основному - это созданию окна, в котором можно будет рисовать с помощью
OpenGL. Минимальная программа, которая создает окно и что-нибудь рисует там состоит из следующих шагов:
- Инициализация GLUT.
- Установка параметров окна.
- Создание окна.
- Установка функций, отвечающих за рисование в окне и изменении формы окна.
- Вход в главный цикл GLUT.
(1) Инициализация GLUT
Инициализация GLUT производится командой:
void glutInit(int *argcp, char **argv);
Первый параметр представляет из себя указатель на количество аргументов в командной строке, а второй - указатель на массив аргументов. Обычно эти значения берутся из главной функции программы. Ведь
общий вид прототипа функции:
int main(int argc, char *argv[]);
(2) Установка параметров окна
Установка параметров окна содержит в себе несколько этапов. Прежде всего необходимо указать размеры окна:
void glutInitWindowSize(int width, int height);
Первый параметр width - ширина окна в пикселях, второй height - высота окна в пикселях. Отмечу также, что если эту команду опустить, то GLUT сам установит размеры окна по умолчанию, обычно это 300x300.
Далее можно задать положение создаваемого окна относительно верхнего левого угла экрана. Делается это командой:
void glutInitWindowPosition(int x, int y);
Необходимо также установить для окна режим отображения информации. Т.е. установить для окна такие параметры как: используемая цветовая модель, количество различных буферов, и т.д. Для этого в GLUT
существует команда:
void glutInitDisplayMode(unsigned int mode);
У команды имеется единственный параметр, который может быть представлен одной из следующих констант или комбинацией этих констант с помощью побитового ИЛИ.
Константа |
Значение |
GLUT_RGB |
Для отображения графической информации используются 3 компоненты цвета RGB. |
GLUT_RGBA |
То же что и RGB, но используется также 4 компонента ALPHA (прозрачность). |
GLUT_INDEX |
Цвет задается не с помощью RGB компонентов, а с помощью палитры. Используется для старых дисплеев, где количество цветов например 256. |
GLUT_SINGLE |
Вывод в окно осуществляется с использованием 1 буфера. Обычно используется для статического вывода информации. |
GLUT_DOUBLE |
Вывод в окно осуществляется с использованием 2 буферов. Применяется для анимации, чтобы исключить эффект мерцания. |
GLUT_ACCUM |
Использовать также буфер накопления (Accumulation Buffer). Этот буфер применяется для создания специальных эффектов, например отражения и тени. |
GLUT_ALPHA |
Использовать буфер ALPHA. Этот буфер, как уже говорилось используется для задания 4-го компонента цвета - ALPHA. Обычно применяется для таких эффектов как прозрачность объектов и антиалиасинг.
|
GLUT_DEPTH |
Создать буфер глубины. Этот буфер используется для отсечения невидимых линий в 3D пространстве при выводе на плоский экран монитора. |
GLUT_STENCIL |
Буфер трафарета используется для таких эффектов как вырезание части фигуры, делая этот кусок прозрачным. Например, наложив прямоугольный трафарет на стену дома, вы получите окно, через которое
можно увидеть что находится внутри дома. |
GLUT_STEREO |
Этот флаг используется для создания стереоизображений. Используется редко, так как для просмотра такого изображения нужна специальная аппаратура. |
Вот пример использования этой команды:
void glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
(3) Создание окна
После того как окно установлено необходимо его создать.
int glutCreateWindow(const char *title);
Эта команда создаёт окно с заголовком, который вы укажете в качестве параметра и возвращает HANDLER окна в виде числа int. Этот HANDLER обычно используется для последующих операций над этим окном,
таких как изменение параметров окна и закрытие окна.
(4) Установка функций обратного вызова
Установка функций, отвечающих за рисование в окне и изменении формы окна. После того, как окно, в которое будет выводится или как говорят "рендерится" графическая информация, подготовлено
и создано, необходимо связать с ним процедуры, которые будут отвечать за вывод графической информации, следить за размерами окна, следить за нажатиями на клавиши и т.д. Самая первая и самая необходимая
функция которую мы рассмотрим, отвечает за рисование. Именно она всегда будет вызываться операционной системой, чтобы нарисовать (перерисовать) содержимое окна. Итак, задаётся эта функция командой:
void glutDisplayFunc(void (*func)(void));
Единственный параметр этой функции - это указатель на функцию, которая будет отвечать за рисование в окне. Например чтобы функция void Draw(void), определенная в вашей программе отвечала за рисование
в окне, надо присоединить ее к GLUT следующим образом:
glutDisplayFunc(Draw);
С другой стороны, вы сами можете заставить систему перерисовать окно, это нужно например тогда, когда вы изменили состояния объектов или изменили их внешность, то вам понадобится перерисовать содержимое
окна, чтобы отобразить сделанные изменения. Поэтому в GLUT существует специальная функция glutPostRedisplay(), которая заставляет систему перерисовать текущее окно.
И ещё одна функция, которая по моему мнению является важной - это функция, которая отслеживает изменения окна. Как только у окна изменились размеры, необходимо перестроить вывод графической информации
уже в новое окно с другими размерами. Если этого не сделать, то например увеличив размеры окна, вывод информации будет производиться в старую область окна, с меньшими размерами. Определить функцию,
отвечающую за изменение размеров окна нужно следующей командой:
void glutReshapeFunc(void (*func)(int width, int height));
Единственный параметр - это указатель на функцию, отвечающую за изменение размеров окна, которая как видно должна принимать два параметра width и height, соответственно ширина и высота нового (измененного)
окна.
(5) Вход в главный цикл GLUT
Вход в главный цикл GLUT. Ну и последнее, что необходимо сделать, чтобы запустить нашу программу - это войти в так называемый главный цикл GLUT. Этот цикл запускает на выполнение так называемое сердце
GLUT, которое обеспечивает взаимосвязь между операционной системой и теми функциями, которые отвечают за окно, получают информацию от устройств ввода/вывода. Для того, чтобы перейти в главный цикл GLUT,
надо выполнить единственную команду:
void glutMainLoop(void);
Пример программы с использованием GLUT
#include <gl/glut.h>
#include <math.h>
//Функция изменения размеров и установки координат
void Reshape(int width, int height)
{
//Установка порта вывода
glViewport(0, 0, width, height);
//Режим матрицы проекций
glMatrixMode(GL_PROJECTION);
//Единичная матрица
glLoadIdentity();
//Установка двумерной ортографической системы координат
gluOrtho2D(-50., 50., -50., 50.);
//Режим видовой матрицы
glMatrixMode(GL_MODELVIEW);
}
//Функция визуализации
void Draw(void)
{
//Очистка цветового буфера
glClear(GL_COLOR_BUFFER_BIT);
//Установка цвета отображения
glColor3d(1.0, 1.0, 0.0);
//Рисование осей
glBegin(GL_LINES);
//Установка вершин
glVertex2d(-40., .0);
glVertex2d(40., .0);
glVertex2d(.0, -40.);
glVertex2d(.0, 40.);
//Завершить рисование осей
glEnd();
//Установка цвета отображения ломаной
glColor3d(0.0, 1.0, 1.0);
//Рисование ломаной линии
glBegin(GL_LINE_STRIP);
double x,y;
for(double fi=0; fi<20.*acos(0.); fi+=2.*acos(0.)/20.)
{
//Вычисление координат
x=fi*cos(fi);
y=fi*sin(fi);
//Установка вершины ломаной
glVertex2d(x, y);
}
//Завершить рисование ломанной
glEnd();
//Завершить выполнение команд
glFlush();
}
int main(int argc, char *argv[])
{
//Инициализация GLUT
glutInit(&argc, argv);
//Задание размеров окна
glutInitWindowSize(400, 300);
//Задание положения окна
glutInitWindowPosition(100, 100);
//Инициализация режимов
glutInitDisplayMode(GLUT_RGB);
//Задание заголовка окна
glutCreateWindow("Whirlpool");
//Определить функцию изменения размеров
glutReshapeFunc(Reshape);
//Определить функцию перерисовки
glutDisplayFunc(Draw);
//Определить цвет очистки
glClearColor(0, 0, 0, 1);
//Вход в главный цикл GLUT
glutMainLoop();
return 0;
}
|