How do I use gluLookAt properly?

22,744

(The intuition behind the "up" vector in gluLookAt is simple: Look at anything. Now tilt your head 90 degrees. Where you are hasn't changed, the direction you're looking at hasn't changed, but the image in your retina clearly has. What's the difference? Where the top of your head is pointing to. That's the up vector.)

But to answer your question: gluLookAt calls should not be concatenated. In other words, the only pattern in which it's OK to use gluLookAt if you don't know exactly how it works is the following:

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

It seems from your code that you're doing something like this:

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

This will generate weird results, because gluLookAt multiplies the current matrix by the viewing matrix it computes. If you want to concatenate transformations you're really better off figuring out how to make glTranslate, glScale and glRotatef work for you. Even better, you should learn how the coordinate transformations work and stick to glMultMatrix.

Share:
22,744
Matthew Mitchell
Author by

Matthew Mitchell

Developer of iOS and Android Apps. Developer of the cbitcoin library: http://cbitcoin.com.

Updated on August 01, 2020

Comments

  • Matthew Mitchell
    Matthew Mitchell almost 4 years

    I don't want to get into complex trigonometry to calculate rotations and things like that for my 3D world so gluLookAt seems like a nice alternative. According to the documentation all I need to do is place 3 coordinates for the cameras position, three for what I should be looking at and an "up" position. The last made no sense until I assumed it had to be at right angles with the line of sight in the direction the top of the screen should be.

    It doesn't work like that at all. I have some python code. This is the code which initialises some data and some mode code for when I enter this part of the game:

    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)" basically sets up the projection matrix to have a 45 degree angle of view and near and far coordinates of 0.1 and 100.

    The first gluLookAt puts the camera in the correct position, nicely.

    I have a cube drawn with the centre of (0,0,0) and it works fine without gluLookAt. Before I draw it I have this code:

    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()
    

    Now from that, the up position should always be the same as it's always at right angles. What I'd have thought it would do is move forward and back the z-axis with the up and down keys and left and right through the x-axis with the left and right keys. What actually happens, is when I use the left and right keys, the cube will rotate around the "eye" being accelerated by the keys. The up key causes another cube from nowhere to slice through the screen and hit the first cube. THe down key brings the mysterious cloned cube back. This can be combined with the rotation to give a completely different outcome as the documentation said would arise.

    What on earth is wrong?

    Thank you.