View Full Version : gluLookAt() problems
Buschmaster
Dec 21, 2008, 12:29 AM
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:
-(void) moveIt {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
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.
lazydog
Dec 21, 2008, 04:48 AM
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
( 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.
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
ncl
Dec 21, 2008, 05:43 AM
My understanding was that this would make it so the object was in the middle of the view looking at it from the origin.
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 ?
The camera up-vector needs to be orthogonal to the line of sight which in your case would be 90 degrees to the vector
Actually, it is not necessary. According to the man page (http://developer.apple.com/DOCUMENTATION/Darwin/Reference/ManPages/man3/gluLookAt.3.html) (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.
lazydog
Dec 21, 2008, 05:58 AM
Actually, it is not necessary. According to the man page (http://developer.apple.com/DOCUMENTATION/Darwin/Reference/ManPages/man3/gluLookAt.3.html) (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.
That's useful to know, thanks!
b e n
Buschmaster
Dec 21, 2008, 08:36 AM
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?
ncl
Dec 21, 2008, 10:27 AM
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.
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 ?
Buschmaster
Dec 21, 2008, 12:06 PM
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?
lazydog
Dec 21, 2008, 12:30 PM
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
Buschmaster
Dec 21, 2008, 10:31 PM
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
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:
- (void)drawSelf
{
// Save the current transformation by pushing it on the stack
glPushMatrix();
// Load the identity matrix to restore to origin
glLoadIdentity();
// 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);
glLoadIdentity();
// Restore the current transformation by popping it off
glPopMatrix();
}
Which is being called all the time because this is getting called:
- (void)drawView:(GLView*)view;
{
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
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.
ncl
Dec 22, 2008, 04:53 AM
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
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...)
drawObject();
...
The reason is that gluLookAt modifies the current matrix. But each time your drawView is called, you reset it with glLoadIdentity().
Buschmaster
Dec 22, 2008, 06:09 AM
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
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...)
drawObject();
...
The reason is that gluLookAt modifies the current matrix. But each time your drawView is called, you reset it with glLoadIdentity().
Oh! Makes sense and it's working perfectly now! Thanks everyone! :)
Edit: Wait... no it's not. Here's my new code:
- (void)drawView:(GLView*)view;
{
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
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];
}
ncl
Dec 22, 2008, 08:08 AM
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.
lazydog
Dec 22, 2008, 08:26 AM
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.
ncl
Dec 22, 2008, 09:00 AM
Edit: I think you still need your translation, otherwise the object will be drawn at the origin instead of currentPosition.
Indeed :o
I don't know why I thought it wasn't necessary...
Buschmaster
Dec 22, 2008, 01:41 PM
Awesome, now it's working as it should be for sure. ;)
vBulletin® v3.8.6, Copyright ©2000-2012, Jelsoft Enterprises Ltd.