Как работает масштабирование, панорамирование и вращение? - PullRequest
6 голосов
/ 25 февраля 2009

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

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

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

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

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

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


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

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

Ответы [ 3 ]

7 голосов
/ 25 февраля 2009

Они достигаются путем применения ряда команд 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 )

Если честно, это отчасти хакерский подход.

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

4 голосов
/ 25 февраля 2009

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

1 голос
/ 25 февраля 2009

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

Учитывая локальную точку

  • Local -> World Transform
  • Мир -> Преобразование камеры
  • Камера -> Преобразование экрана (обычно проекция. Зависит от того, используете ли вы перспективу или ортогональную)

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

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

...