М. Ву, Т. Девис, Дж. Нейдер, Д. Шрайнер - OpenGL. Руководство по программированию (Библиотека программиста) (2006) (1124363), страница 18
Текст из файла (страница 18)
листинг 2.10. использование функции О1Аггауе(егпепс() для задания цвета н вершин 51ЕпаыеС1)епС5Саге(6С СО(Оп АаРАЧ); 61Епав)еС11епС5Саге(6С ЧЕЙТЕХ АааАЧ); 51Со1огРо)п(ег(3, 6( РСОАТ, О, со1огл); а1чегСехРа1п(ег(2, 6( 1МТ, О, чег(1СЕ5); а\Веа1п(6( ТК!АМ6СЕ5), 51АггауЕ1еаепС(2); х1АггауЕ)еаепС(3); 51АггауЕ1епепС(5); 51ЕПЕ(); При выполнении последние пять строк равносильны следующему коду: 61аез1п(6( Та!АМ6(Е5); 51Со1огЗТЧ(со!огл л (2 ' 3)); агуегтех21ч(чегСТсел л (2 * 2)); В)сосогз Тч(сосогл + (3 ' 3)); 61чег(ех21ч(чег(1сел л (3 * 2)); 516010ГЗ Тч(со10Г5 л (5 * 3)); атчегтех2!ч(чегС)сел л (5 ' 2)); 51Епс(); Так как функция а1Аг г а уЕ1евеп С () вызывается только для одной вершины, она может увеличить число вызовов функций и снизить производительность.
Нелишне предупредить, что если содержимое массивов изменяется между а1Веа1 и () и а1Епс) (), то нет гарантий, что вы получаете оригинальные данные или изменяете данные интересуюшего элемента. Для большей уверенности не изменяйте содержимое любых элементов массива, которые могут быть доступны до завершения формировании примитива. Разыменование элементов массива по списку Функция я1Аг г а уе1еа ел с () удобна для неупорядоченного доступа к данным массивов.
Сходные функции В10ганЕ1евептз (), В1ИЧ1СТ ОганЕ1евепС5 () И а10ганКапаеЕ1евептз() Хороши дпя доступа К даннЫм В МассивЕ, когда нужЕн более упорядоченный образ действий. чоЫ я10ганЕ(еаепс5(С(епшп тоЫе, С?з(хе( соипд О)епшп Гуре, чоЫ "(пйсез); Определяет последовательность графических примитивов.
Значение соил(— зто число элементов, индексы которых хранятся в массиве спс(ссею Параметр гвре должен быть равен бс Ом516ме0 Вчте, 6с Ом516ме0 5нОРт или 6с ОМ516МЕО 1МТ, это тип данных массива тг(саек Аргумент тог)е указывает тип рисуемых примитивов и принимает одно из значений, передаваемых в функцию я1Веа(пО; например,6С РОСУ60М,6С 11МЕ СООР,6С С1МЕ5,6С РО1МТ5 н г.л. 80 Глава 2 ° Управление состоянием н рисование геометрических объектов Задняя часть 4 (Теряя Рнс. 2.15.
Куб с пронумерованными вершинами Листинг 2.ХЕ. Использование функции д[Е)гашЕ[егпеп[я() для разыменовання нескольких элементов массива 5сас!с 6(иьусе ггопс1пб[сез[! = (4, 5, 6, 7): 5(аС!с 6(иЬуте г!ВЬС!пб!се![] = (1, 2, 6, 5); 5сас!с 6(иьусе ьассоа!пб!се![] = (О, 1. 5, 4); 5СаС!с 6СЬЬу(е Ьасх1пб!сез(] = (О, 3. 2, 1): згаС!с 6СиЬУСе се(С1пб!се![] = (В, 4, ?, 3); згаС!с 6(иЬу(е Сор1лсм сез[] = (2, 3, 7, 6); ггопг1пбссе!); г!ВЬС1пб!сез); ЬЬССов1пб!се!),' Ьасх1пбссез); 1еГС1пб[сез); Сор1пб!сез): 610гаие1евепсз(61 00405, 610гаиЕ]еаеп(4<6( 00405, 610ганесевепсз(6( ОЬА05, 6\огаиЕ1еаептз(6С (]0405, 610ган61евеп(5(6( 00А05, 610гаиЕ[евеп(з(6( 00А05, 4, 6( ЬН516МЕЬ ВУТЕ, 4.
61 ЬН516ЙЕ0 ВУТЕ, 4, 6( ин516йео Вуте, 4, 6( ЬЙ516МЕЬ ВУТЕ, 4, 6( ВМ516МЕ0 ВУТЕ, 4, 61 ЬН516НЕ0 ВУТЕ. ПРИМЕЧАНИЕ Ннкагкуляцня д[пгаиб[егпеп[зЦ мекду операторными скобками 0[бед[0()/0[баб() является ошибкой. С несколькими типами примитивов (такими как 6Е (]ОА05, 61 ТР1АН6ЕЕ5 и 6с е1не5) возможна упаковка нескольких списков индексов в один массив. Так как Эффект от функции 610гаиЕ1евептз() схож с результатом применения следующей последовательностью команд; 61Вед!л(аобе); гог (! = 0; ! < саипс; 1+ч) 61АггауЕ1евепС(!пб!се![!]): 61Епб(); Кроме того, функция 610ганЕ1евеп15() проверяет корректность значений тоНе, соил( и (уре. Также, в отличие от предыдущей последовательности, функция 610гаиЕ1евептз() оставляет некоторые состояния неопределенными.
После ее выполнения текущий ВСВ-цвет, вторичный цвет, цветовой индекс и флаг краев не определены, если соответствующие массивы активированы. С помощью функции 610гаиЕ1евепсз() вершины на каждой грани куба могут быть помещены в массив индексов. Листинг 2.11 представляет два способа использования функции 610гаиб]евепС5() для построения куба. Рисунок 2.15 показывает номера вершин, используемых в листинге 2.11. Массивы вершин 81 примитив 6Е 00А05 представляет каждую группу из четырех вершин в ниде многоугольника, можно упаковать эти индексы, используемые в листинге 2.11, в одиночный массив, как показано в листинге 2.12.
Листинг 2.12. Объединение нескольких вызовов функций д]0гаиЕ!егпепй() в один зтат]с бьоЬу(е а11[па(се>[! = (4, 5, б, 7, 1, 2, б, 5, О, 1, 5, 4, О, 3, 2, 1, О, 4, 7, 3, 2, 3, 7, б): 810ганЕ1евеп(5(6( ООАО5, 24, 6Е ОК5[6ИЕО 8УТЕ, а11[па!сез); Для других типов примитивов упаковка индексов из различных массивов в одиночный массив даст различные результаты. В листинге 2.13 использу3отся два вызова функции е10ганЕ(е!пептэ() с примитиВОМ 6Е Е]МЕ 5ТР[Р для рисования двух прерывистых линий. Вы не можете просто объединить эти два массива и ограничить вызовы функции одним без связывания линий в одну, соединенную в вершинах б и 7. (Заметьте, что вершина 1 используется в обеих линиях только для того, чтобы показать, что это допустимо.) Листинг 2.13.
Два вызова функции д]ОгачгЕ[ешепш(), рисующие две прерывистые линии 5!а!!с бсиьуте апе]па!сез[] = (О, 1, 2, 3, 4, 5, б); 5!а!!с 6(опусе !но[па(сез[] = (7, 1, 8, 9, 1О, 11]; 810ганб[евептз(бь ШКЕ бта[Р, 7, бг Онб[бкба Вутб, опе[па]соз); 810гане(евепгз(бе [[ке 57Р[Р, б, 6[ Онб[бнео ауте, !но[по!сеа); В ОрепС(.
версии 1.4 была введена функция к1М011!Огане1еиепгб() с целью объединения нескольких вызовов функций к10ганЕ1еиептз() в один. чоЫ к1М011! ОганЕ1евепгэ(С].еппп! тоо[е, С(.яге[ "соипд С[.епшп гуре, чоЫ ""шй(сез, С].яхе] рптсопп(); Вызывает последовательность выполнения из рптсоипг (количество) функций к10ганЕ1еаептэ(). Параметр гпйсез — это массив указателей на списки элементов массива. Параметр соил( — массив количеств вершин, найденных в каждом соответствующем элементе списка.
Параметры тог(е (тип примитива) и гуре (тип данных) такие же, как в функции а10гане1еиептз () . Вызов функции к1М011!ОганЕ1еиептз() равНОСИлЕн ЦИКЛУ !ог (! = О; ! < Рг!всаопт; 3++) ( (! (сооп![(] > 0) 810гаиЕ1епептз(аоае, сапа![!], (уре, (па(сез[(]); Вызовы функции а10ганЕ1евептз() в листинге 2.13 могут быть объединены в одиночный вызов функции а1М011! ОганЕ1еаепгз (), как показано в листинге 2.14. как и функции к10гане1епепгб () и к1ми11! Огане1евептб(), функция к10гаиРапееЕ1евепгз () ПрЕднаЗНачЕна дпя доступа к данным и рисования их СОдержимого.
Функция к\ОганРапаеЕ1епептб() также вносит дополнительные ограничения на значения индексов в расчете на рост производительности программ. 82 Глава 2 ° Управление состоянием и рисование геометрических объектов Ради оптимальной производителысости некоторые реализации ОрепС]. могут осуществлять упреждающую выборку ограниченного объема данных о вершинах. Функция я10 г анйапяе Е1евепС з О позволяет задавать диапазон вершин для упреждающей выборки.
Листинг 2.14. Использование функции д1Мц11!ОгаучЕ]евер(): шчаггаую згаС!с 61ооуте оое!пе]се!(] = (В, 1, 2, 3, 4, 5, 6); згзС!с вьоьуСе Сно]огн се! Н = (2, 1, В, З, се, 11]; зСаСзс 6Сз(се! соопС(1 = (7, 6); зСаС!с 6Счо!О ' (пе!сез(2] = (опе1ое!сез, Сно1ое!сез); 61Мо1С]вгаиЕ1еяео(з (6С ЩМЕ 5ТР1Р. соооС, 6С ВМ516МЕР ВУТЕ, (ое]сев, 2); чоЫ я10ганйапяеЕ1еяепсз(СЕепцш топе, СЕшпс зсагс, СЕц]пс епс(, СЕВ(ге] соипй С!.епшп Гуре, чоЫ "тс]есез)1 Создает последовательность графических примитивов, аналогичных, но более ограниченных, чем определяемые с помощью функции я10ганЕ!евепсзО. Аргументы функции к10ганйапяеЕ1евеп(з() подобны соответствующим аргументам функции а10гане1ео!ел сз (), включая то!(е (вид примитива), свинг (число элементов), (уре (тнп данных) и (пг((сез (данные о вершинах).
Дополнительныс аргументы зсагс и епс! определяют диапазон значений спс(ссез включительно. Ссылка вне диапазона (зсагс, епг!']Для вершин в массиве спс((сех является ошибкой. Однако реализация ОрепСЕ не ищет эту ошибку и не сообшает о ней. Таким образом, некорректное значение индекса может вызвать, а может и не вызвать, ошибку ОрепС]., и результат полностью зависит от версии. Чтобы определить рекомендуемый максимум числа вершин для предварительной обработки и максимального числа индексов (показывает число рисуемых вершин),используйтефункцию я16еС]пгеяегчО срежимами6с МАХ ЕСЕМЕМТ5 ЧЕРТ]СЕ5 и 6С МАХ ЕСЕМЕМТ5 ?М0]СЕ5.
Если значение епс( — зсаг(+! больше рекомендованного максимума предобрабатываемых индексов, функция а10ганРапяее1еяепсз () нарисует корректное изображение, но производительность может снизиться. Не каждый индекс в диапазоне [згагг, епс!'] обязан задействоваться. Однако в некоторых реализациях, если вы определяете редко используемый диапазон, это влечет лишнюю обработку множества неиспользуемых вершин. Возможно, что ваша реализация ОрепС]., обращаясь к я1АггауЕ1еяепсз(), я10ганЕ1ееепСВ О, я1Мо1С(0ганЕ1еяепСВ О н я10ганйапяеЕ1е!оепСВО, кэширует недавно востребованные (то есть измененные) вершины, позволяя приложению оперировать теми же данными без повторных преобразований. Возьмем, например, вышеупомянутый куб, у которого шесть граней (многоугольников) и только восемь вершин. Без я1*е1еяепсз() рисование всех шести граней требует обработки 24 вершин, из них !б операций являются избыточными.
При кэшировании ОрепС]. минимизирует избыточность и фактически обработает всего восемь вершин. (Повторное использование может быть ограничено внутри одиночного вызова я10гане1еяепсз () или я10ганйапяее]ееепсз О, одного индекс- Массивы вершин 83 ного массива для функций В1Ии1110гаиЕ(евепгзО нли для В1АггауЕ1евепгз() внутри пары В1Век!п()ГВ1Епо().) Разыменование последовательности элементов массива В то время как В1АггауЕ1евептз(), В10гаиЕ1евепсз О и В10гаидапВеЕ1евептэ О «прыгают» по вашим массивам данных, функггия В10гаиАг гауз() «перепахивает» их.
чоЫ В10гаиАггауз(С[.епнш тос[е, С]!ггт ггтхГ, С1.яхе[ свинг); Строит последовательность графических примитивов, обращаясь к элементам кахсдого активированного массива начиная сггтхг и заканчивая /ггзг + соипг — 1. Аргумент тос[е определяет тип примитивов и получает такие же значения, как в В1ВеВ!и(), например; ьс РОсЧВОМ, И (1МЕ сООР, 6( (1МЕ5, ВЕ РО]МТ5 и т, д. Результат выполнения В10гаияггауз () аналогичен следующей последовательности команд: агвеагп (вове); гог (! = 0; ! < соопг; г+») В]АггауЕ1евепс(!!ге! + !); а1Епд(); так же, как и функция В10гаие1евепсзО, функция В10гаидггауэ() выполняет контроль значений своих аргументов и оставляет текущие значения КСВ-цвета, вторичного цвета, индексного цвета, координат нормалей, координат тумана, координат текстуры и флага краев неопределенными, если соответствующий массив активирован.