М. Ву, Т. Девис, Дж. Нейдер, Д. Шрайнер - OpenGL. Руководство по программированию (Библиотека программиста) (2006) (1124363), страница 24
Текст из файла (страница 24)
В стандарте С массивы хранятся по строкам, и здесь этот элемент берется из точки пересечения 1-й строки иуьго столбца. Один из способов избежать разночтений между строками и столбцами состоит в объявлении матрицы как и[16). Другим способом является использование функций Орепб[ ц1Ьоавтгаозрозе- Магг!х*О и я1ни1(тгапзрозенагг!х'О, которые оперируют с матрицами со- гласно стандарту С.
Аргументом й1(оабМагг!х*О и к1Мо1(Магг!х*О является вектор из 16 значений (иь ив..., т„), который определяет матрипу М в порядке столбцов следующим образом: г«одепьно-видовые преобразования 107 гоЯ а1~оаотгапзрозеМасг1х(Я)(сопзс ТУРЕ "гл); Устанавливает 16 значений текущей матрицы, взятых из матрицы т, элементы которой хранятся по строкам. Такой же эффект оказывает вызов функции ~11оаеМасг1х*(гл7). тоЫ а1Ио11тгапзрозеиасг1х(Я)(сопзс ТУРЕ "гл); Умножает матрицу т, определяющую 16 значений, на текущую матрицу и сохраняет результат в последней. Эквивалентно вызову функции а1Ии11Иасг! х'(тТ). Избежать лишнего пересчета и тем самым повысить эффективность преобразований можно за счет списков отображения, поместив в них часто используемые матрицы (и также им обратные).
(См. раздел «Философия проектирования списков отображения» главы 7.) ОрепСЕ часто приходится выполнять транспонирование молельно-видовой матрицы для того, чтобы нормали и отсекающие плоскости были правильно преобразованы в координаты глаза. Модельно-видовые преобразования Модельные и видовые преобразования тесно связаны между собой и в ОрепОЕ фактически объединены в одну модельно-видовую матрицу. (См.
раздел «Пример; рисование кубам) Одна из нетривиальных дилемм, появившихся в компьютерной графике недавно, — это выбор соответству|ощей совокупности трехмерных преобразований. Как вы уже видели, задачи решаются неоднозначно: мы цожем переместить камеру в прямом направлении или же объект в противоположном. Каждый из вариантов имеет преимушества и недостатки, но в ряде случаев какой-то один более естественно отражает суть преобразований. Если вы способны найти ненадуманный подход, применимый к вашему приложению, вам будет легче реализовать в програмл1ном коде нужные матричные операции, реализующие эти преобразования.
Поэтому первая часть данного раздела посвящена вопросам продумывания преобразований, а вторая — командам. Все применяемые в дальнейших примерах команды для работы с матрицами вы уже встречали. Не забывайте, что перед выполнением модельно-видовых преобразований вы должны вызывать функцию а1Иатг1хиооео со значением 6~ ИООЕь1Г1ЕИ в качестве аргумента. Размышления о преобразованиях Начнем с двух простых действий: поворота на 45' против часовой стрелки относительно оси г и сдвига вниз по оси х. Предположим, что объект, который вы строите, мал по сравнению с перемещением (чтобы лучше видеть эффект от перемещения) и расположен в начале координат.
Если сначала повернуть объект, а затем его сместить, объект будет располагаться на оси х. Если же сначала сместить его по оси х, а затем повернуть относительно начала координат, он попадет на линию у - х, как показано на рис, 3.4. То есть порядок действий является критич- 108 Глава 3 ° Визуализация ным. Если вы производите преобразование А, а затем Б, почти всегда результат будет отличным от того, каким бы он был, если бы вы их выполняли в обратном порядке. Рис. 3.4. Поворот ипи сдвиг, вот в чем вопрос Теперь давайте поговорим о порядке, в котором производятся преобразования. Все модельно-видовые операции представляются матрицами размерностью 4 х 4. Каждое выполнение х1ио1(нас г(х* О или команды преобразования умножает новую матрицу М (4 х 4) на текущую модельно-видовую матрицу С; в результате образуется матрица СМ.
Затем вершины о умножаются на теку)цую модельновидовую матрицу. Это означае~, что последняя команда преобразования, вызванная в ва)пей программе, на самом деле является первой применяемой к вершинам: СМч. Таким образом, напрашивается мысль, что матрицы определяются в обратном порядке. Однако, как часто случается, по результатам размышлений что-то противоположное оказывается правильнее скороспелого вывода. Посмотрите на следуюший код, который рисует одну точку с помощью трех преобразований: Х1Матг(хиоее(6( ИООЕЕЧ1ЕИ); В1(оаа)бент(ту(): В1Мо1(Магг(хт(И); /' преобразование и */ Х1Мо1(Магг!хт(И); /" преобразование И */ В1Мо1тиатг1х((Е): /" преобразование Е */ В1вех~п(6Е Р01МТ5); В1чегтехзт(ч]; /' рисуем измененную вершину ч */ Х1Епб(): Здесь матрица преобразований претерпевает изменения в порядке Ь Х, ХМ и ХМЬ, где Š— единичная матрица. Измененная вершина — ХЬМч.
Отсюда преобразование вершины равно Х(М(Ьч)) — то есть вершина ч сначала умножается на Ь, результат Ьч умножается на М, и результат МЬч умножается на Х. Обратите внимание, что преобразования для ч происходят фактически в обратном порядке по сравнению с тем, как онп были указаны. (Реально выполняется только одно умножение вершины на модельно-виловую матрицу. В данном примере матрицы Х, М, и Ь уже псремножены до того, как онн применяются к ю) Модельно-видовые преобразования 109 Система фиксированных координат Итак, если отталкиваться от системы фиксированных координат, в которой положением, ориентацией и маспггабированием модели управляет умножение матриц.
можно считать, что умножение осуществляется в обратном порядке относительно следования команд в написанном коде. Из простого примера, показанного в левой части рис. ЗА, становится понятно, что для того, чтобы после выполнения операций объект лежал па оси, необходимо сначала выполнить поворот, а затем сдвиг. А для этого нужно поменять последовательность операций на обратную, то есть код будет выглядеть следуюп(им образом (где К вЂ” матрица вращения, а Т— сдвига): а)на(г1ХНрсе(ЦГ НОВЕ()/)ЦИ); а1(оаа!г)еп(1(у () . а1ви1(ма(г1хг(т); /* сдвиг а1нв1(на\г1х((а): /* вращение */ агах (ие аь) ес1(); Локальная система координат Можно подойти к вопросу видовых преобразований с другой стороны и забыть о системе фиксированных координат в пользу локальной системы координат, которая привязана к рисуемому объекту. В ней все операции происходят применительно к локальным координатам, а умножение матриц в коде выполняется в естественном порядке написания команл.
(Независимо от подхола, код остается тем же, просто воспринимается он иначе.) Возвращаясь к примеру перемешенияповорота, представим объект с прикрепленной к нему системой координат. Пара/пельный перенос сдвигает объект и его систему координат вниз по оси х. Затем объект поворачивается относительно начала координат (несмещенного), нс меняя своего расгголожения на оси. Зтот вариант годится для приложений наподобие сочлененной руки робота: в плече, локте, запястьях и на каждом пальпе. Чтобы оценить, как кончики пальцы переместятся относительно тела, предпочтительно начать вращение и смещение с плеча и опускаться вниз в порядке перечисления. Обратное представление является более запутанным. Второй подход бывает более сложным, особенно при наличии масштабирования, и тем более когда оно неоднородно, то есть коэффициенты для различных осей разные.
После неоднородного масштабирования сдвиг перемещает вершины с учетом множителя от предыдущего преобразования, так как система координат сжата нли растянута. Такое масп(табирование, смешанное с вращением, может привести к тому, что оси системы координат потеряют перпендикулярность. Как упоминалось ранее, обычно в коде команды видового преобразования предшествуют командам модельных преобразований. В этом случае вершины модели сначала получают требуемую ориентацию, и затем срабатывают преобразования вида. Видовые команды должны идти первыми, поскольку умножение матрип задается в обратном порядке.
Однако не обязательно определять какие-либо молельно-видовые преобразования, если достаточно действий по умолчанию. Когда 110 Глава 3 ° Визуализация преобразования вида пе определены, «камера» находится в начале координат, «смотрит» вдоль оси г в минус бесконечность. Если не заданы явно модельные преобразования, модель не перемещается и сохраняет свои положение, ориентацию и размер. Так как команды модельных преобразований могут использоваться вместо видовых преобразований, они пригшмаются е рассмотрение первыми несмотря на то, что команды видовых преобразований в действительности выдаются раньше.
Программисты при составлении кода должны отталкиваться от этого постулата. Часто сначала пишут весь код, необходимый для композиции сцены, включая позиционирование и ориентирование объектов друг относительно друга. Затем определяется местоположение точки наблюдения, связанной со всей сценой, и добавляется код для соответствующих преобразований просмотра. Модельные преобразования В Орепо(. определены три команды модельных преобразований; я1Тгап з1аге* (), я1яотаге* () и 515са1е" (), Эти три функции трансформируют объект (или систему координат, если думать об изменении системы координат, а не объекта) посредством сдвига, врашения и масштабирования.
Результат эквивалентен мультиплицированию матриц преобразования, вращения или масштабирования с последуюшим вызовом команды я1И>11Иагг1х»О, принимаюшей полученную матрицу в качестве аргумента. Однако означенные команды дают результат быстрее, чем к1Ии11Иат г)х* О. Ореп('ь автоматически вычисляет нужные матрицы за вас. (См. приложение Е для получения более подробной информации.) Каждое умножение матриц можно описать в терлшнах операций над вершинами геометрического объекта в фиксированной системе координат или в терминах операций над локальной системой координат, связанной с объектом.
Перемещение гоЯ я1Тгапз1ате(Я)(ТУРЕ х, ТУРЕ у, ТУРЕ г)' Перемножает текущую матрицу и матрицу, которая перемешает объект с помощью значений х, у и г (или сдвигает локальную систему координат на те же значения). Рисунок 3.5 показывает результат использования команды я1Тгапз1ате«О. Вращение чоЯ к1когате(Я)(ТУРЕ апц1е, ТУРЕ х, ТУРЕ у, ТУРЕ г); Перемножает текущую матрицу и матрицу, врашаюшую объект (или локальную систему координат) против часовой стрелки вокруг луча из начала координат в точку (х, у, г). Аргумент апфе определяет угол поворота (в градусах).
Результат работы функции В1 Рога те г (45, О; О, О; 6, О: 1, 9), поворачиваюшей объект вокруг оси г на 45', показан на рис. 3.6. Модельно-видовые преобразования 111 Рис. 3.5. Перемещение объекта Рис. З.б. Вращение объекта Поинттте, что объект, располагающийся дальше от оси вращения, будет повернут больше (имеет большую орбиту вратцения), чем объект, находящийся недалеко от оси вращения. Если значение аргумента аль)е равно нулю, команда а1иотате*() ничего не делает. МОСШтабИРОВаНИЕ еоЫ В15са1е(Ы)(ТУРЕх, ТУРЕу, ТУРЕг); Умножает текутцую матрицу на матрицу, определяющую растяжение, сжатие пли зеркальное отражение объекта относительно осей.
Каждая координата х, у и г каждой точки обьекта умножается на соответствующее значение х, у или г. Если рассматривать операцию с точки зрения локальной системы координат, на те же значения растягиваются, сжимаются нли отражаются оси локальной системы координат, и, соответственно, трансформирустся связанный с ними объект. Рисунок З.7 демонстрирует результат выполнения команды 515са1ет(г.в: -0,5: 1,Е) . Функция а15са1е* () выполняет три преобразования, изменяющих размеры видимого объекта: масштабирование со значением больше 1.0 растягивает объект, а значение меньше 1.0 уменьшает его.