Как правильно использовать gluLookAt?

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

Это совсем не так. У меня есть немного кода Python. Это код, который инициализирует некоторые данные и код режима, когда я вхожу в эту часть игры:

def init(self):
    self.game_over = False
    self.z = -30
    self.x = 0
def transfer(self):
    #Make OpenGL use 3D
    game.engage_3d(45,0.1,100)
    gluLookAt(0,0,-30,0,0,0,0,1,0)

"game.engage_3d (45,0.1,100)" в основном устанавливает матрицу проекции, чтобы иметь угол обзора 45 градусов и ближние и дальние координаты 0,1 и 100.

Первый gluLookAt ставит камеру в правильное положение, приятно.

У меня есть куб, нарисованный с центром (0,0,0), и он прекрасно работает без gluLookAt. Прежде чем нарисовать его, у меня есть этот код:

gluLookAt(self.x,0,self.z,0,0,0,0,1,0)
if game.key(KEY_UP):
    self.z += 2.0/game.get_fps()
if game.key(KEY_DOWN):
    self.z -= 2.0/game.get_fps()
if game.key(KEY_LEFT):
    self.x += 2.0/game.get_fps()
if game.key(KEY_RIGHT):
    self.x -= 2.0/game.get_fps()

Исходя из этого, верхнее положение всегда должно быть таким же, как всегда под прямым углом. То, что я думал, что это будет делать, это двигаться вперед и назад по оси z с помощью клавиш вверх и вниз, а влево и вправо через ось x с помощью клавиш слева и справа. Что на самом деле происходит, когда я использую левую и правую клавиши, куб будет вращаться вокруг "глаза", ускоряемого клавишами. Клавиша вверх заставляет другой куб из ниоткуда прорезать экран и ударить первый куб. Клавиша "вниз" возвращает загадочный клонированный куб обратно. Это может быть объединено с ротацией, чтобы дать совершенно другой результат, поскольку указанная документация возникнет.

Что на земле не так?

Спасибо.

1 ответ

Решение

(Интуиция за вектором "вверх" в gluLookAt проста: посмотрите на что угодно. Теперь наклоните голову на 90 градусов. Там, где вы находитесь, не изменилось, направление, на которое вы смотрите, не изменилось, но изображение на вашем Сетчатка явно имеет. Какая разница? Куда указывает верхняя часть вашей головы. Это восходящий вектор.)

Но чтобы ответить на ваш вопрос: вызовы gluLookAt не должны объединяться. Другими словами, единственный шаблон, в котором можно использовать gluLookAt, если вы точно не знаете, как он работает, это следующее:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
# do not touch the modelview matrix anymore!

Из вашего кода видно, что вы делаете что-то вроде этого:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
# some stuff..
gluLookAt(...);

Это приведет к странным результатам, потому что gluLookAt умножает текущую матрицу на матрицу просмотра, которую он вычисляет. Если вы хотите объединить преобразования, вам действительно лучше понять, как заставить glTranslate, glScale и glRotatef работать на вас. Более того, вы должны узнать, как работают преобразования координат, и придерживаться glMultMatrix.

Другие вопросы по тегам