❮ Назад в библиотеку

МЕТОДЫ ОПТИМИЗАЦИИ ПРОГРАММ КОМПЬЮТЕРНОЙ ГРАФИКИ OPENGL

Г.В. Князева

Аннотация: Из своего практического опыта автор показывает, как можно добиться высокого качества визуализации в программе OpenGL.

Ключевые слова: высокоуровневая оптимизация, структуры данных, приложение, интерполяция цветов, векторные версии команд, текстурированные объекты

Организация приложения

 На первый взгляд может показаться, что производительность приложений, основанных на OpenGL, определяется в первую очередь производительностью реализации самой библиотеки OpenGL. Это верно, однако организация всего приложения (использование локальных и глобальных переменных, структур данных, библиотек, последовательность выполнения команд) также очень важна.

Высокоуровневая оптимизация

 Обычно от программы под OpenGL требуется визуализация высокого качества на интерактивных скоростях. Но, как правило, и то и другое сразу получить не удается. Следовательно, необходим поиск компромисса между качеством и производительностью. Существует множество различных подходов к данному вопросу:

Низкоуровневая оптимизация

 Объекты, отображаемые с помощью OpenGL, хранятся в некоторых структурахданных. Скорость визуализации определяется эффективностью использования таких структур. Желательно, чтобы использовались структуры данных, которые могут быть быстро и эффективно переданы на конвейер OpenGL. Например, если необходимо отобразить массив треугольников, то использование указателя на этот массив значительно более эффективно, чем передача его OpenGL поэлементно.

 Предположим, что создается приложение, которое реализует рисование карты местности. Один из компонентов базы данных - список городов с их шириной, долготой и названием.

Для хранения информации о городе создается соответствующая структура данных. Список городов может храниться как массив таких структур. Затем создается функция, которая рисует города на карте в виде точек разного размера с подписями: если город маленький, то точки имеют размер 2 px, если большой - 4 px.

Реализация, представленная в первом варианте, неудачна по следующим причинам:

 Во втором варианте реализации glPointSize() вызывается только дважды, и увеличивается число вершин между glBegin() и glEnd(). Однако остаются еще пути для оптимизации. Если поменять структуры данных, то можго еще повысить эффективность рисования точек.

 Самым оптимальным можно считать третий вариант. После реорганизации структуры города разных размеров хранятся в разных списках, положения точек хранятся отдельно в динамическом массиве. Исключается необходимость в условном операторе внутри glBegin/glEnd и имеется возможность использовать массивы вершин для оптимизации.

Оптимизация вызовов opengl

 Существует много возможностей улучшения производительности OpenGL. К тому же разные подходы к оптимизации приводят к разным эффектам при аппаратной и программной визуализации. Например, интерполяция цветов может быть очень дорогой операцией без аппаратной поддержки, а при аппаратной визуализации почти не дает задержек.

Передача данных в opengl

 Рассмотрим способы минимизации времени на передачу данных о примитивах в OpenGL.

 Использование связанных примитивов, таких как GL_LINE_LOOP, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, и GL_QUAD_STRIP, требует для определения меньше вершин, чем отдельные линии или многоугольник. Это уменьшает количество данных, передаваемых OpenGL.

 Использование массивов для передачи параметров в команды может быть очень выигрышным. Вместо использования команд glVertexPointer/glColorPointer/glNormalPointer лучше пользоваться одной командой, как например, glInterleavedArrays (GL_C4F_N3F_V3F, 0, pData);, что означает, что первые четыре float относятся к цвету, затем три float - к нормали, и последние три float задают координаты вершины.

 Последовательное расположение данных в памяти улучшает скорость обмена между основной памятью и графической подсистемой.

 Использование векторных версий команд glVertex*(), glColor*(), glNormal*() и glTexCoord*(), которые в качестве аргументов принимают указатели (например, glVertex3fv(v)) могут работать значительно быстрее, чем их соответствующие версии glVertex3f(x, y, z).

 Уменьшение сложности примитивов при построении поверхностей. Текстурированные объекты, например, могут быть качественно отображены с небольшой сложностью геометрии.

 Использование дисплейных списков для наиболее часто выводимых объектов. Дисплейные списки могут храниться в памяти графической подсистемы и, следовательно, исключать частые перемещения данных из основной памяти.

 Не следует указывать ненужные атрибуты вершин. Например, если освещение выключено, не нужно вызывать glNormal(); если не используются текстуры, не нужно вызывать glTexCoord(), и т.д.

 Минимизация кода между glBegin/glEnd позволяет использовать максимальную производительность графической системы.

Преобразования

 Преобразования включают в себя трансформации вершин от координат, указанных в glVertex*(), к оконным координатам, отсечение, освещение и т.д.

 Рекомендации по применению освещения:

Растеризация

 Растеризация часто является узким местом программных реализаций OpenGL.

 Рекомендации по оптимизации растеризации:

Текстурирование

 Наложение текстур является дорогой операцией, как в программных, так и в аппаратных реализациях.

 Рекомендации по применению текстурирования:

Очистка буферов

 Очистка буферов цвета, глубины, маски и буфера-накопителя может требовать много времени, особенно в программных реализациях OpenGL.

 Рекомендации, которые могут помочь оптимизировать эту операцию:

Разное

 В данном разделе приведены рекомендации общего характера по оптимизации приложений OpenGL, которые нельзя отнести к какой-либо категории:

 Конечно, эти рекомендации охватывают лишь малую часть возможностей по оптимизации OpenGL-приложений. Тем не менее при их правильном использовании можно достичь существенного ускорения работы программ компьютерной графики OpenGL.

Литература