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

StackOverflow https://stackoverflow.com/questions/584463

Вопрос

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

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

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

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

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

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


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

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

Это было полезно?

Решение

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

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

forward = cross( up, right )

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

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

Другие советы

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top