Главная страница

Руководство по работе с графической библиотекой OpenGL. Руководство разработано с учетом опыта чтения курса Компьютерная графика


Скачать 0.66 Mb.
НазваниеРуководство по работе с графической библиотекой OpenGL. Руководство разработано с учетом опыта чтения курса Компьютерная графика
Дата21.10.2022
Размер0.66 Mb.
Формат файлаdocx
Имя файла221937-83556.docx
ТипРуководство
#747097
страница17 из 30
1   ...   13   14   15   16   17   18   19   20   ...   30
Используйте связанные примитивы

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

Используйте массивы вершин

На большинстве архитектур замена множественных вызовов glVertex/glColor/glNormal на механизм массивов вершин может быть очень выигрышной.

Используйте индексированные примитивы

В некоторых случаях даже при использовании связанных примитивов GL_TRIANGLE_STRIP (GL_QUAD_STRIP) верши­ны дублируются. Чтобы не передавать в OpenGL дубли, увели­чивая нагрузку на шину, используйте команду glDrawElementsQ.

Задавайте необходимые массивы одной командой

Вместо использования команд glVertexPointer, glColorPointer, glNormalPointer лучше пользоваться одной командой

void glinterleavedArrays ( Glint format,

Glsizei stride , void * ptr);

9.2. Оптимизация вызовов OPENGL

121

Так, если имеется структура

typedef struct tag_VERTEX_DATA

{

float color [4];

float normal [3]; float vertex [3]; }VERTEX_DATA; VERTEX_DATA * pData;

то параметры можно передать с помощью следующей команды gllnterleavedArrays (GL_C4F_N3F_V3F, 0, pData);

что означает, что первые четыре float относятся к цвету, затем три float к нормали, и последние три float задают координаты вершины. Более подробное описание команды смотрите в специ­фикации OpenGL.

Храните данные о вершинах в памяти последовательно

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

Используйте векторные версии glVertex, glColor, glNormal и glTexCoord.

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

Уменьшайте сложность примитивов

Во многих случаях будьте внимательны, чтобы не разбивать большие плоскости на части сильнее, чем необходимо. Поэкс­периментируйте, например, с примитивами GLU для определе­ния наилучшего соотношения качества и производительности.

122

Глава 9. Оптимизация программ

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

Используйте дисплейные списки

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

Не указывайте ненужные атрибуты вершин

Если освещение выключено, не вызывайте glNormal. Если не используются текстуры, не вызывайте glTexCoord, и т.д.

Минимизируйте количество лишнего кода между опера­торными скобками glBegin/glEnd

Для максимальной производительности на high-end системах важно, чтобы информация о вершинах была передана графиче­ской подсистеме максимально быстро. Избегайте лишнего кода между glBegin/glEnd.

Пример неудачного решения:

g 1В е g i n (GL_TRIANGLE_STRIP); for (i=0; i < n; i++)

{

if (light ing )

{

glNormal3fv (norm [ i ]) ;

}

glVertex3fv(vert [i ]) ;

}

glEnd();

9.2. Оптимизация вызовов OPENGL

123

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

if (lighting )

{

glBegin (GL_TRIANGLE_STRIP);

for (i=0; i < n ; i++)

{

glNormal3fv (norm [ i ]) ; glVertex3fv(vert [i ]) ;

}

glEnd();

} else

{

glBegin (GL_TRIANGLE_STRIP);

for (i=0; i < n ; i++)

{

glVertex3fv(vert [i ]) ;

} glEnd();

}

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

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

Освещение

  • Избегайте использования точечных источников света.

  • Избегайте использования двухстороннего освещения (two-sided lighting).

124

Глава 9. Оптимизация программ

  • Избегайте использования локальной модели освещения.

  • Избегайте частой смены параметра GL_SHININESS.

  • Рассмотрите возможность заранее просчитать освещение. Можно получить эффект освещения, задавая цвета вершин вместо нормалей.

Отключайте нормализацию векторов нормалей, когда это не является необходимым

Команда glEnable/Disable(GL_NORMALIZE) управляет норма­лизацией векторов нормалей перед использованием. Если вы не используете команду glScale, то нормализацию можно отключить без посторонних эффектов. По умолчанию эта опция выключена.

Используйте связанные примитивы

Связанные примитивы, такие как GL_LINES, GL_LINE_LOOP, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, и GL_QUAD_STRIP уменьшают нагрузку на конвейер OpenGL, а также уменьшают количество данных, передаваемых графи­ческой подсистеме.

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

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

Отключайте тест на глубину, когда в этом нет необходи­мости

Фоновые объекты, например, могут быть нарисованы без те­ста на глубину, если они визуализируется первыми.

9.2. Оптимизация вызовов OPENGL

125

Используйте отсечение обратных граней полигонов

Замкнутые объекты могут быть нарисованы с установленным режимом отсечения обратных граней glEnable(GL_CULL_FACE) Иногда это позволяет отбросить до половины многоугольников, не растеризуя их.

Избегайте лишних операций с пикселями

Маскирование, альфа-смешивание и другие попикссльныс операции могут занимать существенное время на этапе расте­ризации. Отключайте все операции, которые вы не используете.

Уменьшайте размер окна или разрешение экрана

Простой способ уменьшить время растеризации — уменьшить число пикселей, которые будут нарисованы. Если меньшие раз­меры окна или меньшее разрешение экрана приемлемы, то это хороший путь для увеличения скорости растеризации.

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

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

Используйте эффективные форматы хранения изобра­жений

Формат GL_UNSIGNED_BYTE обычно наиболее всего подхо­дит для передачи текстуры в OpenGL.

Объединяйте текстуры в текстурные объекты или дис­плейные списки.

Это особенно важно, если вы используете несколько текстур, и позволяет графической подсистеме эффективно управлять

126

Глава 9. Оптимизация программ

размещением текстур в видеопамяти.

Не используйте текстуры большого размера

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

Комбинируйте небольшие текстуры в одну

Если вы используете несколько маленьких текстур, то можно объединить их в одну большего размера и изменить текстурные координаты для работы с нужной подтекстурой. Это позволяет уменьшить число переключений текстур.

Анимированные текстуры

Если вы хотите использовать анимированные текстуры, не используйте команду 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);

}
1   ...   13   14   15   16   17   18   19   20   ...   30


написать администратору сайта