Файл: графическая библиотека opengl.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 09.06.2020

Просмотров: 1707

Скачиваний: 4

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 81

Чтобы

 

не

 

передавать

 

в

 OpenGL 

дубли

увеличивая

 

нагрузку

 

на

 

шину

используйте

 

команду

 

glDrawElements() 

(

см

раздел

 

2.5.) [

все

Задавайте

 

необходимые

 

массивы

 

одной

 

командой

Вместо

 

использования

 

команд

 

glVertexPointer/glColorPointer/glNormalPointer

 

лучше

 

пользоваться

 

одной

 

командой

 

void glInterleavedArrays ( Glint format,  
                           Glsizei stride,  
                           void * ptr); 

так

если

 

имеется

  

структура

 

typedef struct tag_VERTEX_DATA 


float color[4]; 

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

VERTEX_DATA * pData; 

то

 

параметры

 

можно

 

передать

 

с

 

помощью

 

следующей

 

команды

 

glInterleavedArrays (GL_C4F_N3F_V3F, 0, pData); 

что

 

означает

что

 

первые

 

четыре

 float 

относятся

 

к

 

цвету

затем

 

три

 float  

к

 

нормали

и

 

последние

 

три

 float  

задают

 

координаты

 

вершины

.  

Более

 

подробное

 

описание

 

команды

 

смотрите

 

в

 

спецификации

 OpenGL. [

все

Храните

 

данные

 

о

 

вершинах

 

в

 

памяти

 

последовательно

.  

Последовательное

 

расположение

 

данных

 

в

 

памяти

 

улучшает

 

скорость

 

обмена

 

между

 

основной

 

памятью

 

и

 

графической

 

подсистемой

. [

А

]  

Используйте

 

векторные

 

версии

 

glVertex

glColor

glNormal

 

и

 

glTexCoord

Функции

 

glVertex*(), glColor*()

 

и

 

т

.

д

., 

которые

 

в

 

качестве

 

аргументов

 

принимают

 

указатели

  (

например

glVertex3fv(v)

могут

 

работать

 

значительно

 

быстрее

чем

 

их

 

соответствующие

 

версии

 

glVertex3f(x,y,z)

 [

все

]  

Уменьшайте

 

сложность

 

примитивов

.  


background image

 82

Во

 

многих

 

случаях

 

будьте

 

внимательны

чтобы

 

не

 

разбивать

 

большие

 

плоскости

 

на

 

части

 

сильнее

чем

 

необходимо

Поэкспериментируйте

например

с

 

примитивами

 GLU 

для

 

определения

 

наилучшего

 

соотношения

 

качества

 

и

 

производительности

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

 

объекты

например

могут

 

быть

 

качественно

 

отображены

 

с

 

небольшой

 

сложностью

 

геометрии

.  [

все

]  

Используйте

 

дисплейные

 

списки

.  

Используйте

 

дисплейные

 

списки

 

для

 

наиболее

 

часто

 

выводимых

 

объектов

Дисплейные

 

списки

 

могут

 

храниться

 

в

 

памяти

 

графической

 

подсистемы

 

и

следовательно

исключать

 

частые

 

перемещения

 

данных

 

из

 

основной

 

памяти

. [

А

]  

Не

 

указывайте

 

ненужные

 

атрибуты

 

вершин

  

Если

 

освещение

 

выключено

не

 

вызывайте

 

glNormal

Если

 

не

 

используются

 

текстуры

не

 

вызывайте

 

glTexCoord

и

 

т

.

д

. [

все

]  

Минимизируйте

 

количество

 

лишнего

 

кода

 

между

 

glBegin/glEnd

  

Для

 

максимальной

 

производительности

 

на

 high-end 

системах

 

важно

чтобы

 

информация

 

о

 

вершинах

 

была

 

передана

 

графической

 

подсистеме

 

максимально

 

быстро

Избегайте

 

лишнего

 

кода

 

между

 

glBegin/glEnd

.    

  

Пример

 

неудачного

 

решения

 glBegin(GL_TRIANGLE_STRIP); 
 for (i=0; i < n; i++)  
 { 
    if (lighting) 
    { 
       glNormal3fv(norm[i]); 
    } 
    glVertex3fv(vert[i]); 
 } 
 glEnd(); 

 

Эта

 

конструкция

 

плоха

 

тем

что

 

мы

 

проверяем

 

переменную

 

lighting

 

перед

 

каждой

 

вершиной

Этого

 

можно

 

избежать

за

 

счет

 

частичного

 

дублирования

 

кода

:  

if (lighting) 


background image

 83


   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(); 

8.2.2. 

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

  

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

 

включают

 

в

 

себя

 

трансформации

 

вершин

 

от

 

координат

указанных

 

в

  g

lVertex*(),

 

к

 

оконным

 

координатам

отсечение

освещение

 

и

 

т

.

д

 

Освещение

  

 

Избегайте

 

использования

 

локальных

 

источников

 

света

т

.

е

координаты

 

источника

 

должны

 

быть

 

в

 

форме

 (x,y,z,0) [

П

]  

 

Избегайте

 

использования

 

точечных

 

источников

 

света

. [

все

]  

 

Избегайте

 

использования

 

двухстороннего

 

освещения

 (two-

sided lighting). [

все

]  

 

Избегайте

 

использования

 

отрицательные

 

коэффициентов

 

в

 

параметрах

 

материала

 

и

 

цвета

. [

П

]  

 

Избегайте

 

использования

 

локальной

 

модели

 

освещения

 .[

все

]  

 

Избегайте

 

частой

 

смены

 

параметра

 

материала

  

GL_SHININESS

 

[

П

]  

 

Некоторые

 

реализации

 OpenGL 

оптимизированы

 

для

 

случая

 

одного

 

источника

 

света

 [

А

П

]  


background image

 84

 

Рассмотрите

 

возможность

 

заранее

 

просчитать

 

освещение

Можно

 

получить

 

эффект

 

освещения

задавая

 

цвета

 

вершин

 

вместо

 

нормалей

. [

все

]  

Отключайте

 

нормализацию

 

векторов

 

нормалей

когда

 

это

 

не

 

необходимо

.  

Команда

 

glEnable/Disable(GL_NORMALIZE)

 

управляет

 

нормализацией

 

векторов

 

нормалей

 

перед

 

использованием

Если

 

вы

 

не

 

используете

 

команду

 

glScale

то

 

нормализацию

 

можно

 

отключить

 

без

 

посторонних

 

эффектов

По

 

умолчанию

 

эта

 

опция

 

выключена

. [

все

]  

Используйте

 

связанные

 

примитивы

.  

Связанные

 

примитивы

такие

 

как

 

GL_LINES

GL_LINE_LOOP

GL_TRIANGLE_STRIP

GL_TRIANGLE_FAN

и

 

GL_QUAD_STRIP

 

уменьшают

 

нагрузку

 

на

 

конвейер

 OpenGL, 

а

 

также

 

уменьшают

 

количество

 

данных

передаваемых

 

графической

 

подсистеме

.  

8.2.3. 

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

 

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

 

часто

 

является

 

узким

 

местом

 

программных

 

реализаций

 

OpenGL.  

Отключайте

 

интерполяцию

 

цветов

когда

 

в

 

этом

 

нет

 

необходимости

  

Интерполяция

 

цветов

 

включена

 

по

 

умолчанию

Плоское

 

затенение

 

не

 

требует

 

интерполяции

 

четырех

 

компонент

 

цвета

 

и

как

 

правило

быстрее

 

на

 

программных

 

реализациях

 OpenGL. 

Аппаратные

 

реализации

 

обычно

 

выполняют

 

оба

 

вида

 

затенения

 

с

 

одинаковой

 

скоростью

Для

 

отключения

 

используйте

 

команду

 

glShadeModel(GL_FLAT)

 [

П

]  

Отключайте

 

тест

 

на

 

глубину

когда

 

в

 

этом

 

нет

 

необходимости

.  

Фоновые

 

объекты

например

могут

 

быть

 

нарисованы

 

без

 

теста

 

на

 

глубину

если

 

они

 

визуализируется

 

первыми

 [

все

]  

Используйте

 

отсечение

 

обратных

 

граней

 

полигонов

 

Замкнутые

 

объекты

 

могут

 

быть

 

нарисованы

 

с

 

установленным

 

режимом

 

отсечения

 

обратных

 

граней

 

g

lEnable(GL_CULL_FACE)

 

Иногда

 

это

 

позволяет

 

отбросить

 

до

 

половины

 

многоугольников

не

 

растеризуя

 

их

.[

все

]  


background image

 85

Избегайте

 

лишних

 

операций

 

с

 

пикселями

 

Маскирование

альфа

-

смешивание

 

и

 

другие

 

попиксельные

 

операции

 

могут

 

занимать

 

существенное

 

время

 

на

 

этапе

 

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

Отключайте

 

все

 

операции

которые

 

вы

 

не

 

используете

. [

все

]  

Уменьшайте

 

размер

 

окна

 

или

 

разрешение

 

экрана

 

Простой

 

способ

 

уменьшить

 

время

 

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

 – 

уменьшить

 

число

 

пикселей

которые

 

будут

 

нарисованы

Если

 

меньшие

 

размеры

 

окна

 

или

 

меньшее

 

разрешение

 

экрана

 

приемлемы

то

 

это

 

хороший

 

путь

 

для

 

увеличения

 

скорости

 

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

. [

все

]  

8.2.4. 

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

  

Наложение

 

текстур

 

является

 

дорогой

 

операцией

как

 

в

 

программных

так

 

и

 

в

 

аппаратных

 

реализациях

 

Используйте

 

эффективные

 

форматы

 

хранения

 

изображений

  

Формат

 GL_UNSIGNED_BYTE 

обычно

 

наиболее

 

всего

 

подходит

 

для

 

передачи

 

текстуры

 

в

 OpenGL. [

все

]  

Объединяйте

 

текстуры

 

в

 

текстурные

 

объекты

 

или

 

дисплейные

 

списки

.  

Это

 

особенно

 

важно

если

 

вы

 

используете

 

несколько

 

текстур

 

и

 

позволяет

 

графической

 

подсистеме

 

эффективно

 

управлять

 

размещением

 

текстур

 

в

 

видеопамяти

. [

все

]  

Не

 

используйте

 

текстуры

 

большого

 

размера

 

Небольшие

 

текстуры

 

быстрее

 

обрабатываются

  

и

 

занимают

 

меньше

 

памяти

что

 

позволят

 

хранить

 

сразу

 

несколько

 

текстур

 

в

 

памяти

 

графической

 

подсистемы

 [all]  

Комбинируйте

 

небольшие

 

текстуры

 

в

 

одну

 

Если

 

вы

 

используете

 

несколько

 

маленьких

 

текстур

можно

 

объединить

 

их

 

в

 

одну

 

большего

 

размера

 

и

 

изменить

 

текстурные

 

координаты

 

для

 

работы

 

нужной

 

подтекстурой

Это

 

позволяет

 

уменьшить

 

число

 

переключений

 

текстур

.  

Анимированные

 

текстуры

 

Если

 

вы

 

хотите

 

использовать

 

анимированные

 

текстуры

не

 

используйте

 

команду

 

glTexImage2D

 

чтобы

 

обновлять

 

образ