М. Ву, Т. Девис, Дж. Нейдер, Д. Шрайнер - OpenGL. Руководство по программированию (Библиотека программиста) (2006) (1124363), страница 105
Текст из файла (страница 105)
Пользователь может указать как колесо, так и болт, по это создает две записи реакции. В таком случае вы должны решить, какую запись обрабатывать, возможно, отталкиваясь от значения глубины, определенного для выбранного объекта и соответствующего максимальному прибли- В листинге 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. 8.0, 0.0, 8.9, -0.5, 2.5); 81Ма(г!хнобе(6С МООЕСЧ1ЕЫ); 81Соаб1бепС!СУ(); ) 1пС еа1п(1пС агяс, сьаг "'агач) ( 81иС1п1С(аагас, агзч); 81и(1п110!зр1аунобе(6(ОТ 51Н6СЕ [ 6[ОТ 868 [ ОСОТ ОЕРТН); 81иС1п(СЫ!пбпи51се(299.
200); 81иг1п!Сы)пбоиРоз111оп(199. 190); 81иССгеатеьн пбои(агах[0!); 1пзС(); 81итноисерипс(р(сййестз); 81исйезпарееипс(геспаре); 81иСОззр1аурипс(б!Ер1ау); 81иСМа1пьооР(): гесигп 9: Упражнения ° Измените листинг 23.0, добавив вызовы 81ризниап1е() так, чтобы при выборе в стеке сохранялись составные имена. Каково при этом будет содержимое буфера выбора? ° По умолчанию команда е10ерспйапйе () устанавливает отображение г-значений в диапазон [0.0, 1.0). Попробуйте изменить значения 810ерспйап8е() и посмотрите, как ваши модификации повлияют на г-значения, возвращаемые в массиве записей нажатий. Выбор 483 рекомендации по написанию программы, использующей механизм выбора 5сльшинство программ, позволяющих пользователю интерактивно редактировать кометрические объекты, предоставляют пользователю механизм для предварительного выбора групп элементов или отдельных элементов.
Для программ двухкерного рисования (например, текстовых редакторов, программ верстки и проекшрования электронных схем) может быть легче делать собственные вычисления зля выбора, чем обращаться к механизму Орепб(.. Часто нетрудно выявить конгуры, ограничивающие двухмерные объекты, и выстроить их в иерархическую пруктуру для ускорения доступа. Например, выбор в стиле Орепоь для про~рамы конструирования сверхбольших интегральных схем (У151), содержащих каллиопы прямоугольников, может оказаться относительно медленным.
Вместе стем учет информации об ограничивающих рамках, когда прямоугольники обычно выровнены относительно экрана, может чрезвычайно ускорить процесс зыбо)к в такой программе. Надо полагать, что и написать такой код тоже проще. другой пример. Поскольку нажатия регистрируются только для геометрических збъектов, вы можете захотеть создать собственный метод для выбора текста. Установка текущей позиции растра — это геометрическая операция, но она эффективна только в отношении одиночной доступной для выбора точки, обычно по ней можно опознать только левый нижний угол текста. Если ваша программа-рехзктор требует манипулирования отдельными символами текстовой строки, незбходим другой механизм выбора. Вы можете рисовать небольшие прямоугольники вокруг каждого символа в режиме выбора, но вряд ли такая обработка текста проще, да и носит индивидуальный характер.
Если вы решите использовать механизм выбора Ореп01, организуйте вашу прорамму и ее структуры данных так, чтобы облегчить рисование соответствующих гпнсков объектов как в обычном режиме визуализации, так и в режиме выбора. 3 атом случае, когда пользователь выделяет что-либо мышью, вы можете испольювать те же структуры данных для операции выбора, с помощью которых вы отозражали элементы на экране. Также определитесь с тем, разрешить ли пользовагелю выбирать сложные объекты. Это можно сделать посредством выделения едкого бита каждому подобъекту при сохранении устанавливаемого в момент вызора объекта (такой путь, однако, требует от вас сканирования полного списка злементов для нахождения выделенных).
Вы можете посчитать это полезным для поддержания списка указателей на выбранные элементы в расчете на ускорение поиска. Возможно, это неплохая идея — выделение бита элементу, поскольку, когда вы рисуете полную картинку, вы можете захотеть отобразить выбранные элеяенты как-то иначе (например, другим цветом или в пределах рамки выделения). Наконец, примите во внимание интерфейс пользователя, которому можно разрешить: ю выбор элемента; е захват группы элементов; ° добавление элемента к вылелению; 484 Глава 13 ° Выбор и обратная связь ° добавление захваченной группы к текущему выделению; ° удаление элемента из числа выделенных; ° выбор одного элемента из группы перекрывающихся элементов.