Как работает масштабирование, панорамирование и вращение?

Используя OpenGL, я пытаюсь нарисовать примитивную карту своего кампуса.

Может ли кто-нибудь объяснить мне, как обычно реализуется панорамирование, масштабирование и вращение?

Например, с панорамированием и масштабированием, я просто настраиваю окно просмотра? Итак, я строю и рисую все свои линии, составляющие мою карту, а затем, когда пользователь щелкает и перетаскивает, он настраивает мое окно просмотра?

Для панорамирования сдвигает ли он значения x/y моего окна просмотра, а для масштабирования увеличивает/уменьшает ли мое окно просмотра на некоторую величину? А для ротации?

Нужно ли для поворота выполнять аффинные преобразования для каждой полилинии, представляющей мою карту кампуса? Не будет ли это дорого делать на лету на карте приличного размера?

Или окно просмотра остается прежним, а панорамирование/масштабирование/вращение выполняется как-то иначе?


Например, если вы перейдете по этой ссылке, вы Я увижу, как он описывает панорамирование и масштабирование точно так же, как я описал выше, изменяя окно просмотра.

Разве это не правильно?


person KingNestor    schedule 25.02.2009    source источник


Ответы (3)


Они достигаются путем применения серии команд glTranslate, glRotate (которые представляют положение и ориентацию камеры) перед рисованием сцены. (технически вы вращаете всю сцену!)

Существуют служебные функции, такие как gluLookAt, которые как бы абстрагируются от некоторых подробностей об этом.

Для простоты предположим, что у вас есть два вектора, представляющих вашу камеру: положение и направление.

gluLookAt принимает позицию, пункт назначения и восходящий вектор.

Если вы реализуете векторный класс, destinaion = position + direction должен дать вам точку назначения.

Опять же, чтобы упростить задачу, вы можете предположить, что вектор вверх всегда равен (0,1,0)

Затем, перед рендерингом чего-либо в вашей сцене, загрузите матрицу идентичности и вызовите gluLookAt.

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( source.x, source.y, source.z, destination.x, destination.y, destination.z, 0, 1, 0 );

Затем начните рисовать свои объекты

Вы можете позволить пользователю развернуться, слегка изменив положение вправо или влево. Вращение немного сложнее, так как вам нужно повернуть вектор направления. Предполагая, что вы вращаете камеру, а не какой-то объект в сцене.

Одна проблема заключается в том, что если у вас есть только вектор направления «вперед», как вы его перемещаете? где право и лево?

Мой подход в этом случае состоит в том, чтобы просто взять векторное произведение «направления» и (0,1,0).

Теперь вы можете перемещать камеру влево и вправо, используя что-то вроде:

position = position + right * amount; //amount < 0 moves to the left

Вы можете двигаться вперед, используя «вектор направления», но IMO лучше ограничить движение горизонтальной плоскостью, поэтому получите прямой вектор так же, как мы получили правильный вектор:

forward = cross( up, right )

Честно говоря, это несколько хакерский подход.

Правильный подход заключается в использовании более «сложной» структуры данных для представления «ориентации» камеры, а не только прямого направления. Однако, поскольку вы только начинаете, хорошо делать все шаг за шагом.

person hasen    schedule 25.02.2009
comment
Позвольте мне добавить, что ни в коем случае окно просмотра (установленное через glViewport) не входит в этот процесс. Окно просмотра определяет, в какой области вашего окна вы будете визуализировать (на самом деле это не так, но пока подумайте об этом именно так) и обычно охватывает все окно. - person Thomas; 25.02.2009

Все эти «действия» могут быть выполнены с использованием функций преобразования матрицы представления модели. Вы должны прочитать о glTranslatef (панорамирование), glScalef (масштабирование), glRotatef (вращение). Вам также следует прочитать базовое руководство по OpenGL, возможно, вам будет полезна эта ссылка.

person okutane    schedule 25.02.2009

Как правило, каждый раз, когда вы ссылаетесь на любую точку в трехмерном пространстве в opengl, применяются три шага.

Учитывая местную точку

  • Локальное -> Мировое преобразование
  • Мир -> Трансформация камеры
  • Камера -> Трансформация экрана (обычно проекция. зависит от того, используете ли вы перспективу или ортогональность)

Каждое из этих преобразований берет вашу трехмерную точку и умножает ее на матрицу.

Когда вы вращаете камеру, она обычно изменяет мир -> преобразование камеры, умножая матрицу преобразования на ваше аффинное преобразование поворота/панорамирования/масштабирования. Поскольку все ваши точки перерисовываются в каждом кадре, новая матрица применяется к вашим точкам, что создает впечатление вращения.

person FryGuy    schedule 25.02.2009