OpenGL: понимание трансформации - PullRequest
0 голосов
/ 05 марта 2011

Я пытался понять урок 9 из учебника NEHE, в котором речь идет о перемещении растровых изображений в трехмерном пространстве.

самое интересное здесь - это перемещать 2-мерную растровую текстуру по простому четырехугольнику через трехмерное пространство и постоянно держать его лицом к экрану (зрителю). Таким образом, растровое изображение выглядит трехмерным, но все время находится на 2d лицом к зрителю, независимо от того, где оно находится в трехмерном пространстве.

В уроке 9 создается список звезд, движущихся по кругу, что выглядит действительно красиво. Чтобы не видеть звезду сбоку, кодер делает хитрое кодирование, чтобы звезда постоянно смотрела на зрителя.

код для этого следующий: (следующий код вызывается для каждой звезды в цикле)

glLoadIdentity();
glTranslatef(0.0f,0.0f,zoom);
glRotatef(tilt,1.0f,0.0f,0.0f);
glRotatef(star[loop].angle,0.0f,1.0f,0.0f);
glTranslatef(star[loop].dist,0.0f,0.0f);
glRotatef(-star[loop].angle,0.0f,1.0f,0.0f);
glRotatef(-tilt,1.0f,0.0f,0.0f);

После линий выше начинается рисование звезды. Если вы проверите последние две строки, вы увидите, что преобразования из строк 3 и 4 просто отменены (как отмена). Эти две линии в конце дают нам возможность постоянно видеть звезду лицом к зрителю. Но я не знаю, почему это работает.

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

Поэтому, когда я вызываю glTranslatef, я знаю, что текущая матрица представления умножается на значения перевода, предоставляемые glTranslatef. Другими словами "glTranslatef (0.0f, 0.0f, zoom);" переместил бы место, где я собираюсь нарисовать мои звезды на сцене, если масштаб будет отрицательным. OK.

но ЧТО именно здесь перемещается? Зритель перемещен "прочь" или есть какая-то система координат объекта, которая перемещается в сцену с помощью glTranslatef? Что здесь происходит?

Тогда glRotatef, что здесь вращается? Опять система координат, сам зритель?

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

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

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

Ответы [ 3 ]

4 голосов
/ 05 марта 2011

Еще один способ думать о стеке матриц gl - это подняться назад, от вашего вызова ничьей. В вашем случае, поскольку ваша ничья - последняя строка, давайте увеличим код:

1) Сначала звезда вращается на -40 градусов вокруг оси X относительно начала координат.

2) Звезда вращается на -star [loop] .angle вокруг оси Y относительно начала координат.

3) Звезда перемещается звездой [петля]. Направьте вниз по оси X.

4) Звезда вращается звездочкой [петля]. Вокруг оси Y относительно начала координат. Поскольку звезда больше не находится в начале координат из-за шага 3, это вращение перемещает центр звезды И вращает ее локально.

5) Звезда вращается путем наклона вокруг оси X относительно начала координат. (Примечание 4)

6) Звезда перемещается вниз по оси Z на единицы увеличения.

Трюк здесь сложно набрать в тексте, но попытайтесь представить последовательность ходов. Хотя шаги 2 и 4 могут показаться, что они инвертируют друг друга, перемещение между ними меняет характер вращения. Ключевая фраза в том, что повороты определены вокруг источника. Перемещение звезды меняет эффект вращения.

Это приводит к типичному использованию матриц стеков, когда вы хотите повернуть что-то на месте. Сначала вы перемещаете его в начало координат, затем поворачиваете его, затем вы перемещаете его назад. То, что у вас здесь есть, в значительной степени та же самая концепция.

Я считаю, что использование двух рук для визуализации матриц полезно. Держите одну руку, чтобы представить начало координат, а вторую (обычно правую, если вы находитесь в правой системе координат, такой как OpenGL), представляете объект. Я растягиваю пальцы, как оси XYZ, чтобы визуализировать вращение как локально, так и вокруг начала координат. Начиная с этого момента, последовательность вращений вокруг начала координат и линейных перемещений должна быть более легкой для изображения.

Второй вопрос, который вы задали, касается поведения матрицы камеры в типичной конфигурации OpenGL. Во-первых, понять концепцию координат экранного пространства (аналогично координатам устройства). Это пространство, которое на самом деле отображается. X и Y - векторы вашего экрана, а Z - глубина. Пространство обычно находится в диапазоне от -1 до 1. Перемещение объекта вниз по Z эффективно удаляет объект.

Камера (или матрица перспективы) обычно отвечает за преобразование пространства «Мир» в это пространство экрана. Эта матрица определяет «зрителя», но, в конце концов, это просто другая матрица. Матрица всегда применяется «последней», поэтому, если вы читаете преобразования вверх, как я уже описывал, камера обычно находится на самом верху, как вы видите. В этом случае вы могли бы думать о том последнем преобразовании (переводе с увеличением) как очень простая матрица камеры, которая перемещает камеру назад на единицы масштабирования.

Удачи. :)

1 голос
/ 05 марта 2011

На glTranslatef в середине влияет вращение: он перемещает звезду вдоль оси x на расстояние dist, а ось x в это время поворачивается на (угол наклона + угол) по сравнению с исходная ось х.

В opengl у вас есть координаты объекта, которые умножаются на (стек) матрицы проекций. Итак, вы двигаете объекты. Если вы хотите «переместить камеру», вы должны выполнить многократное преобразование по обратной матрице положения и оси камеры:

ProjectedCoords = CameraMatrix ^ -1. ObjectMatrix. ObjectCoord

0 голосов
/ 22 марта 2011

Я также нашел это очень запутанным, но я просто поиграл с некоторыми кодами NeHe, чтобы лучше понять glTranslatef () и glRotatef ().

В настоящее время я понимаю, что glRotatef () фактически вращает систему координат, так что glRotatef (90.0f, 0.0f, 0.0f, 1.0f) приведет к тому, что ось x окажется там, где была ось yранее.После этого вращения glTranslatef (1.0f, 0.0f, 0.0f) будет перемещать объект вверх по экрану.

Таким образом, glTranslatef () перемещает объекты в соответствии с текущим поворотом системы координат.Поэтому порядок glTranslatef и glRotatef важен в уроке 9.

С технической точки зрения моё описание может быть не идеальным, но оно работает для меня.

...