Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (1124366), страница 13
Текст из файла (страница 13)
Анимированные текстуры
Если вы хотите использовать анимированные текстуры, не используйте команду glTexImage2D чтобы обновлять образ текстуры. Вместо этого рекомендуется вызывать glTexSubImage2D или glTexCopyTexSubImage2D.
9.2.5. Очистка буферов
Очистка буферов цвета, глубины, маски и буфера-накопителя может требовать значительного времени. В этом разделе описаны некоторые приемы, которые могут помочь оптимизировать эту операцию.
Используйте команду glClear с осторожностью
Очищайте все нужные буферы с помощью одной команды glClear.
Неверно:
9.2. Оптимизация вызовов OPENGL
127
g 1С1 е а г (GL_COLOR_BUFFER_BEr) ;
if (stenciling) /* очистить буфер маски? */
{
g 1С1 е а г (GL_STENCIL_BUFFER_Brr);
}
Верно:
if (stenciling) /* очистить буфер маски? */
{
g 1С1 е а г (GL_COLOR_BUFFER_BIT | STENCIL_BUFFER_BIT);
} else
{
glClear (GL_COLOR_BUFFER_Brr) ;
}
9.2.6. Разное
Проверяйте ошибки GL во время написания программ
Вызывайте команду glGetError() для проверки, не произошло ли ошибки во время вызова одной из функций OpenGL. Как правило, ошибки возникают из-за неверных параметров команд OpenGL или неверной последовательности команд. Для финальных версий кода отключайте эти проверки, так как они могут существенно замедлить работу. Для проверки можно использовать, например, такой макрос:
^include <assert.h> #define CHECK_GL \
assert (glGetErrorQ != GL_NO_ERROR);
Использовать его можно так:
glBegin (GL_TRIANGLES); glVertex3f (1 ,1 ,1); glEnd();
128
Глава 9. Оптимизация программ
CHECK_GL;
Используйте glColorMaterial вместо glMaterial
Если в сцене материалы объектов различаются лишь одним параметром, команда glColorMaterial может быть быстрее, чем glMaterial.
Минимизируйте число изменений состояния OpenGL
Команды, изменяющие состояние OpenGL (glEnable, glDisable, glBindTexture и другие), вызывают повторные внутренние проверки целостности, создание дополнительных структур данных и т.д., что может приводить к задержкам.
Избегайте использования команды glPolygonMode
Если вам необходимо рисовать много незакрашенных многоугольников, используйте glBegin с GL_POINTS, GL_LINES, GL_LINE_LOOP или GL_LINE_STRIP вместо изменения режима рисования примитивов, так как это может быть намного быстрее.
Конечно, эти рекомендации охватывают лишь малую часть возможностей по оптимизации OpenGL-приложений. Тем не менее, при их правильном использовании можно достичь существенного ускорения работы ваших программ.
9.3. Контрольные вопросы
-
Перечислите известные вам методы высокоуровневой оптимизации OpenGL-приложений.
-
Почему предпочтительнее использование связанных примитивов?
9.3. Контрольные вопросы
129
3) Какая из двух команд выполняется OpenGL быстрее? glVertex3f (1 ,1 ,1);
или
float vet [3] = {1 ,1 ,1}; glVertex3fv ( vet );
Часть III
Создание приложений с OpenGL
131
Глава 10.
OpenGL-приложения с помощью GLUT
10.1. Структура GLUT-приложения
Далее будем рассматривать построение консольного приложения при помощи библиотеки GLUT. Эта библиотека обеспечивает единый интерфейс для работы с окнами вне зависимости от платформы, поэтому описываемая ниже структура приложения остается неизменной для операционных систем Windows, Linux и других.
Функции GLUT могут быть классифицированы на несколько групп по своему назначению:
-
инициализация;
-
начало обработки событий;
-
управление окнами;
-
управление меню;
-
регистрация функций с обратным вызовом;
133
134 Глава 10. OPENGL-приложения с помощью GLUT
-
управление индексированной палитрой цветов;
-
отображение шрифтов;
-
отображение дополнительных геометрических фигур (тор, конус и др.).
Инициализация проводится с помощью функции:
glutlnit (int *argcp , char **argv)
Переменная argcp есть указатель на стандартную переменную argc, описываемую в функции main(), a argv — указатель на параметры, передаваемые программе при запуске, который описывается там же. Эта функция проводит необходимые начальные действия для построения окна приложения, и только несколько функций GLUT могут быть вызваны до нее. К ним относятся:
glutlnitWindowPosition (int x, int у) glutlnitWindowSize (int width, int height) glutlnitDisplayMode (unsigned int mode)
Первые две функции задают соответственно положение и размер окна, а последняя функция определяет различные режимы отображения информации, которые могут совместно задаваться с использованием операции побитового «или» (« | »):
GLUT_RGBA Режим RGBA. Используется по умолчанию, если не указаны режимы GLUT_RGBA или GLUT_INDEX.
GLUT_RGB To же, что и GLUT_RGBA.
GLUT INDEX Режим индексированных цветов (использование палитры). Отменяет GLUT_RGBA.
GLUT_SINGLE Окно с одиночным буфером. Используется по умолчанию.
GLUT_DOUBLE Окно с двойным буфером. Отменяет GLUT SINGLE.
10.1. Структура GLUT-приложения
135
GLUT_STENCIL Окно с буфером маски. GLUT_ACCUM Окно с буфером-накопителем. GLUT_DEPTH Окно с буфером глубины.
Это неполный список параметров для данной функции, однако для большинства случаев этого бывает достаточно.
Работа с буфером маски и буфером накопления описана в главе 7.
Функции библиотеки GLUT реализуют так называемый со-бытийно-управляемый механизм. Это означает, что есть некоторый внутренний цикл, который запускается после соответствующей инициализации и обрабатывает одно за другим все события, объявленные во время инициализации. К событиям относятся: щелчок мыши, закрытие окна, изменение свойств окна, передвижение курсора, нажатие клавиши и «пустое» (idle) событие, когда ничего не происходит. Для проведения периодической проверки совершения того или иного события надо зарегистрировать функцию, которая будет его обрабатывать. Для этого используются функции вида:
void glutDisplayFunc (void (*func) (void)) void glutReshapeFunc (void (*func) (int width,
int height)) void glutMouseFunc (void (*func) (int button,
int state , int x, int y)) void glutldleFunc (void (*func) (void)) void glutMotioiiFimc (void (* func) (int x, int y)); void glutPassiveMotionFunc (
void (*func)(int x, int y));
Параметром для них является имя соответствующей функции заданного типа. С помощью glutDisplayFimc() задается функция рисования для окна приложения, которая вызывается при необходимости создания или восстановления изображения. Для
136 Глава 10. OPENGL-приложения с помощью GLUT
явного указания, что окно надо обновить, иногда удобно использовать функцию
void glutPostRedisplay (void)
Через glutReshapeFuncQ устанавливается функция обработки изменения размеров окна пользователем, которой передаются новые размеры.
glutMouseFimcQ определяет функцию-обработчик команд от мыши, a glutldleFuncQ задаст функцию, которая будет вызываться каждый раз, когда нет событий от пользователя.
Функция, определяемая glutMotionFuncQ, вызывается, когда пользователь двигает указатель мыши, удерживая кнопку мыши. glutPassiveMotionFiinc регистрирует функцию, вызываемую, если пользователь двигает указатель мыши и не нажато ни одной кпопки мыши.
Контроль всех событий происходит внутри бесконечного цикла в функции
void glutMainLoop (void)
которая обычно вызывается в конце любой программы, использующей GLUT. Структура приложения, использующего анимацию, будет следующей:
#include <GL/glut.h>
void Myldle(void)
{
/* Код, который меняет переменные, определяющие следующий кадр */
"};
void MyDisplay (void)
{ /* Код OpenGL, который отображает кадр */
10.2. GLUT в среде MICROSOFT VISUAL C++ 6.0 137
/* После рисования переставляем буферы */ glutSwapBuffers ();
};
void main(int argcp , char **argv)
{ /* Инициализация GLUT */ glutlnit (feargcp, argv); glutInitWindowSize(640, 480); glutlnitWindowPosition (0 , 0); /* Открытие окна */
glutCreateWindow ( "My„OpenGLw Application " ) ; /* Выбор режима: двойной буфер и RGBA цвета */ glutlnitDisplayMode (GLUT_RGBA |
GLUT_DOUBLE | GLIJT_DEFTH); /* Регистрация вызываемых функций */ glutDisplayFunc (MyDisplay ) ; glutldleFunc(Myldle) ;
/* Запуск механизма обработки событий */ glutMainLoop () ;
};
В случае , если приложение должно строить статичное изображение, можно заменить GLUT_DOUBLE на GLUT_SINGLE, так как одного буфера в этом случае будет достаточно, и убрать вызов функции glutldleFuncQ.
10.2. GLUT в среде Microsoft Visual C++ 6.0
Перед началом работы необходимо скопировать файлы glut.h, glut32.1ib glut32.dll в каталоги MSVC\Include\Gl, MSVC\Lib, Windows\System соответственно. Также в этих каталогах надо проверить наличие файлов gl.h, glu.h, opengl32.1ib, glu32.1ib, opengl32.dll, glu32.dll, которые обычно входят в состав Visual C++ и Windows. При использовании команд из библиотеки
138 Глава 10. OPENGL-приложения с помощью GLUT
GLAUX к перечисленным файлам надо добавить подключаемые файлы библиотеки — glaux.h и glaux.lib.
Для создания приложения надо выполнить следующие действия:
-
Создание проекта: для этого надо выбрать File—>New—> Projects—^Win32 Console Application, набрать имя проекта, ОК.
-
В появившемся окне выбрать «An empty project», Finish, ОК.
-
Текст программы можно либо разместить в созданном текстовом файле (выбрав File—>New—>Files—>Text File), либо добавить файл с расширением *.с или *.срр в проект (выбрав Project—)► Add To Project—s^Files).
-
Подключить к проекту библиотеки OpenGL. Для этого надо выбрать Project—^Settings—>Link и в поле Object\library modules набрать названия нужных библиотек: opengl32.1ib, glu32.1ib, glut32.1ib и, если надо, glaux.lib.
-
Для компиляции выбрать Build—>Build program.exe, для выполнения — Build—>Execute program.exe.
-
Чтобы при запуске не появлялось текстовое окно, надо выбрать Project—>Settings—>Link и в поле Project Options вместо «subsystem:console» набрать «subsystem:windows», и набрать там же строку «/cntry:mainCRTStartup».
Когда программа готова, рекомендуется перекомпилировать ее в режиме «Release» для оптимизации по быстродействию и объему. Для этого надо выбрать Build—>Set Active Configuration и отметить «... -Win32 Release», а затем заново подключить необходимые библиотеки.
10.3. GLUT в среде MICROSOFT VISUAL C++ 2005 139
10.3. GLUT в среде Microsoft Visual C++ 2005
Перед началом работы необходимо скопировать файлы glut.h, glut32.1ib и glut32.dll в каталоги MVS8\VC\PlatformSDK\Include, MVS8\VC\PlatformSDK\Lib, Windows\System соответственно. Также в этих каталогах надо проверить наличие файлов gl.h, glu.h, opengl32.1ib, glu32.1ib, opengl32.dll, glu32.dll, которые обычно входят в состав Visual СИ—Ь и Windows. При использовании команд из библиотеки GLAUX к перечисленным файлам надо добавить подключаемые файлы библиотеки — glaux.h и glaux.lib.
Для создания приложения надо выполнить следующие действия:
-
Создание проекта: для этого надо выбрать File—>New—> Projects—>Win32—>Win32 Console Application, набрать имя проекта, ОК.
-
В появившемся окне во вкладке Application Settings выбрать «Console application», «An empty project», Finish.
-
Текст программы можно либо разместить в созданном текстовом файле (выбрав File—>New—>Files—>Visual C+H—> C++File ), либо добавить файл с расширением *.с или *.срр в проект (выбрав Project—>Add To Project—>Files).
-
Подключить к проекту библиотеки OpenGL. Для этого надо выбрать Project—^Properties—^Configuration Properties—> Linker—>Input и в поле Additional dependencies набрать названия нужных библиотек: opengl32.1ib, glu32.1ib, glut32.1ib и, если надо, glaux.lib.
-
Для компиляции выбрать Build—> program.exe, для выполнения—Debug—> Start Debugging или Debug—>Start Without Debugging.
140 Глава 10. OPENGL-приложения с помощью GLUT
• Чтобы при запуске программы не появлялось консольное текстовое окно, надо выбрать Project—^Properties—» Configuration Properties—^Linker—^System и в поле SubSystem вместо «Console» выбрать «Windows». Перейти в раздел Linker—> Advanced и в поле Entry Point написать «wmainCRTStartup» (без кавычек).