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

Я не хочу входить в сложную тригонометрию, чтобы вычислять вращения и подобные вещи для моего 3D-мира, поэтому 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.