Главная » Просмотр файлов » Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC)

Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (1124366), страница 12

Файл №1124366 Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC)) 12 страницаЮ.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (1124366) страница 122019-05-11СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 12)

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

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

• Можно отображать геометрию сцены с низким качеством во время анимации, а в моменты остановок показывать ее с

115

116

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

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

• Аналогично, объекты, которые располагаются далеко от наблюдателя, могут быть представлены моделями пони­женной сложности. Это значительно снизит нагрузку на все ступени конвейера OpcnGL. Объекты, которые нахо­дятся полностью вне поля видимости, могут быть эффек­тивно отсечены без передачи на конвейер OpcnGL с по­мощью проверки попадания ограничивающих их простых объемов (сфер или кубов) в пирамиду зрения.

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

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

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

Пример. Предположим, что мы пишем приложение, которое реализует рисование карты местности. Один из компонентов ба­зы данных — список городов с их шириной, долготой и названи­ем. Соответствующая структура данных может быть такой:

struct city

{

float latitute , longitude; /* положение города */
char *name; /* название */

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

117

int large_flag; /* 0 = маленький, 1 = большой */

};

Список городов может храниться как массив таких структур. Допустим, мы пишем функцию, которая рисует города на карте в виде точек разного размера с подписями:

void draw_cities( int n, struct city citylist [] )

{

int i ;

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

{

if ( citylist [ i ]. large_flag)

glPointSize( 4.0 ); else

glPointSize( 2.0 );

glBegin( GL_POINTS );

glVertex2f( citylist [ i ] . longitude ,

city list [ i ]. latitude ); glEnd();

/* рисуем название, города */ DrawText ( citylist [ i ] . longitude , citylist [ i ] . latitude , citylist [ i ] . name); } }

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

  • glPointSize вызывается для каждой итерации цикла;

  • между glBegin и glEnd рисуется только одна точка;

  • вершины определяются в неоптимальном формате.

Ниже приведено более рациональное решение:

void draw_cities( int n, struct city citylist [] ) {

118

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

}

int i ;

/* сначала рисуем маленькие точки */ glPointSize( 2.0 ); glBegin( GL_POINTS ); for ( i=0; i < n ; i++)

{

if ( city list [ i ]. large_flag==0) {

glVertex2f( citylist [ i ] . longitude , city list [ i ]. latitude ); } }

glEnd();

/* большие точки рисуем во вторую очередь */ glPointSize( 4.0 ); glBegin( GL_POINTS ); for ( i=0; i < n ; i++)

{

if ( city list [ i ]. large_flag==l)

{

glVertex2f( citylist [ i ] . longitude , city list [ i ]. latitude ); } } glEnd();

/* затем рисуем названия городов */ for ( i=0; i < n ; i++)

{

DrawText ( citylist [ i ] . longitude ,

citylist [i]. latitude ,

citylist [i]. name ) ; }

В такой реализации мы вызываем glPointSize дважды и уве­личиваем число вершин между glBegin и glEnd.

Однако остаются еще пути для оптимизации. Если мы поме-

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

119

няем наши структуры данных, то можем еще повысить эффек­тивность рисования точек. Например:

struct city list

{ _

int num_cities; /* число городов в списке */

float ^position;/* координаты города */

char **name; /* указатель на названия городов */

float size ; /* размер точки, обозначающей город */

};

Теперь города разных размеров хранятся в разных списках. Положения точек хранятся отдельно в динамическом массиве. После реорганизации мы исключаем необходимость в условном операторе внутри glBegin/glEnd и получаем возможность исполь­зовать массивы вершин для оптимизации. В результате наша функция выглядит следующим образом:

void draw_cities( struct city list * 1 i s t )

{

int i ;

/* рисуем точки */ glPointSize( list —>size );

glVertexPointer( 2, GL_FLOAT, 0,

list —>num_cities ,

list —>position ) ; glDrawArrays( GL_POINTS, 0, list->num_cities ); /* рисуем название города */ for (i=0; i < list —>num_cities ; i++)

{

DrawText( citylist [ i ] . longitude , citylist [ i ] . latitude citylist [i].name); } }

120

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

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

9.2.1. Передача данных в OpenGL

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

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

Связанные примитивы, такие как 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. Оптимизация программ

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

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

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

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

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

Характеристики

Тип файла
Документ
Размер
3,41 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6439
Авторов
на СтудИзбе
306
Средний доход
с одного платного файла
Обучение Подробнее