gluLookAt implementation

Started by
5 comments, last by Miranda 19 years, 1 month ago
Hi, I am trying to implement a version of gluLookAt for Symbian Series 60 (OpenGL ES) and I can't seem to get it to work. The code I have is as follows (based on Mesa's code):

void lookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez,
	  GLfloat centerx, GLfloat centery, GLfloat centerz,
	  GLfloat upx, GLfloat upy, GLfloat upz)
{

   GLfloat m[16];
   GLfloat x[3], y[3], z[3];
   TReal mag;

   /* Make rotation matrix */

   /* Z vector */
   z[0] = eyex - centerx;
   z[1] = eyey - centery;
   z[2] = eyez - centerz;
   Math::Sqrt(mag, z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
   if (mag) {			/* mpichler, 19950515 */
      z[0] /= mag;
      z[1] /= mag;
      z[2] /= mag;
   }

   /* Y vector */
   y[0] = upx;
   y[1] = upy;
   y[2] = upz;

   /* X vector = Y cross Z */
   x[0] = y[1] * z[2] - y[2] * z[1];
   x[1] = -y[0] * z[2] + y[2] * z[0];
   x[2] = y[0] * z[1] - y[1] * z[0];

   /* Recompute Y = Z cross X */
   y[0] = z[1] * x[2] - z[2] * x[1];
   y[1] = -z[0] * x[2] + z[2] * x[0];
   y[2] = z[0] * x[1] - z[1] * x[0];

   /* mpichler, 19950515 */
   /* cross product gives area of parallelogram, which is < 1.0 for
    * non-perpendicular unit-length vectors; so normalize x, y here
    */

   Math::Sqrt(mag, x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
   if (mag) {
      x[0] /= mag;
      x[1] /= mag;
      x[2] /= mag;
   }

   Math::Sqrt(mag, y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
   if (mag) {
      y[0] /= mag;
      y[1] /= mag;
      y[2] /= mag;
   }

#define M(row,col)  m[col*4+row]
   M(0, 0) = x[0];
   M(0, 1) = x[1];
   M(0, 2) = x[2];
   M(0, 3) = 0.0;
   M(1, 0) = y[0];
   M(1, 1) = y[1];
   M(1, 2) = y[2];
   M(1, 3) = 0.0;
   M(2, 0) = z[0];
   M(2, 1) = z[1];
   M(2, 2) = z[2];
   M(2, 3) = 0.0;
   M(3, 0) = 0.0;
   M(3, 1) = 0.0;
   M(3, 2) = 0.0;
   M(3, 3) = 1.0;
#undef M
   glMultMatrixf(m);

   /* Translate Eye to Origin */
   glTranslatef(-eyex, -eyey, -eyez);

}
I have checked all my input parameters for when this method is used and they are all fine, but it just doesn't seem to do anything. I'm really stumped! I'm not sure if you can help me or not because it might be more of a Symbian specific question, but I have my fingers crossed anyway. Thanks, Miranda
Advertisement
Have you looked at how Mesa3D does it?
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
yeah, it's pretty much exactly the same. The only things I have really changed are the way Sin and Cos are calculated and the types of the parameters and some variables. That is why I don't know what's wrong, because it's so similar to Mesa's code.

sgi has opened the source code of "sample implemention" (google "ogl-sample"), which has the _origin_ sourc code of glulookat, you can have a look.

I just look the code roughly, ogl-sample makes forword vector differently:

z[0] = centerx - eyex;
z[1] = centery - eyey;
z[2] = centerz - eyez;

You can check ogl-sample's code for more details.

Hi,
yeah I noticed that as well when I was comparing my code to the explanation of gluLookAt provided by PyOpenGL .

But it seems that this is accounted for in the final matrix that is multiplied with the current matrix.

In the PyOpenGL specification the final matrix is:
M =	(	s[0]	s[1]	s[2]  0 		u[0]	u[1]	u[2]  0 		-f[0]	-f[1]	-f[2] 0 		0	0	0     1 	)

*note the -f

and mine is:
M =	(	x[0]	x[1]	x[2]  0 		y[0]	y[1]	y[2]  0 		z[0]	z[1]	z[2] 0 		0	0	0     1 	)

All these values are positive.

I reasoned that this makes up for the different (opposite) way that the z vector is calculated, but my Maths aren't that good so please tell me if I'm wrong here.

I tried changing these values and it still isn't doing anything. I suspected that this would be the case because I think that if it is just some wrong values, it would move the scene but it would be wrong, and my scene is not moving at all. [crying]

Thanks,
Miranda
Oh, yes, it is OK to calculate z (forward) vector such way, provided use it as positive late.

I just test your code - replaced Math::Sqrt with stdlib's sqrt - it works.

hmmm very odd. But thanks for that! I guess the problem must be elsewhere then...

This topic is closed to new replies.

Advertisement