OpenGL. Руководство по программированию (Библиотека программиста) (2006). Ву М., Девис Т., Нейдер Дж., Шрайнер Д (1124475), страница 30
Текст из файла (страница 30)
Квждая плоскость определяется коэффициентами ее уравнения: Ат + Ву е Сг + с) = О. Плоскости отсечения автоматически преобразуются соответственно молельно- видовым преобразованиям. результирующий объем есть пересечение видимого объема н всех полупространств, определенных дополнительными плоскостями отсечения. Напомним, что у многоугольников, подлежащих отсечению, Орепб(. автоматически пересчитывает вершины. Рис.
3.22. Дополнительные плоскости отсечения и объем видимости то!с( д161)рР1апе(С(.епшш рсале, сопзс 01с(опЫе 'ес)иабоп); Определяет плоскость отсечения. Указатель ес)иагсоп адресует тачки для четырех коэффициентов уравнения плоскости, Ах + Ву + Сг + Р = О. Все точки, заданные в координатах глаза (х„у„г„тг,), для которых выполняется выражение (А В С Р)М-с(х„У„гн чс,)т > О, лежат в полУпРостРанстве, опРеделенном плоскостью отсечения, где М вЂ” текущая модельно-видовая матрица.
Все точки, не принадлежащие полупрострапству, определенному плоскостью отсечения, отсекаются. Аргумент р1але принимает значения 6). С).1Р Р6АНЕП где (— целое число, обозначающее плоскость отсечения, в диапазоне от О до максиивльного числа плоскостей отсечения минус один. Кахдую плоскость отсечения предварительно нужно определить: вппаме161 611Р РСАИ61); Опсвюченне плоскости отсечения выполняется командой , 110!ваые161 СС1Р РСАНЕ1); 134 Глава 3 ° Визуализация Все реализации ОрепС]. поддерживают как минимум шесть дополнительных плоскостей отсечения, однако в некоторых реализациях их может быть больше.
Чтобы узнать действительное количество, используйте функцию 916ет]псеае гч () со значением аргумента 6С ИАХ ССТР РСАМЕ5. ПРИМЕЧАНИЕ Отсечение выполняется в координатах глаза, а не в координатах отсечения. Зто различие заметно, если матрица проекций — вырожденная, (То есть матрица проекций по причине нулевого детерминанта переводит трехмерные координаты в двухмерные.) Пример отсечения Программа, приведенная в листинге 3.5, рисует каркас сферы с двумя плоскостями отсечения, которые отрезают три четверти сферы, как показано на рис.
3.23. Рис. 3.23. Усеченный каркас сферы Листинг 3.5. Каркас сферы с двумя плоскостями отсечения: сйр.с чо!б !и!г(чо!б) ( 9161еагса1ог(9.9, 9.0, 9.0, 9.0); 915набенобе!(61 РСАТ); чо!б б!зр1ау(чо!б) ( 6СбоцЫе ецп[4] = (9.9, 1.9, 0.9, 0.9); 6СбоцЫе ецп2[4] = ( 1.0, О.О. 0.9, 0.0); 9161еаг(6С СОСОМ ВОРРЕМ ВХТ); 91Со1огзт(1.9, 1,0, 1.0); 91Рцзннатг!х О; 91тгапз1агет(9.9, 9.0, -5.0); /' отсекаем нижнюю половину — у < 0 */ 9161!РР1апе(6С С[1Р РСАМЕВ. ецп); 91Епаые(6С СС1Р РСАМЕВ); /* отсекаем левую половину — х < 9 "/ 9161(РР\апе(6[ СЕ]Р РСАМЕ1, ецп2); 91ЕпаЫе(6С СС]Р РСАМЕ 1); Примеры объединения нескольких преобразований 135 л)лисасес(99.8, 1.0, 8.9, 0.0): 51игнгге5рьеге(1.9, 20, 16); 51Рорнагггх О; Л!Р1изп О; ) чоы гельаре(1пг н, ! пС П) ( 51Ч!енрогг(9, 8, (6(л1сег) н, (6(л1се1) П): 81Магг1хнобе(6С РЙОЗЕСТ10М); 81(оаб)бепг)гу О; Х1иРеглресг)че(60.0, (6(11оаг) иl(6(!1оаг) П, 1.8, 20.0); Л(МаСггхнобе (бг МООЕСН1ЕИ); !пг ла!п(зпг аглс, сьаг** аглч) ( 81иг1п!С(Магас, аглч); Л1иг1п1101зр1аунобе(ОСОТ 51МОСЕ ! 6ЕОТ ЛОВ); л1иг1п(СИ1пбон51се(588, 509); 81иг1п1гн1пбонРол111оп(199, 190); Е1игбгеагенчпбои(аглч(0)); сп1С(); 51иг01лр1аугипс(б1лр1ау): л1исмезпарегипс(гелпаре); 51иСМа)пгоор(); ге!игл 8: Упражнение ° Попробуйте изменить коэффициенты плоскостей отсечения в листинге 3.5.
° Попробуйте осуществить моделъно-виловое преобразование, например Ерсо гаге* (), для изучения функции к161! рР1ане () . Сделайте плоскости отсечения независимыми от объектов в сцене. Примеры объединения нескольких преобразований Этот раздел демонстрирует, как комбинировать несколько преобразований для получения требуемого результата. Он содержит два примера: солнечная система, ибьекты которой нужно вращать вокруг их осей и по их орбитам, и рука робота, ючлененная в нескольких местах, при движении которой преобразуются связанлие с суставами системы координат.
Сплнечная система Программа, представленная в этом разделе, рисует простую Солнечную систему, слстоящую из Солнца и планеты, при помощи команд рисования сфер. Вращение солнца и планеты вокруг собственных осей реализовано командой к1йогаге* (). 136 Глава 3 ° Визуализация Для перемещения планеты по орбите применена команда 81тгап51ате*(). Требуемые размеры сфер зада!отея аргументами функции к!0!И! ге5 рве ге (). Для рисования Солнечной системы сначала нужно опрелелить модельно-виловые преобразования н преобразования проецирования. В данном примере используются команды 810Регзрестьуе() и 810Ьоохдт(). Рисование Солнца тривиально, поскольку Сольще неподвижно относительно начала фиксированной системы координат и перемещение не требуется. Для остального, то есть вращения Солнца вокруг оси, достаточно к\котате* () .
Рисование планеты, вращающейся вокруг Солнца, как показано на рис. 3.2/ь, требует нескольких модельных преобразований. Планета оборачивается вокруг своей оси за один день, а за год она совершает полный оборот вокруг Солнца. Рнс. 3.24. Солнце и планета Для определения порялка модельных преобразований представим, что происходит с локальььоьй системой координат.
Функция к1дотасе*() вращает локальную систему координат, которая изначально совпадала с фиксированной системой координат. Затем функция я1тгап51ате' () перемещает локальную систему координат в точку на орбите планеты. Расстояние переноса равно радиусу орбиты. Таким образом. функция 8180(ате* () определяет положение планеты па орбите (текущее время года).
Затем вторая функция 81йоса1е* () поворачивает локальнуьо систему координат вокруг локальной оси, тем самым залавая время суток на планете. Когда все команды преобразований выполнены, рисуется планета. Итак, имитация Солнечной системы реализуется следуилцей последовательностью команд (полностью программа приведена в листинге 3.6): 81Ризьнасгьх(); 8!о!И! ге5рлеге(1.8, 20, 16); рисуем солнце '/ 81аотатет((6с(1оат) уеаг, 0.8, 1.0, О.О); 8!тгапз!атет(2.8. 0.0, 0.8); 8!Ялте(ет((81(!оет) ОаУ. О.О, 1.8, 0.8); 8!осиьгезрпеге(8.2, 18. 8); /' рисуем планету */ 81Рорнасг!х(); примеры объединения нескольких преобразований 137 Листинг 3.б. Планетарная система: р(апе(.с !(а((с !пт уеаг = 8, бау = 0; чо!б !и!1(чо!б) ( 81С(еагсо(ог(0.0, 0.0, 0.0, 8,0); 515лабеиобе1(6С АУСАТ)'. ) чо!б б(ар1ду(чо(б) ( 51С(еаг(6С СОСОй ВОГРЕй 81Т); 51СЬ1огзг(1.8.
1.0. 1.8); 81Рцапид(гтх(), 51о(Н!ге5рлеге(1.0, 20, 16); /' рисуем солнце '/ В(йо1а1е(((6С(1оас) уеаг, 0.0, 1.0, О.О); 51Тгапа1а(ег(2.8, 0.0, 0.0); В(йо(асе(((6С()оа() бау, В.О, 1.8, В.О); 51о(И! ге5рлеге(0. 2, 10, В); /* рисуем планету */ 51Рарна 1 г ! х (); 51о(5нарво((ега(); ) чо(б ге!ларе(!пт н, (пс П) ( 5)ч!еирогт(8, О, (6са(ает) и, (6са!ае!) и)! 51насгтхиобе(6С Рйо)ЕСТ!ОН); 51(оаб(беп(!(у(); 51оРегарессчче(60.0, (6С(1ааС) и/(6С!\пас) П, 1.0, 20.0); е(ласт(хлебе(6( НООЕСУ)ЕН); 81Соаб(бент!Су(); 51о(ооХА((8.0, 0.8, 5.0, 0.0, 8.0, О.О, 0.0, 1.0. О.О); чо!б Хеуьоагб(опа!Бпеб слаг Кеу, (пс х, !пт у) ( !и!тел (Кеу) ( сазе 'б': бау = (бау +1О) К 3 60; 81ц(Роатйеб(аР1аУ() Ьгеак: сапе '0': бау " (бау — 10) % 360: 81ц(Роа1йеб(аР1аУ(); Ьгеэх; саае 'у': уеаг = (уеаг +5) % 3 60, В)оспоасйеб!ар(ау(); Ьгеах; саае 'У': уеаг = (уеаг — 5) % 3 68; 81ц(Роасйебтар1ау(); Ьгеак; продолженое Р 138 Глава 3 к Визуализация Листинг З.б (продолжение) ветви!1: Ьгеах; 1пт па1п(1пт агкс.
сваг" агви) ( а)ит(п1!(аагас. агау); а)ит)п!(0(зр!ауиобе(СЬит ЬОВВЬ5 ! Сгит аСВ); В)ит)п1(И!пбои5!те(500, 500); В!ит)п1(Н!пбоиео51(1оп(100, 100); в!итсгеа(еу)!лбов(агат[0]); !п11(); а)и(0!зр)аурипс(б!ар!ау); а)итаезпарегипс(гезьаре)') а)иткеуЬоагбгипс(хеуЬоагб); а)и!на(п!.оор(); ге(игл 0; Упражнение ° Попробуйте добавить луну к планете или несколько луп и планет. Подсказка: используйте функции а) Ризбиатг(х() и а)Рарнатг(х() для хранения и восстановления положения и ориентации системы координат в требуемый момент времени. Если вы решили обзавестись несколькими спутниками, следует сохранять систему координат до позиционирования каждой луны и восстанавливать ее после рисования каждой луны.
° Попробуйте наклонить ось планеты. Сочлененная рука робота Этот раздел содержит программу, которая создает сочлененную руку робота из двух пли более сегментов. Рука должна быть подвижна в плече, локте нли других суставах. На рис. 3.25 приведена рука с одним подвижным суставом. Рис. 3.25. Рука робота Для рисования сегментов руки подходит масштабированный (вытянутыт1) куб, но сначала вам надо применить модельные преобразования для ориентирования каждого сегмента. Так как центр локальной системы координат изначально нахо- Примеры объединения нескольких преобразований 139 амгся в пентре куба, нужно переместить локальную систему координат к одной ю границ куба.
С другой стороны, хотя физически сустав двигается относительно шарнира, ло- шческн куб вращается вокруг своего центра. Поэтому после вызова функции 51Тгап51 а те* () для указания точки вращения и функции к! ВО Саге* () для вра- щеввя куба мы возвращаемся к центру куба. Затем, перед рисованием, куб мас- птабируется (сплющивается или растягивается). Функции к1ризьмасг!х() и 51рорнасг)х() ограничивают применение вносимого функцией к15са1е'() эф- фекта. Код рисования первого сегмента руки будет выглядеть примерно так (пол- ная программа приведена в листинге 3.7); С!Тгап51аСеч(-!.8, О.
О, 9. 0); с!Мосасег((ссг)оас) зьоо!Оег, 9.8, 9,9, !.9); 51тгап51агеч(!.8, 0.0, 0.8): 51РшП Ма! г ч х (); 5!5са1ег(2.0, 0.4, !.0); 51ЬСМ(геСЬЬе(!. 0); 5!Роряагг! х(); Поскольку система координат раз была повернута, ось х уже ориентирована месь длины руки. Таким образом, для рисования следующего сустава необходим перекос вдоль оси х локальной системы координат в следующую точку враще- аия. В этой точке вращения опять можно использовать приведенный выше код.