# gluLookAt() problems

Discussion in 'Mac Programming' started by Buschmaster, Dec 20, 2008.

1. ### Buschmaster macrumors 65816

Joined:
Feb 12, 2006
Location:
Minnesota
#1
I'm just trying to learn how to implement gluLookAt() in a basic way and I was hoping that this would work for moving my object into the middle of the view from the origin:
Code:
-(void) moveIt {
glMatrixMode(GL_MODELVIEW);
gluLookAt(0.0, 0.0, 0.0, myObject.currentPosition.x, myObject.currentPosition.y, myObject.currentPosition.z, 0.0, 1.0, 0.0);
}

But it doesn't... I know this is being called, but the camera's view is not moved to the current position of the object. Anyone able to help me out here with the basics of gluLookAt()?

My understanding was that this would make it so the object was in the middle of the view looking at it from the origin.

2. ### lazydog macrumors 6502a

Joined:
Sep 3, 2005
Location:
Cramlington, UK
#2
Hi

It might be that your object is too near to the camera and is being clipped by the near plane. However I think the main problem is the 'up vector'. You're aligning it with the y-axis which is not what you want (unless your object lies in the x-z plane). The camera up-vector needs to be orthogonal to the line of sight which in your case would be 90 degrees to the vector

Code:
( myObject.currentPosition.x, myObject.currentPosition.y, myObject.currentPosition.z )
Calculating the up-vector can be difficult. As a quick check try placing the camera at the same height as the object, that way ( 0, 1, 0 ) will be a valid up-vector.

Code:
gluLookAt(0.0, myObject.currentPosition.y, 0.0, myObject.currentPosition.x, myObject.currentPosition.y, myObject.currentPosition.z, 0.0, 1.0, 0.0);
}

b e n

3. ### ncl macrumors member

Joined:
Aug 16, 2008
#3
Indeed, it should. As lazydog said, make sure the object is not too close to the near or far planes. Also, are you sure you projection matrix is setup correctly ?

Actually, it is not necessary. According to the man page (Apple), gluLookAt builds an orthogonal basis from the 3 parameters. In summary, for the 3 basis vector v1, v2, v3, it takes v1=(center-eye), v2 = (v1 x up) and v3 = (v1 x v2) (where x is the cross product and all vectors are normalized). The only requirement is that (center-eye) and up cannot be parallel.

4. ### lazydog macrumors 6502a

Joined:
Sep 3, 2005
Location:
Cramlington, UK
#4
That's useful to know, thanks!

b e n

5. ### Buschmaster thread starter macrumors 65816

Joined:
Feb 12, 2006
Location:
Minnesota
#5
The only problem is that the camera doesn't move at all when this code is called so I don't think it's the parameters. Am I missing something altogether like a push and pop matrix? I'm still fairly new to OpenGL so I'm not the most competent at how everything flows yet.

Also, the currentPosition of the object is {0.0, -0.3, -4.0}

I purposefully offset it from the center hoping that when my method is called it would snap to the center. gluLookAt() doesn't create a new origin, does it?

6. ### ncl macrumors member

Joined:
Aug 16, 2008
#6
By "the camera doesn't move at all", do you mean you can see the object, but it's not centered ? If that's the case, are you sure you call gluLookAt() before drawing the object ?

7. ### Buschmaster thread starter macrumors 65816

Joined:
Feb 12, 2006
Location:
Minnesota
#7
I can see the object before and after the gluLookAt() is called and it is in the same position.

My object is being drawn time after time so I know it's being done before the object is being drawn. Will this get in the way if it's being drawn all the time?

8. ### lazydog macrumors 6502a

Joined:
Sep 3, 2005
Location:
Cramlington, UK
#8
I'm not sure I understand what your problem is exactly.

On each frame are you drawing the object first, performing a gluLookAt(), and then drawing the object again()? Perhaps you could post some more code?

b e n

9. ### Buschmaster thread starter macrumors 65816

Joined:
Feb 12, 2006
Location:
Minnesota
#9
Yes, my drawSelf is basically being called all the time. Perhaps I should re-write this a bit differently?

So what's happening is..

The view is setup

The view is drawn (over and over)
The gluLookAt() is called
The view is drawn (over and over)

Here's my drawSelf:
Code:
- (void)drawSelf
{
// Save the current transformation by pushing it on the stack
glPushMatrix();

// Load the identity matrix to restore to origin

// Translate to the current position
glTranslatef(currentPosition.x, currentPosition.y, currentPosition.z);

// Rotate to the current rotation
glRotatef(currentRotation.x, 1.0, 0.0, 0.0);
glRotatef(currentRotation.y, 0.0, 1.0, 0.0);
glRotatef(currentPosition.z, 0.0, 0.0, 1.0);

// Enable and load the vertex array
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
glEnable(GL_NORMALIZE);

// Loop through faces and draw them
for (int i = 0; i < numberOfFaces; i++)
{
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, &faces[i]);
}

glDisableClientState(GL_VERTEX_ARRAY);

glMatrixMode(GL_MODELVIEW);

// Restore the current transformation by popping it off
glPopMatrix();

}

Which is being called all the time because this is getting called:
Code:
- (void)drawView:(GLView*)view;
{
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(0.0, 0.5, 1.0, 1.0);
[myObject drawSelf];
Vertex3D newPosition;
newPosition.x = myObject.currentPosition.x;
newPosition.z = myObject.currentPosition.z;
newPosition.y = myObject.currentPosition.y - 0.001;
myObject.currentPosition = newPosition;
}
That's just to make it so it looks like it's falling down.

10. ### ncl macrumors member

Joined:
Aug 16, 2008
#10
You don't call gluLookAt anywhere in that code. You have to call gluLookAt each time the frame is drawn. It should look like this
Code:
glMatrixMode(GL_MODELVIEW);
gluLookAt(...)
drawObject();
...

The reason is that gluLookAt modifies the current matrix. But each time your drawView is called, you reset it with glLoadIdentity().

11. ### Buschmaster thread starter macrumors 65816

Joined:
Feb 12, 2006
Location:
Minnesota
#11
Oh! Makes sense and it's working perfectly now! Thanks everyone!

Edit: Wait... no it's not. Here's my new code:
Code:
- (void)drawView:(GLView*)view;
{
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(0.0, 0.5, 1.0, 1.0);
Vertex3D newPosition;
newPosition.x = monkeyFace.currentPosition.x;
newPosition.z = monkeyFace.currentPosition.z;
newPosition.y = monkeyFace.currentPosition.y - 0.001;
monkeyFace.currentPosition = newPosition;
gluLookAt(0.0, 1.0, 0.0, monkeyFace.currentPosition.x, monkeyFace.currentPosition.y, monkeyFace.currentPosition.z, 0.0, 1.0, 0.0);
[monkeyFace drawSelf];
}

12. ### ncl macrumors member

Joined:
Aug 16, 2008
#12
If the -drawSelf method used here is the same as the one you previously posted, it begins with a glLoadIdentity() that resets the modelview matrix. You should remove it.
Also, you probably don't need the translation: gluLookAt() does it for you.

13. ### lazydog macrumors 6502a

Joined:
Sep 3, 2005
Location:
Cramlington, UK
#13
Yup, you definitely want to get rid of the glLoadIdenty() in drawSelf(). Also you don't need the glMatrixMode(GL_MODELVIEW); glLoadIdentity(); pair at the end.

b e n

Edit: I think you still need your translation, otherwise the object will be drawn at the origin instead of currentPosition.

14. ### ncl macrumors member

Joined:
Aug 16, 2008
#14
Indeed
I don't know why I thought it wasn't necessary...

15. ### Buschmaster thread starter macrumors 65816

Joined:
Feb 12, 2006
Location:
Minnesota
#15
Awesome, now it's working as it should be for sure.