М. Ву, Т. Девис, Дж. Нейдер, Д. Шрайнер - OpenGL. Руководство по программированию (Библиотека программиста) (2006) (1124363), страница 53
Текст из файла (страница 53)
В листинге 7 2 список отображения создается в подпрограмме ! и! с (). Этот список отображения содержит команды ОрепОЕ для рисования красного треугольника. В процедуре 0(зр1ауО список отображения выполняется 10 раз. Дополнительно в непосредственном режиме рисуется лилия. Заметьте, что список отображения выделяет память для размещения команд и значений необходимых переменных. Листинг 7.2.
Использование списка отображения: !(5(.с Е(а!пт 11втяаще; иас(с хо!О )и!1(хо)О) ( ывтиаще = В16епе!в!в»): 11ИенЕ(вт(1(вткаще, 61 ЕОИР1ЕЕ); З1со1огз!».О, 0.0, 0.0); /' текущий цвет — красный */ З1вез!п(6$. ТИ1АИ6(Е5); Птодолженне Ф 246 Глава / ° Списки отображения Листинг 2.2 (продолжение) 61ЧегСех21(9.0, 0.6); 61Чегтех21(1.0, 8.0); 61Чеггех21(0.0.
1.6); 61Епб(); 61Тгвпз1зте1(1.5, 8.0, 6.0); /' перемещение позиции '/ 61Епб!.тзс(); 615лзбЕМОбв1(6С ЕСАТ); зсаС!с чотб бган(!пе(чотб) ( 616ей!п(61 С1НЕ5); 61Чегтех21(9.0, 0.5): 61Чегтех21(15.0, 0.5); В)впб(); чотб б!зр1зу(чо!б) ( 6ьи!пС т; 6161евг(61 СО(06 ВВЕГЕН В)Т); 616а1ог31(0.9, 1.8, 0.0); /* текущий цвет - зеленый '/ 1ог (! = 9; ! < 18; т++) /* рисуются 19 треугольников '/ 616в11(тзС(1!зтыаюе); бган(!пе О; /* зта линия зеленая? нет! '/ /' Где нарисована линия? */ 611105П() ! Команда я1Тгэп51ате1() перемещает позицию рисования в соответствии с положением следующего объекта. Без этого треугольник рисовался бы поверх себя самого. Эти десять вызовов 81Тгап51ате1() также воздействуют на выполнение процедуры бган( ! пе (), вызываемой в непосредственном режиме.
Поэтому, если вы обращаетесь к командам преобразования изнутри списка отображения, не забывайте о вносимом ими на всю программу эффекте. Одновременно может выполняться только один список отображения. Други. ми словами, вы должны, когда придет время, следом за 61меыс! 51() вызвать 81епбс! 5с(), чтобы указать конец одного списка перед началом выполнения другого. Конечно, команда к1ЕобЕ ! 5 С () без сопутствующей ей открывающей команды влечет ошибку 61 1НЧЛС10 ОРЕНАТ10)). (См.
раздел «Обработка ошибок! главы 14 для получения более подробной информации об обработке ошибок.) Присвоение имени списку отображения и создание списка Каждый список отображения идентифицируется целочисленным индексом. При создании списка отображения вы должны быть внимательны, чтобы ненароком не указать уже используемый номер и, таким образом, не перезаписать существующий список отображения новым. Соответственно, во избежание путаницы Создание и выполнение списка отображения 247 используйте команду к\6епь1эгэ() дяя ГЕнЕРиРования одного или более ранее ве использованных индексов. Ял(пг 616епС(эгэ(б(.э(хе( галде); Выделяет диапазон прелварительно высвобожденных смежных индексов (галде).
Возвращаемое целое число — это индекс, соответствующий началу блока смежных индексов. Все индексы в блоке при этом помечаются как используемые, и последующие вызовы 616епгчэгв() не вернут эти значения, пока вы не удалите их собственноручно. Нуль возврашается, если требуемое количество индексов не может быть выделено или если аргумент канде сам равен нулю. В сведующем примере запрашивается один новый индекс, проверяется результат мяроса и, если все в порядке, создается список отображения: 1Иг!ппех = Х16епг! вгв(1); И И(вг(ппех (= Э> ( хгяенг(вг(11вг(поех,ог сонР(ге1; К1Еппг(эг(]; ) ПРИМЕЧАНИЕ Ноль не является корректным индексом.
тоЫ К1йенг1эг(01ц1пг Ы, С1.еппгп тес(е); Указывает начало списка отображения. Команды Орепб(., вызываемые в дальнейшем (пока не встретится 8 1 Е и о С( э г () ), помещаются в список, за исключением тех команд, которые по определению не могут быть в нем сохранены. (Эти команды обрабатываются немедленно, во время создания списка.) Аргумент йтг — это ненулевое положительное целое число, уникальным образом идентифицирующее список.
Возможные значения для аргумента тес(е: 6С СОИР1СЕ и 6С СОМРТСЕ АЙО ЕХЕСОТЕ. Используйте 61 СОМР11Е, если хотите, чтобы команды ОрепС(. обрабатывались во время их размешения в списке; чтобы команды до помещения их в список выполнялись в непосредственном режиме, укажите 61 СОИРТСЕ АИО ЕХЕСОТЕ. тоЫ а1 Ело С ( э г(чоЫ); Помечает конец списка отображения. При создании списка отображения запоминается текущий контекст Орепб) . Такям образом, когда контекст разрушается, список отображения также уничтожаекя. Некоторые оконные системы поддерживают множество контекстов, разде- жмых между собой различными списками отображения.
В этом случае список отображения разрушается, когда уничтожается последний контекст в общей группе. Что сохраняется в списке отображения? Когда вы формируете список отображения, в нем сохраняются только значения вырзжений. Если значения в массиве впоследствии изменяются, значения в спи- 248 Глава 7 ° Списки отображения оке изменяются также. В следующем фрагменте кода список отображения содер- жит команду, устанавливающую в качестве текущего цвета РСВА черный — (0.0, 0.0, 0.0).
Последующее изменение значения массива со[от ресгог на красный цвет (1.0, 0.0, 0.0) не оказывает эффекта на список отображений, поскольку последний содержит значения, которые были актуальны на момент его создания: 6[11оат со1ог чесгаг[3) = [б.о, 6.0, В,О); д[ненс$кг[1. ВС СОНР[СЕ>; 91Со1огзтч[со[ог чесгог); 91ЕпОС$ат(); со1ог чесгог[81 = 1.6; Не все комшцгьг ОрепСЕ могут быть помещены в список отображения и выполнены таким образом.
Например, ими не могут быть команды, которые устанавливают состояние клиента, и команды, возвращающие значения параметров состояния. (Их в основном легко опознать — так как они возвращают значения параметров, передаваемых по ссылке, или возвращают значения напрямую.) Такие команды при включении их в список отображения выполняются немедленно. В табл.
7.1 перечислены команды ОрепС[., которые можно включить в список отображения. (Заметьте, что 91кеиС $ зт() генерирует ошибку, если она вызывается изнутри еше не завершенного списка.) Некоторые из этих команд нами еше не рассматривались, но вы можете найти их описание в тексте книги с помощью предметного указателя. Таблица 7.1.
Функции Орепбс, допустимые к помещению в списке отображения Для четкого понимания причины этих ограничений вспомните, что в сетевом окружении клиент ОрепСЕ может находиться на одном компьютере, а сервер — на другом. Созданный список отображения постоянно хранится на сервере, таким образом, сервер не может рассчитывать на клиента в плане получения информации, связанной со списком отображения.
Если запрашивающие команды, такие как 916ет' () или 911з ' О, разрешить к использованию в списках отображения, вызывающая программа будет зависеть от непредсказуемости времени возврата данных через сеть. Пока у нее не будет списка отображения в оригинальном виде, 9[АгеТехтцгекдек(сепг() 9[С[$епгдс1$чеТех1цгеВ 91Со[огРЫпгег() 9[Ое[егеС[вта() д !Ое[егеТехтцгек() 901$ааЫеСбеп!51аге() д[Ег)деЕ[адро[п[ег() д[ЕпаЫеСбеп151аге() д!Реег[Ьаскдц([егВ 9[Е[п[5Ь() 9[Р[ц5Ь() 9[ЕодСоогг)ро[п!ег() д[депВвм() 9[дептехгцгевВ 9!Вес*!) 9[[пг[ехРо[птег() 9$[псег[еачег[АггаукВ 9[[кЕпаЫег[() д[Ы.)кг() дНктехгцгеВ 9$$[оппа[Ро(псег() д[Р[хе[51оге() д!РорСбепгАПпЬ() 9[РцкЬС[[ептА11пЬ() 9[Реаг[Р)хе[к() 9[Репг[егмог[еВ 9$5есопбагуСо[огРо(пгег() 9$5е[естВо((ег() 9[техСоогг[Ро[пгег() д!ЧекехРо[птег() Создание и выполнение списка отображения 249 з каком он послан, вызывающая программа не будет знать, где ей разместить дандме.
Таким образом, любые команды, возвращающие значения, не могут быть помещены в список отображения. Команды, изменяющие состояние клиента, такие к>к д1Р! хе15(о ге (), к15е1есгвит(ег (), и команды, описывающие массивы вершнн, также не могут быть сохранены в списке. Например, подпрограммы спецификации вершин массива (такие как к1че ггехРд1пгег О, д1Со1огРо! пге г О и д11пге г1еачеПАг гауз О ), устанавливают укамтелн состояния клиента и тоже не могут быть сохранены в списке отображения.
Команды д1АггауЕ1евеп(О, д10гаиАггауз() н д10гаиЕ1емептэо посылают данные для построения примитивов из элементов, принадлежащих доступным массивам, соответственно, эти операции могут быть сохранены в списке отобракения. (См. Раздел «Массивы вершин» главы 2.) Данные массива вершин, сохраювные в списке отображения, извлекаются через разыменование указателей, но де непосредственно. Таким образом, дальнейшие изменения значений в вершидкт не будут влиять на определение примитивов в списке отображения. К влияющим командам относятся и любые команды, использующие режимы юхранения пикселов (р!херзсогайе шог(ез). (См.
раздел «Режимы хранения пик(гдов» главы 8.) Другие подпрограммы, полагающиеся на состояние клиента, там>е как д1Е1оэп О и д1Г! и! зв О, не могут быть сохранены в списке отображеви, поскольку они зависят от состояния клиента в момент обработки списка. Зыполнение списка отображения Весле того как вы создали список отображения, вы можете запустить его на выпслнение вызовом д1С а111 ! это. Разумеется, один и тот же список отображения южно выполнять многократно, а также можно смешивать его обработку с командщв непосредственного режима, как мы это уже видели.
чо(П Е1Са11С!э1(ОЕп!пс)мГ); Выполняет список отображения, указанный аргументом 1(зг. Команды списка отображения выполняя>тся в порядке своего сохранения, как если бы списка отбражения и не было. Если аргумент Ы не определен, ничего не происходит. Вмможете вызывать д1Са111! зт() из любой точки программы, пока активен сомветствующий ему контекст Ореном (тот же, что был активен на момент создажи списка, или контекст из общей группы). Список отображения может быть авдан в одной подпрограмме, а выполнен — в другой, благодаря его уникальной здеятнфикации по индексу. Л вот для сохранения списка отображения в файле ыв, наоборот, для загрузки его из файла средств не имеется. Это лишнее подперждение временного характера списков отображения.
иерархические списки отбражения Зм можете создать иерархический список отображения, в котором изнутри однощспнска отображения — между д1меиЕ ! эт() и д1ЕпбЕ! э1() — выполняется выдв других списков той же командой д1Сз11С ! зт () . Иерархически упорядочен- 250 Глава 7 ° Списки отображения ные списки полезны для объектов, составленных из готовых компонентов, особенно если последние используются больше одного раза.