# OpenGL gluLookat replacement

This topic is 2871 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Before I start, YES I have read lots of posts and code examples but I'm still stuck :-)

Here is my replacement code for gluLootat()

 void lsMatrix4x4::LookAt( const lsVector3& eyePosition, const lsVector3& lookAt, const lsVector3& upVector ) { lsMath math; lsVector3 e, l, u; lsVector3 forward, side, up; lsMatrix4x4 matrix2, mat2; e = eyePosition; l = lookAt; u = upVector; // make sure up is normalized up = upVector; up.normalize(); // forward vector forward = l - e; forward.normalize(); // side vector side = math.Cross( forward, up ); side.normalize(); // recalc up vector up = math.Cross( forward, side ); up.normalize(); matrix2.matrix[0] = side.x; matrix2.matrix[4] = side.y; matrix2.matrix[8] = side.z; matrix2.matrix[1] = up.x; matrix2.matrix[5] = up.y; matrix2.matrix[9] = up.z; matrix2.matrix[2] = -forward.x; matrix2.matrix[6] = -forward.y; matrix2.matrix[10] = -forward.z; mat2 *= matrix2; mat2.TranslateMatrix( -e.x, -e.y, -e.z ); *this = mat2; } 

And here is the output from both OpenGL and my engine.

 Camera Matrix : FPS_Camera Matrix : OpenGL -1 0 0 6.54721e-07 0 1 0 -1.76 0 0 -1 2.76058e-05 0 0 0 1 Matrix : vortxGE -1 0 0 -6.54721e-07 0 -1 0 -1.76 0 0 -1 -2.76058e-05 0 0 0 1 

I'm bashing my head against a wall, LOL.. It looks like a simple fix.

Any ideas anyone?

##### Share on other sites
And here's another example of a test app.

 cout << endl; cout << "*********************************************************" << endl; cout << "** Matrix Test " << endl; cout << "*********************************************************" << endl; lsMatrix4x4 mat; lsVector3 eye, look, up; GLfloat glmat[16]; lsOpenGL *ogl = vortxge->getCdl()->getOpengl(); // Identity // OpenGL glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glGetFloatv( GL_MODELVIEW_MATRIX, glmat ); ogl->DisplayMatrix4( glmat, "OpenGL: Identity" ); // vortxGE Matrix ogl->DisplayMatrix4( mat.matrix, "vortxGE: Identity" ); // LookAt // OpenGL glLoadIdentity(); gluLookAt( 0,0,-10.0, 0,0,0, 0,1,0 ); glGetFloatv( GL_MODELVIEW_MATRIX, glmat ); ogl->DisplayMatrix4( glmat, "OpenGL: LookAt" ); // vortxGE LookAt mat.LoadIdentity(); eye = lsVector3( 0, 0, -10.0 ); look = lsVector3( 0, 0, 0 ); up = lsVector3( 0, 1, 0 ); mat.LookAt( eye, look, up ); ogl->DisplayMatrix4( mat.matrix, "vortxGE: LookAt" ); 

And the output. I took the old SGI code as an example for LookAt.. hmmmmmmm.

 ********************************************************* ** Matrix Test ********************************************************* Matrix : OpenGL: Identity 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 Matrix : vortxGE: Identity 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 Matrix : OpenGL: LookAt -1 0 0 0 0 1 0 0 0 0 -1 -10 0 0 0 1 Matrix : vortxGE: LookAt -1 0 0 0 0 -1 0 0 0 0 -1 10 0 0 0 1 

##### Share on other sites
Could this be because the old SGI code was Left-Handed and now OpenGL is Righ-Handed ???? Help :-)

##### Share on other sites
This is my LookAt function. I think I started from the Mesa implementation originally. My matrix class is row-major so that's why everything is transposed from you. I have to pass transpose=true to glUniformMatrix4fv because of this.

 INLINE static void CreateLookAt(Vector3 const & position, Vector3 const & target, Vector3 const & upVector, Matrix & result) { Vector3 forward; Vector3::Subtract(target, position, forward); forward.Normalize(); Vector3 right; Vector3::Cross(forward, upVector, right); right.Normalize(); Vector3 up; Vector3::Cross(right, forward, up); up.Normalize(); result.elements[0] = right.X; result.elements[1] = right.Y; result.elements[2] = right.Z; result.elements[4] = up.X; result.elements[5] = up.Y; result.elements[6] = up.Z; result.elements[8] = -forward.X; result.elements[9] = -forward.Y; result.elements[10] = -forward.Z; result.elements[12] = 0.0f; result.elements[13] = 0.0f; result.elements[14] = 0.0f; result.elements[3] = -Vector3::Dot(right,position); result.elements[7] = -Vector3::Dot(up,position); result.elements[11] = Vector3::Dot(forward,position); result.elements[15] = 1.0f; } 

##### Share on other sites

This is my LookAt function. I think I started from the Mesa implementation originally. My matrix class is row-major so that's why everything is transposed from you. I have to pass transpose=true to glUniformMatrix4fv because of this.

 INLINE static void CreateLookAt(Vector3 const & position, Vector3 const & target, Vector3 const & upVector, Matrix & result) { Vector3 forward; Vector3::Subtract(target, position, forward); forward.Normalize(); Vector3 right; Vector3::Cross(forward, upVector, right); right.Normalize(); Vector3 up; Vector3::Cross(right, forward, up); up.Normalize(); result.elements[0] = right.X; result.elements[1] = right.Y; result.elements[2] = right.Z; result.elements[4] = up.X; result.elements[5] = up.Y; result.elements[6] = up.Z; result.elements[8] = -forward.X; result.elements[9] = -forward.Y; result.elements[10] = -forward.Z; result.elements[12] = 0.0f; result.elements[13] = 0.0f; result.elements[14] = 0.0f; result.elements[3] = -Vector3::Dot(right,position); result.elements[7] = -Vector3::Dot(up,position); result.elements[11] = Vector3::Dot(forward,position); result.elements[15] = 1.0f; } 

Thanks doesnotcompute

It might be easier using dot products then MultMatrix, thank you so much for your reply. I'll give it a try soon.

##### Share on other sites

 // recalc up vector up = math.Cross( forward, side ); 

It looks like you've reversed this cross product. forward x side will get you the down vector using the right-hand rule. Try doing side x forward and see if that fixes the issue.

##### Share on other sites
WOW !! I did so many things wrong with this it would be hard to explain how I fixed everything..

In short I had matrix calcs doubling up and rotation matrix mixed into my translation matrix. I must of had a brain fade during my rewrite.

All fixed now, thanks for your responces :-) P.S. ignore the code above its wring in so many ways. LOL.

##### Share on other sites

[quote name='Lee Stripp' timestamp='1325219444' post='4898045']
 // recalc up vector up = math.Cross( forward, side ); 

It looks like you've reversed this cross product. forward x side will get you the down vector using the right-hand rule. Try doing side x forward and see if that fixes the issue.
[/quote]

Yep, I was at that point where I was trying anything. Code got messy, I didn't need to recalc the Up vector :-)

##### Share on other sites
Update for anyone interested.

Here's my working code
 void lsMatrix4x4::LookAt( const lsVector3& eyePosition, const lsVector3& lookAt, const lsVector3& upVector ) { lsMath math; lsVector3 e, l, u; lsVector3 forward, side, up; lsMatrix4x4 rotmat, transmat; e = eyePosition; l = lookAt; u = upVector; // make sure up is normalized up = upVector; up.normalize(); up.debug( "up: " ); // forward vector forward = l - e; forward.normalize(); forward.debug( "forward: " ); // side vector side = math.Cross( forward, up ); side.normalize(); side.debug( "side: " ); rotmat.matrix[0] = side.x; rotmat.matrix[4] = side.y; rotmat.matrix[8] = side.z; rotmat.matrix[1] = up.x; rotmat.matrix[5] = up.y; rotmat.matrix[9] = up.z; rotmat.matrix[2] = -forward.x; rotmat.matrix[6] = -forward.y; rotmat.matrix[10] = -forward.z; transmat.TranslateMatrix( -e.x, -e.y, -e.z ); *this *= transmat * rotmat; } 

And the output it produces
 Matrix : lsNode: Camera [ 1 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 1 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 1 ] [ -10 ] [ 0 ] [ 0 ] [ 0 ] [ 1 ] up: Vector(0,1,0) forward: Vector(0,0,1) side: Vector(-1,0,0) Matrix : Camera ViewMatrix: [ -1 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 1 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ -1 ] [ 10 ] [ 0 ] [ 0 ] [ 0 ] [ 1 ] 

I hope this will help someone avoid the pain I went through :-)

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 21
• 12
• 18
• 25
• 20