OpenGL. Руководство по программированию (Библиотека программиста) (2006). Ву М., Девис Т., Нейдер Дж., Шрайнер Д (1124475), страница 104
Текст из файла (страница 104)
(То есть ширину и высоту можно интерпретировать как чувствительность устройства позиционирования.) Массив ичекрочт[1 содержит текущие координаты окна просмотра, которые могут быть получены вызовом я\Ое1101еяегч(01 Н1ЕиРОйт, 61!01 «ч!енрог1). Результат, вырабатываемый командой д10Р!СКМатг!х(), преобразуется в область отсечения — единичный куб, где — 1 < (х, у, г) < 1 (или -ш < (шх, и/у, шз) < и/). Матрица выбора эффективно выполняет ортогональное преобразование, сводя- в(ее область отсечения к единичному кубу.
Поскольку допускаются преобразования произвольного характера, вы можете делать различные действия над облагтью выбора — например, вращать прямоугольные участки окна. В отдельных ситуациях это легче, чем задавать дополнительные плоскости отсечения для опРеделеччия области выбора. Явстипг 13.3 иллюстрирует выбор, делаемый с помощью указателя мыши. Здесь также показано, как используется множество имен для идентификации различных компонентов примитива; в этом случае объектами выбора являются строка и столбец. Рисуется сетка из квадратов 3 к 3 различных цветов. Массив Ьолггч[3] [3[ !Ранит информацию о цветах для каждого квадрата.
При нажатии левой кнопки выши вызывается процедура рчсх5ч)иагез(), которая идентифицирует квадратн, выбранные мышью. С каждым квадратом сетки связаны два имени: одно— ыя строки и другое — для столбца. Также, когда нажимается левая кнопка мыши, ювеняются цвета всех квадратов, расположенных в позиции указателя. йвстииг 13.3. Пример выбора с помощью указателя мыши: р)с)чэ()ваге,с И! Ьоагб (3) (3); / ' количество цветов для каждого квадрата */ /* Сброс значении цвета для каждого квадрата доски '/ чочб !лч 1(ччочб) ( члт гог (! = 0; ! < 3,' !««) тбг (1 = О; ) < 3; ) ++) Ьовгб(ч1[)) = 0; 3)С)еагсо!ог(9.0, 0.0, 0.0, В.О), ) и(б бгви5ливгев(01елиж жббе) продолжение Ф 476 Глава 23 ° Выбор и обратная связь Листинг 13.3 '(продолжение) 6Си(пС т, 1ог (! =О; ! <3; т++) ( )1 (жопе == 6С 5ЕСЕСТ) В(Соапнаве(!); тот (] = О; ) < 3; ) <+> ( ! 1 (врое == 6С 5ЕСЕСТ) В]РозПМаве()); В[Со[ог31((6С1[оаС) [/З.В, (6С1[оаС) >/З,В, (6С1[оаС) Ьоагв[)][>]/3.0); В[Нес» (!.
). т<). >+[); ! 1 (воде == 6С 5ЕСЕСТ) В[Роряаве(): /' Процедура ргосеззН[Сз выводит содержимое массива записей реакции "/ чета ргосеззН(Сз(6СтпС П(Сз, 6Со[пС Ьоттег[]) ( цпз[йпед тпС [, 6Со(пС [т, )), павез, *ртг; рг[пС1("записей = йд'тп", П(Сз); ртг = (6(ц(пС *) Ьц[тег; 1ог (! = О; т < п[сз; [++) ( /* для каждой записи */ павез = 'рсг! рг[п(1(" число имен для данной записи = %!['тп", павез); рсг++; Рг!'п[1(" х1 = ВВ;", (1[оаС) "РСг/Вх71111111); РСг++; р» пС1(" з2 = ХВ'тп", (1[оаС) 'р(г/Ох71111111); ртг++; рг)пС1(" имена "); 1ог () = О; ) < павез; )++) ( /' для каждого имени '/ рг!п(1("ХО ", *р(г); т 1 () == О) /' установка строки и колонки )! = 'рсг; е[зе [1 () == [) )) = "рсг: рсг++; ргтп(1("(и"); Ьоагп[тт] ())] = (Ьоагп(т!] [))] < С> Х 3: №Ое1[пе ВО15[2Е 512 чо(О ртсй5диагез((пС Ьо(Соп, зпС зеа(е, тпС х, !пС у) ( 6[и[и! яе]есСВцв[ВОР512Е]: 6СтпС Пттз; 6СтпС ч[енрагС[4]; Выбор 477 т( <Сот<оп .= 660т <Ерт ВОТТОН [[ атаев <= 6<От ООИН> гесцгп; 916ес1псевегч(6с ч1еиРОйт, чтеирогс); 915Е!ЕССВис(ЕГ(ВОГ511Е, ЗЕ1ЕССВЦГ); [ (ЧО<б) 91йЕПбЕГМОбЕ(6С 5ЕСЕСТ); 911п!<Навез(); Всрцзииаве<9); 91ИаСгтхИобе( 6!.
Рйо)ЕСТ1ОН); 91РцзПИаегтх(): 91Соаб1бепС<Су(); <' создает область выбора разиером 5х5 пиксепов в позиции указателя */ 91цР<<ййатг<х((6(боцб<е) х, (6Сбоцб)е) (ч<еирогС[3) - у), 5.9, 5.0, чтеирогС); асцОгСПого<Е.Е, 3.О, О,Е, 3.9>; бгаи5оцагез(6С 5ЕСЕСТ); 91Ма<гтхМобе(6С Рйо>ЕСТ10Н); 91Рорйа<гтх(); 91Р1цзп(); П<Сз = В>йепбегйобе<66 йЕНОЕй>; ргосеззН<Сз(И<Сз, зе1ествцс); 91цсРозсйебтзр1ау(); т чотб б<зр1ау(чо<б) ( 91С1еаг(6С СО(Ой ВОРРЕй В1Т); бгаи5пцагез(6С йЕНОЕй); В<Р)цзи<>; ) чо<б гезпаре(<пс и, тпс и) В<Ч<еирогС(9, О, и, П); 91ИаСг<хМобе(6С РВО>ЕСТ10М); 91Соаб1бепС<Су<); 91иО о20(О.О, 3.0, 9.0, 3.9): 91Ма<гтхМобе<6С НООЕСЧ1ЕИ); 91Соаб1бепС<Су(); ) <пс ватп(тпс агвс, спаг*' агеч) [ ВсцС1п<С(еагвс, агвч); В!цС1п<СОтзр1ауМобе(ОСОТ 51НОСЕ [ 6(ОТ й6В); 91цС1п<СИтпбои5<се(199, 190): 91цС1п<СИ<пбоиРоз<С<оп(199, 100); 91цССгеатеи<пбои(агвч[9[): <п<с(): продопжение,р 478 Глава 13 к Выбор и обратная связь Листинг 13.3 (продолжение) В1о1номвеуопс(р)сх5ямагев); Р1итаевларегмпс(гевларе); 51и10аар)ауямпс(б1ар1ау); 51отна1псоор(); гетогп Е, Выбор мышью с помощью составных имен и иерархической модели Составные имена могут также использоваться для выбора части иерархического объекта сцены.
Например, если вы отображаете сборочную линию автомобилей, может потребоваться позволить пользователю передвинуть мышь и выделить третий болт на передней стороне колеса третьего автомобиля на линии. Для идентификации каждого уровня иерархии можно использовать отдельные имена: автомобиля, колеса и болта. Но есть и другой вариант, когда одним именем можно описать только одну молекулу во множестве молекул, где дополнительными именами можно различить отдельные атомы, принадлежащие молекуле. Листинг 13.4 — зто модификация листинга ЗА, где рисовался автомобиль с четырьмя одинаковыми колесами, а каждое колесо имело пять идентичных болтов.
Код был дополнен лишь манипуляциями со стеком имен в иерархической модели объектов. Листинг 13.4. Создание составных имен бган иьее1 апб Ьо)тв() ( )опв 1; бган инее) Ьобу(); (1 = 0; 1 < 5; 1++) ( 51РмвьМасг(х(); В)Рогато(у).В'1, В.Е, В,В, В1тгапв1асе((3.0, 0.0, 0.0)) 61Ривлнаве(1); бган Ьо(г Ьобу(); В1Рорнаве(); к1РорМасг1х(); бган Ьобу апб илее1 апб Ьо1тв() ( бган саг Ьобу(); З1Ровлнасг)х(); 51тгапв1асе(40, О, 20); /* положение первого колеса */ З1Ривпмаве(1)) /* имя колеса с номером 1 */ бган илее( апб Ьа1(в(): З1Рорнаве(); а1РорМагг1х(): к1Рмялнагг!х(),' В1тгапв1асе(40, О, -20); /* положение второго колеса */ Выбор 479 к1РивПйаве(2); l* имя капесв с номером 2 *I бган иПее1 апб Ьо11в(); д1Рорйаве(); к1РорйаСг!х(); М аналогичное рисование дпя двух других колес Листинг 13.5.
Использование составных имен бган тпгее свгв() ( к11п ! (навея (); Х1Ровпйа1г!х(); сгапк1вте Со !!тот саг роя!С!оп(); к)Рокпйаве(1); бган Ьобу апб илее1 апб ЬЬ1(в(): Б1Рорйаве(); Б1Рорйатг!х(): к)яовпиасг!х(); тгвпв1ате то яесопб саг ров!т!оп(); к1Рпвпйвве(2); бгви Ьобу апб ипее1 апб Ьо11в(); Б1Рорйаве(); к)Рорнатг!х(); $1РО5ПМатг!х(); тгапь1вте то тптгб свг ров!1!оп(); В1Рняпйаве(3); бган Ьобу апб ипее1 апб Ьо1(в(); Х1Рорйаве(); к1РорМасг!х(); ) Предположилт, что выбор сделан. Ниже показаны некоторые возможные возвра- иаемые из стека имен значения и их интерпретация.
В этих примерах в большип- пве возвращается одна запись реакции; с(1 и с(2 — значения глубины. 2б1 б221 Явтомобиль 2, колесо 1 Корпус автомобиля 3 Болт О на колесе !автомобиля 1 1б) б2 3 3 Й б2 1 1 0 Попытка выбора за пределами всех автомобилей пусто Последняя интерпретация исходит из того, что в одной области выделения нельзя одновременно выбрать болт и колесо.
Пользователь может указать как колесо, так и болт, по это создает две записи реакции. В таком случае вы должны решить, какую запись обрабатывать, возможно, отталкиваясь от значения глубины, определенного для выбранного объекта и соответствующего максимальному прибли- В листинге 13.5 используются процедуры из листинга 13А для рисования трех различных автомобилей, нумерованных в порядке 1, 2 и 3. 480 Глава 13 а Выбор и обратная связь жению к точке наблюдения.
Использование значений глубины разбирается в сле- дующем разделе. Выбор мышью и значения глубины Листинг 13.6 демонстрирует, как использовать значения глубины для выбора из выбранных объектов. Эта программа рисует три перекрывающихся прямоугольника в нормальном режиме визуализации.
Когда нажимается левая кнопка мыши, выполняется вызов процедуры р!С)саессз(). Эта процедура возвращает позицию указателя, активирует режим выбора, инициализирует стек имен и производит умножение матрицы выбора на текущую матрицу ортогональной проекции. Выбор регистрируется для каждого прямоугольника, поверх которого находится указатель в момент нажатия левой кнопки мыши.
Наконец, исследуется содержимое буфера выбора с целью идентификации именованных объектов, захваченных областью выбора. Прямоугольники рисуются с различной глубиной, то есть значениями координаты х Поскольку для идентификации всех трех прямоугольников используется одно имя, может быть зарегистрирована только одна запись реакции. Тем не менее эта одна запись обладает различающимися максимальным и минимальным значениями х Листинг 13.6. Выбор мышью с привлечением значений глубины: р!С((берС)),с хо!б !и!С(чо!б) ( 9161еагсо1ог(8.8, 8.0, 8.8, 8.0); 81Епаше(6С ВЕРТН ТЕ5Т); 815ьабенобе1(6С ЕСАТ); 910ерспаапае(9.9, 1.0); /* с-отображение по увопчанию '/ чо(б бганаеста(6Сепчв вобе) (! (вобе == 6С 5ЕСЕСТ) 81Соабйаве(1); 918ез!п(60 00А05); 81са(огЗТ(1.9, 1.8, 8.9); 81ЧегтехЗ((2, 9, 9); 81Чег(ех3((2, 6, 9); 8!ЧегтехЗ!(б, б, 9); 81ЧегсехЗ((6.
9, 8): 91Епб(); (! (вобе == 6С 5ЕСЕСТ) 91Соабиаве(2); 919еа(п(6с 00А05); 91Со1огзс(0.0, 1.0, 1.8); 91ЧегСехЗ!(3, 2, -1); 91Чег(ехЗ!(3, В, -1); 91ЧегСехЗз(В, В, -1); 81ЧегтехЗ!(В, 2, -1); 81Епб(); Выбор 481 ст (воде == 6( 5ЕСЕСТ) 61(оабйаве(З); 51Ведзп(6[ ООА05); 516о1ог3!(1.0, О.О, 1.0); 51Чегтех31(В, 2, -2); В[Чегсехзч(В, 7, -2); В[Честен)1(5, 7, -2); 51Чегтехзс(5, 2, -г); 51[по(); ] чочб ргосеззн1(з(6(зпс пссз.
6(ц!пс ьцттег[]) [ нпз1бпеб спС 1, ]; 66ц]пс навез, 'рсг: ргчптт("записей = %бтп", П11з); ртг = (6ЕЬ[пт ') Ьцт!ег; !ог (! = 0; ч < п[сз; чча) ( /' дпя каждой записи */ павез = 'ртг; рг[пт((" количество имен для записи = Хб(п", павез), ртг++; рг!псг(" з) = йй;", (![оас) 'рсг/Вхгттттттт); рсг++, рг1псч(" з2 = %|(п", (11оас) "рсг/Вх71((гтт(); рсгчч; рг1пст(" имя "); гог () = 0; ) < павез: ]+ч) ( /" дпя каждого имени '/ рг1птт("яб ". 'ртг); ртг<ч; ) ргзпС(("(п"); ) збе1чпа ВОР517Е 512 чо1б р1схйестз(1пт Ьцттоп, чпт агате, [пт х, 1пт у) [ 6(цспт зе1есСВцт[ВОР517Е]; 6(1пт и[15,' 6(1пт чсенрогС[4], 1! (Ьцттоп != 6ЕЬТ СЕЕТ ВОТТОМ [[ агате != ОСОТ ООИМ) гесцгп; 516ет[птебегч(6Е Ч[ЕМРОВТ, чзеирогт); 515е1есСВц!Гег(ВОР517Е, зе1есСВц!); (чо1б) 61депбегйобе(6( 5ЕЕЕСТ); 51[п!(Навез(); 51Рцзпйаве(0); 51йатг1хйобе(6( РКО)ЕСТ10й); 51РцзнйаСгчх().
51Еоаб1бепт[СУ(). /" создает область выбора размером 5х5 пиксепов в позиции указателя мыши '/ 51цР[скиасг!х((6(боцые) х, (6(бочые) (ч[енрогс[3] - у), 5.0, 5.0, чченрогт); продопжвнов р 482 Глава 13 ° Выбор и обратная связь Листинг 13.6 (продолжение) 810гСПо(0.0, 8.0, 9.0, 8.0, -0.5, 2,5),' бганйессс(6( 5есест); 81РорМаСг!х(); 81Е1иаь (); П(Сз = 81йепбегМобе(6( йЕНОЕй); ргосеьан(се(п115, зе1ессВие); чо1б б!Ер1ау(чо1б) ( 8161еаг(6С Соьой ВОЕЕЕй 81Т [ 6[ ОЕРТН ВОЕЕЕй 81Т); бганйестз(6С йЕНОЕН),' 81Е1иеь (); чо1б гехьаре((пС и, !пС П) ( 81Ч!енрогС(9, О, (6(е1се!) и, (6!а(се!) П); 81Ма(г!хМобе(61 Рйо!ЕСТ[ОН); 81Соаб[бепС!СУ(); 810гСПо(0.9.