OpenGL. Руководство по программированию (Библиотека программиста) (2006). Ву М., Девис Т., Нейдер Дж., Шрайнер Д (1124475), страница 54
Текст из файла (страница 54)
252 Глава? ° Списки отображения Соответственно, понимается, что с аргументом 1м/з нужно обращаться как с массивом байтов, беззнаковых байтов, коротких целых чисел, коротких целых без знака, целых чисел, беззнаковых целых чисел или чисел с плавающей запятой. Аргумент гуре может также принимать значение 6Е 2 ВУТЕ5, 6С 3 ВТТЕ5 или 6С 4 ВУТЕ5.
В этом случае цепочки длиной в 2, 3 или 4 байта читаются из массива 1ст(з, а результирующее смещение вычисляется по следующему алгоритму (здесь Оу/е[01 — стартовый байт последовательности): /* Ь = 2, Э ипи 4; байты массива нумеруются в поспедоватепьностн О, 1, 2, 3 "/ от(вес = 0; тот (! = 8; ! < Ь; (++) ( от!вес = от!вес « 8; о!тает += ЬуСе(!): ) !пбех = оттает + 1!яСЬаве; Для многобайтовых полей первыми обрабатываются старшие разряды, а в остальном порядок идентичен обработке массива. Листинг 7А приведен нами в качестве примера использования комбинированных списков отображения, это фрагмент программы, полностью представленной в листинге 7.5.
Эта программа рисует символы векторного шрифта (набора символов, образованных отрезками линий). Процедура ! и! 15сгохебропС() устанавливает индексы списка отображения для каждого символа так, чтобы они соответствовали своим А8СП-кодам. Листинг 7.4. Определение составных списков отображений чо!б !п(С5СгонебропС(чо!б) 6(м(пС паве; Ьаве = 816епС!втв( 128): 81С!втваве(Ьаве); 81яеиС!вС(Ьаве+'А', 6С СОМР1СЕ); бгаигеттег(Абата); 81ЕпбС(вС(); 81яеиС!вС(Ьаве+'Е', 6С СОМР1СЕ); бгаигеССег(Ебата); 81ЕпбС(ят(); 81яеиС!вС(ьаве+'Р', 6С СОМР1СЕ); бгаисеССег(Рбата); 81Епб(!вС(); 81кеиС!вС(Ьаве+'а', 61 СОМРХСЕ); бгаиьеССег(хвата); 81ЕпбС(вт(); 8(кеиС!вС(Ьаве+'5', 61 СОМР1СЕ); бган(.еССег(5бата); 81Епбь!вС(); 81яеиС!ят(Ьаве+' ', 6С СОМР1СЕ); /' пробел */ 8\Тгапв1атег(8.9, 8.0, 0.0); 81ЕпбС(вт(): Команда 816епс! 818 () заказывает 128 последовательных индексов.
Первый из них становится базовым значением. В списке отображения каждый символ представляется суммой базового значения и АВСП-кода символа. В этом примере мы описываем только пять букв и пробел. Выполнение составных списков отображения 253 после создания списков отображения можно вызвать команду к1са111! 515[) ЗЛЯ ИХ Обработки.
Так, можно передать процедуре рг( п151гохе051г ( па [) строку символов: мш рг)п151гонеи51г(пх(6( Ьусе *з) ( 61)пс 1ел = ксг1ел(З); 5]саПС)зсз(]ел, ОС Вуте, з); ) Здесь значение АЯСП-кода служит как смешение в наборе индексов, а целевой индекс образуется его сложением с текущим базовым смещением. Результат ра[юты программы, представленной в листинге 7.5, показан на рис. 7.]. Рис. 7.1. Фраза, составленная нз символов векторного шрифта: А, Е, Р, Р„5 йнстинг 7.5.
Составные списки отображения, определяющие векторный шрифт: Вохе.с Рисгле Рт 1 Мс)спе 5ТМОКЕ 2 Усе()пе ЕМО 3 1уреиег зсгисс слагро)л1 ( ЕСУ]оас к, !Ь1 1уре; . ] СР; СР Аиаса(] = ( ( О, О, РТ), [О, 9, РТ], (1, 10. РТ), (4, 10, РТ), (5 9 РТ] (5 0 5ТВОКЕ) (О 5 РТ) [5 5 ЕМО) СР Ееаса(] = ( (5, е, Рт>, (о. о, Рт>, [в, 1о, рт>, (5, 1в, 5ткоке], (О, 5, РТ], (4, 5, ЕМО] Н Риаса[] = ( О Р (Е 10 РТ) (4, 10, РТ), (5, 9 РТ] (5 (4 5 РТ) (О 5 ЕМО) ]: СР Виа1а(] = ( (В, 6, РТ], (О, 10, РТ), (4.
10, РТ], (5, 9, РТ), (5, 6, РТ], (4, 5, РТ], (О, 5, 5ТМОКЕ), (3, 5. РТ), (5, О, ЕМО) ): СР 54а1а [] = [ (З, 1, рт>, [1, В, Рт), (4, Е, рт], [5, 1, РТ>, (5, 4, Рт], лроаиллгение *Р 254 Глава 7 ° Списки отображения Листииг 7.5 (орос/олжение) (4, 5, РТ), (1, 5, РТ». (8, 6, РТ), (8, 9, РТ), (1, 18, РТ), (4, !8, РТ), (5, 9, ЕМО) /' бганСеСсег() интерпретирует команды из массива ' для символа и воспроизводит символ отрезками прямых >/ ьтаС1с чо1б бганСеССег(СР *1) ( 61Веа!п(6с с1МЕ 5ТМ1Р); нл(!е (1) ( ьи(сел (1->суре) ( саье РТ; 61Чегтех2(ч(81->х); Ьгеа)с; саье 5ТРОКЕ: 81Чегтех2тч(й1->х); 61Епб(); 61ВеВ(п(6с (1МЕ 5ТМ1Р); Ьгеас; саье ЕМО: В!Чегтех2(ч(81->х); В)Епб(); В!!галь!атет(В.В, О.О, 8.8>; гесигп; 1++; /' Создание списка отображения для каждого из 6 символов "/ ьтаС>с чо1б (п!С(чо(б) Осм!пс Ьаье; 615лабеМабе1(6( РСАТ); ьаье = 616епс!ьсь(128); 61с!ьсваье(ьаье); В!ЙенС(ьт(Ьаье+'А', 6С СОМР1СЕ>; бгаиСеССег(Абата); 81ЕпбС(ьС(); В!ИенС(ьС(Ьаье+'Е', 6С СОМР(СЕ>; бганСеССег(Ебата>; 81ЕпбС>ьС(); 81йенС(ьС(Ьаье+'Р', 6С СОМРХСЕ); бганСеттег(Рбата); 61Епб(.(ьС(): 6!иенс»ьс(ьаье+'й', 6с сомР1се); бгаисессег(оба!а); В(Епс(С(ьС(); 61меис(ьс(ьаье+'5', 6с сОмР1(е); бгаисессег(5баса); 61ЕпбС>ьС(); 61иенС1ьС(Ьаье+' ', 6С СОМР1СЕ); 61тгапь1асет(В.О, 0.8, 8.8); 61ЕпбСзьС(); спаг *Сеьт! = "А 5РАЙЕ 5ЕМАРЕ АРРЕАЙ5 А5"; слаг *СеьС2 = "АРЕ5 РМЕРАМЕ КАМЕ РЕРРЕМ5"; 256 Глава 7 ° Списки отображения Листинг 7.5 (продолжение) 81итиа1п(оор(); гегигп 9; Управление параметрами состояния с помощью списков отображения Список отображения может содержать вызовы команд, которые изменяют переменные состояния ОрепО)..
Эти изменения производятся во время выполнения списка отображения, как если бы команды выполнялись в непосредственном режиме, и их результаты остаются зафиксированными по окончании выполнения списка отображения. Вы уже видели зто в листинге 7. 2, и мы снова демонстрируем в листинге 7.6, что изменения текущих цвета и матрицы остаются в силе и после выполнения списка отображения. Листинг 7.6. Сохранение состояния после выполнения списка отображения 91кеи()а(О)ат)пеех,01 СОНР11»; 91Со1огЗГ(1.8.
9,0, 8.0); 818еа(п(01 РОЕЧВОИ); 81Негтех2Г(9.8, 9.9); 91Нег(ех2(( 1.9, 9.9]; 91Че ггех2 Г (8. 8, 1. О); 91Епп»: 91тгапа(ага((1.3, 9.8, 8.0); 91Епв» а((); Если теперь вы вызовете следующую последовательность команд, линия будет нарисована красным (текущим) цветом и дополнительно сместится на значение (1.5, 0.0, 0.0): 81Са11(аз((1га(1ппех); 919е91п(0( Е)МЕ5); 81Нагтех2((2.9,- 1.9); 91Чегтех2(( 1.8, 8.9); 81Епп(); С переменными состояния обращаются по-разному. Можно либо оставить изменения в силе, либо, наоборот, предварительно перед обработкой списка зафиксировать состояние и восстановить его по окончании выполнения списка. Это ваше право, но помните, что команда я16ег" () в списке отображения недоступна и, таким образом внутри него нет возможности запросить текущие переменные состояния.
В то же время в вашем распоряжении имеется команда а1РозЛА11г(ЬО, позво. ляющая сохранить разом несколько переменных состояния, и команда я1Рордттг1Ь() — для восстановления значений. Чтобы сохранить и восстановить текущую матРицу, используйте команды 81Розйнатг(х() и 81Рорнатг(х() согласно рекомендациям раздела «Операции со стеком матрнг(ы» главы 3. Эти Управление параметрами состояния с помощью списков отображения 257 команды могут легально кэпшроваться в списке отображения. Чтобы восстаиовить значения переменных состояния из листинга 7.6, мы могли бы воспользоваться кодом из листинга 7.7. Листинг 7.7.
Восстановление значений переменных состояния изнутри списка отображения 'Е)йеи(т «1(1! «1! по ах,о! СОИР! ! Е); 91Рц«лиатг!х(); 91Рц«ПА11гть(0! СОяаЕИТ В1Т); 91СЬ1огзт(1.9, 9.0. 0.0); 91Веа(п(ОЕ РОСЧООя), 91Чегтех?т(9.9. О.О); В!Чвгтвхгт(!.9. О.О); В!Честен?т(9.9, 91Епб (); В(тгап«1а!ет(1.9. О.О. О.О); 91РорА1(г! Ь(); В!Рорла 1 г ! х (); 11 ! об С ! «1(): Если вы прибегнете к варианту листинга 7.7, с помощью кода листинга 7.8 вы сможете нарисовать линию зеленого цвета, в прежней позиции.
Если вы воспользуетесь списком отображения из листинга 7.6, то есть ие сохрапите (и ие восстановите) состояние, линия будет красной, а ее позиция каждый из десяти раз бужт смешаться иа значение (1.5, 0.0, 0.0). Листинг 7.8. Пример того, как список отображения может или не может кваействовать на с)гач/Е)пе() чо!б б(«р1ау(хотб) ( 0(!пт (; 91С1еаг(СС СО!Ой ВОЕРЕЯ В1Т); 9!Со(агэт(9.9, 1.0, 0.0), /' установить текущим цветом зеленый */ тот (! = 9; т < 10; 1<+) 91Са11(т«1(11«1!пбех); /* список отображения выполняется 19 раз '/ бган!(пе(); /* гле появляется пиния и каким цветом она окрашена? */ Е1Р(ц«Ь(); ) Инкапсуляция изменений режима Вы можетс использовать списки отобралсеиия для организации и сохрапения групп команд, измсияк)щих атрибуты режимов, или для варьирования паракетров.
При переклк)чепии с одной группы настроек ца другую использование списков отображения бывает более эффективно, чем непосредственные вызовы, благодаря кэшированию настроек в формате, наиболее подходящем вашей графической систелте. Это случаи варьировашгя освещения, модели распространения света и свойств иатериала. Вы можете также использовать списки отображения в качестве шабзовов штриховки, параметров тумана и для обсчета секущих плоскостей. В этих 288 Глава 7 ° Списки отображения случаях вы увидите, что списки отображения близки по скорости выполнения к эквивалентным непосредственным вызовам, но помните, что спискам отображений присусци дополнительные издержки на само их поддержание при выполнении.
Листинг 7.9 показывает, как использовать списки отбражения для переключения лсежду тремя различными шаблонами штриховки. Сначала вызывается 616елС! 515() для выделения индексов для каждого образца, и затем для всех трех создаются списки отображения. В результате этой подготовки можно использовать команду к1са111 ! зс () для переключения с одного шаблона на другой. Листинг 7.9. Списки отображения для изменения режима 6СЫоС остзеС; огтееС = 516ееь(згз(3); 51кен« 3С(етгзеС, 66 СОНР(СЕ), 510(заЫе(61 С1МЕ 5Т1РРСЕ); В(ЕлЕС!3С(); В(Меис(зС(остзеСР1, 6С СОНР1СЕ); 51ЕпаЫе(6С 11МЕ 5Т1РРСЕ); 51С(пе5С(рр1е(1, Вхвуеу); 51ЕпеС(зС(); 51ненС(зС(оу(ее(+2, 6С СОИРХСЕ); 51Елаые(6С С1МЕ 5Т!РРСЕ); 51С(ле5С(ррсе(1, Охпы); 5(ЕлЕС(зС(); Еоег(пе Огаиолеь(пе(х1,71,х2,у2) 51вев(л(6С С1МЕ5); 51ЧегСех2(((х1),(У1)); В1Чегтех2(((х2),(У2)); 51Епо(); 51Са11С(зС(о(тзег); егаиопеС(пе(50.0, 125.0, 350.0, 125.0); 51Са11С(3С(ос(ее!+1); Еганопеь(пе(50.0, 100.0, 350.0, 100.0); 51са11с(зс(огсзесч2); Еганопеь!пе(50,Э, 75.0, 35В.О.
75.Э); Вывод пикселов, битовых образов, шрифтов и изображений После прочтения этой главы вы сможете." ° Позиционировать и отображать данные в виде битовых образов ° Считывать пикселы (битовых и иных изображений) из буфера кадров в оперативную память и из памяти обратно в буфер ° Копировать пикселы из одного буфера цвета в другой или в другую позицию того же буфера ° Увеличивать или уменьшать изображения при их записи в буфер кадра ° Управлять форматированием пикселов и выполнять другие преобразования данных во время их передачи в буфер и обратно ° Выполнять обработку пикселов с помощью расширения 1гпаупц 5ц Ьвег 260 Глава 8 ° Вывод пикселов, битовых образов, шрифтов н изображений До этого времени в руководстве основное внимание уделялось воспроизведению векторных данных — точек, линий и многоугольников.