Как правильно использовать gluLookAt? - PullRequest
15 голосов
/ 01 августа 2010

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

У меня нарисован куб с центромof (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 Ответ

38 голосов
/ 01 августа 2010

(Интуиция позади вектора «вверх» в 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.

...