М. Ву, Т. Девис, Дж. Нейдер, Д. Шрайнер - OpenGL. Руководство по программированию (Библиотека программиста) (2006) (1124363), страница 52
Текст из файла (страница 52)
10, О, 8, 9, О, 1, 9); / ° Поворот относительна оси х при нажатии клавиши «х»; вращение вокруг оси у яря нажатии клавиши «у»; прн нажатии клавиши «!» тор возвращается з оригинальное представление '/ чз!б кеуьоагб(цпз!Впеб сьаг кеу, тпс х, !пт у) ( зн!топ (Кеу) ( сазе 'х': сазе 'Х': 81йотатет(38., 1.9, 6,9. 9,9); 91цсРоз(Реб!зр1ау(): Ьгеак; сазе 'у': сазе 'у'; 9)Погасят(39..
6.0, 1.0, 9.9); 91ц(Розсйеб!зР1аУ(): Ьгеах; продолжение бг 242 Глава 7 ° Списки отображения Листинг 7.1 (продолжение) сазе '1': саве '!': 81(оаб1бепг1Су<); Х!ц(оома!<8, 8, !8, 8, О, О, 8, 1, 8); 8!цсРозсйеб!50!ау О; Ьгеак; сазе 22; ех1с(8); Ьгеай; !пС иа1п<1пС агхс, слаг **агхч) 81цС1п!СИ1пбон51се(200, 280); 81цС1п1С(аагхс, агач); Б!ЬС<п1101881аунобе(6СВТ 5!ИВСЕ < 6<ОТ й68); 81цссгеасеи1пбои<агхч<8]): сп1с(); 8\цгйезпарегцпс<гезпаре); 8!цтхеуЬоагбгцпс<йеуЬоагб); 8!цС01зр1аугцпс<б1зр1ау); 8!ЦСИа1п(оор О: гесцгп 0; В первую очередь посмотрим на процедуру сп)С().
Она создает список отображения для тора и устанавливает начальные состояния переменных рендерингз. Заметьте, что подпрограмма для рисования тора (со го 5 () ) обрамлена командами к!иене<В! () и й(епбес5 с (), которые определяют начало и конец списка отображения соответственно. Аргумент ЫА<апсе метода к1иеньсзс Π— это целочисленный индекс, сгенерированный командой к16еп<.15!ВО, уникальным образом идентифицирующий список отображения. Пользователь может вращать тор относительно оси х или у, нажимая клавиши )< или У, когда окно получает фокус клавиатуры.
Всякий раз при этом происходит вызов функции йеуЬоагб(), которая накладывает матрицу поворота на 30' (относительно осей х и у) на текущую модельно-видовую матрицу. Команда й1цсРозтйебсзр1ау() своим вызовом влечет перерисовку тора функцией бсзр1ау() в цикле к1цснаспЕоор() после того, как будут обработаны другие события.
По нажатии клавиши 1 функция йеуЬоагбО восстанавливает начальную модельно-видовую матрицу и возвращает тор в оригинальное положение. Процедура б<зр1ау() очень проста. Она очищает окно, а затем вызывает команду к16з11Ь1 зс () для выполнения команд списка отображения. Если бы мы не использовали списки отображения, процедура бсзр1ау () выдавала бы распоряжение на перерисовку тора при каждом своем вызове. Список отображения содержит исключительно ОрепС(.-команды. В листинге 7.1 в таком списке сохранены только вызовы к1Вей1п(), я11<егтехО и к1Епб().
Их Философия проектирования списков отображения 243 параметры являются вычисляемыми, а результирующие значения копируются в список отображения перед его созданием. Все тригонометрические расчеты пропзподятся только единожды, с целью увеличить производительность рендеринга Значения в списке отображения не могут быть изменены позднее, а команда, помещенная в список, — из него удалена. Также вы не можете добавить новые коканды в список после того, как он был описан. То есть вы вправе удалить имеющпйся список и создать вместо него новый, но не редактировать уже определенный. ПРИМЕЧАНИЕ Списки отображения хорошо сочетаются с командамн бнблнотекн 61.0, поскольку зтм операции в конечном счете разбиваются на команды Ореп6С нижнего уровня, которые проще сохранить в списке отображений.
Использованне списков отображения совместно с 6Ш особенно важно для оптимизации пронзводнтельнсктн «мозанчных» команд (семепвсогп) библиотек 6ш (см. главу 11) н НОЯВ5 (глава 12). Философия проектирования списков Отображения и с- м ст т- о- У ду 1С- се- 2.1 Их С целью поднятия производительности команды списков отображения Орели пзирруютс, причем так, что однажды созданный список отображения не может бить модифицирован. В противном случае выигрыш в производительности был бм сведен к минимуму за счет поиска по списку и лишних операций управления пмкятью. Если бы части списка отображения были изменяемыми, распределение н высвобождение памяти привело бы к дефрагментации памяти.
Любые модифиппцин, внесенные реализацией ОрепОЕ в порядок команд списка отображения с цепью повышения эффективности рендеринга, все равно потребовали бы отката. Также вероятны были бы трудности с доступом к списку, кэшированному где-нибудь в сети или на системной шине, Способ, которым достигается оптимизация команд в списке отображения, может аранроваться от реализации к реализации. Например, такая простая команда, ак и\йоса се* (), может выполняться по-разному быстро, если она помещена в сппсок отображения, поскольку вычисления для получения матрицы вращения пзлеко не тривиальны (онн могут включать в себя извлечение квадратного корня п тригонометрические функции).
В списке отображения, однако, требуется сопрпненне только конечной матрицы вращения, так что время выполнения любой команды вращения из состава списка отображения обусловлено тем, насколько быстро обрабатывает аппаратное обеспечение команду П1иц)СНаСгпх'(). Изощренные реалпзнппп Орепб?. могут даже объединять смежные команды преоб(взовання в одном произведении матриц. Хотя не гарантируется, что ваша реализация Орели оптимизирует списки отобрпжения для любых специфических случаев, выполнение списка отображения никогда нс будет медленнее, чем выполнение тех же команд в индивидуальном порядке. Вместе с тем имеются некоторые издержки, обусловленные процессом перехода к списку отображения. Если такой список невелик, зти издержки способны свести на нет все преимушества списочной организации.
Наиболее пред- 244 Глава 7 ° Списки отображения почтительные места для оптимизации перечислены ниже, со ссылками на главы, где эти темы рассматриваются: ° Матричные операции (глава 3). Большинство матричных операций требуют вычисления обратных матриц. В зависимости от реализации Орепб)., обе матрицы — расчетная и обратная — сохраняются или не сохраняются в списке отображения. ° Растровые двоичные карты и изображения (глава 8). Формат, в котором вн определяете растровые данные, скорее всего, не будет идеальным в плане совместимости с аппаратными средствами.
При компиляции списка отображения Орепбй может преобразовать данные в представление, предпочтительное для оборудования. Это оказывает существенный эффект на скорость рисования растровых символов, поскольку символьные строки обычно состоят из совокупности небольших образов (двоичных карт). ° Источники света, свойства материала и модели распространения света (глава 5). Когда вы отрисовываете сцену со сложными условиями освещения, вы можете изменять материалы для каждого элемента сцены.
Задание материалов само по себе медленная операция, поскольку оно предполагает множество вычислений. Если вы поместите описание свойств материалов в список отображения, эти вычисления не будут выполняться всякий раз при переключении между материалами, так как сохранению подлежат лишь результаты вычислений; в итоге рендеринг освещенной сцены может ускориться. (См. раздел «Инкапсуляция изменений режима» для получения более подробной информации об использовании списков отображения для изменения таких характеристик, как условия освещения.) ° Шаблоны штриховки многоугольников (глава 2).
ПРИМЕЧАНИЕ Для оптимизации текстурных изображений вам будет лучше сохранить данные текстур в объектах текстур, а не в списках отображений. Некоторые из перечисленных здесь команд, используемых для указания свойств, являются контекстно-зависимыми, и вы должны принимать это во внимание, если хотите добиться максимальной производительности. Например, если активен режим СЕ СО~Ой МАГЕМ1А1, для отдельных свойств материала будет отслеживаться гпеьз(и(ий цвет (см. главу 5).
Любые вызовы б1Магег(а1*(), устанавливающие свойства материала, будут игнорироваться. Увеличить производительность можно за счет сохранения переменных состояния вместе с параметрами геометрии. Допустим, вы хотите применить преобразования к части геометрических объектов, а затем вывести обгций результат. Тогда ваш код может выглядеть следующим образом: В1ненс1ьт(1, ОЬ СОМР!ЬЕ); Оган ьоие Веометг(с оь)еств(); В1Епб(.(зт(); В1соавнатг(х (М); В)Са11Ь(зт(1): Создание и выполнение списка отображения 245 Но если геометрические объекты должны быть трансформированы таким обраюы несколько раз, лучше сохранять матрицу в списке отображения. Например, если вы напишете следующий код, в отдельных реализациях вы получите дополнительное увеличение производительности за счет трансформации объектов каждый раз при их отрисовке: 1(зен(!в!», 61 60ИР1(Е); Ецоаоиатг)х(М); Оган воще Зеощетг(с оо)еств(); 11(пд(! вт(); 11(ам Е ! в!»): Полее приятная ситуация имеет место при ренлеринге изображений.
Как вы увидите в главе 8, вы можете модифицировать переменные состояния для передачи ликселов (р(хейсгапз(ег), и управлять характером попиксельной развертки изображений и двоичных карт. Если команды, устанавливающие эти переменные сопояния, в списке отображения предшествуют определению изображений или дончных карт, реализация может выполнить эти операции упредительно н поиестнть результаты в кэш. Помните, что списки отображений не являются панацеей. Очень маленькие списки не всегда имеют смысл в связи с издержками на выполнение самого списка.
Другой недостаток заключается в неизменности содержимого списка отображения. Чтобы производительность была максимальной, списки изображений Орели Лелаются постоянными и недоступными для чтения содержимого. Если приложение нуждается в поддержании используемых в списке данных вне этого списка (например, для последующей их обработки), это увеличивает требования к объеиу необходимой памяти. Создание и выполнение списка отображения Как вы уже видели, команды я1Мен1! 51 () и к1 Е по 1 ! 51 () используются для укамвяя места начала и окончания определения списка отображения, а сам список вызывается на выполнение с помощью идентифицирующего его индекса, генерируемого к1Са111 ! 51().