GluLookAt code

From OpenGL Wiki
Jump to navigation Jump to search

GLU - the OpenGL Utility library is an additional library that contains a handful of functions for additional tasks.
It is traditional and can be found in a lot of tutorials and examples. But GLU uses a lot of OpenGL features that are deprecated now.
The internal modelview matrix should not be used anymore, so the programmer should use a replacement for gluLookAt, that instead of updating the internal modelview matrix will return this matrix.
gluLookAt's source code is very simple and can be replaced easily.
The code here comes from glh library (OpenGL Helper Library), LGPL license https://sourceforge.net/projects/glhlib


This function computes a matrix and multiplies it with whatever is in *matrix.
eyePosition3D is a XYZ position. This is where you are (your eye is).
center3D is the XYZ position where you want to look at.
upVector3D is a XYZ normalized vector. Quite often 0.0, 1.0, 0.0

The code presented here is slightly modified (but functional and correct) from the one in glhlib.

void glhLookAtf2( float *matrix, float *eyePosition3D,
                  float *center3D, float *upVector3D )
{
   float forward[3], side[3], up[3];
   float matrix2[16], resultMatrix[16];
   // --------------------
   forward[0] = center3D[0] - eyePosition3D[0];
   forward[1] = center3D[1] - eyePosition3D[1];
   forward[2] = center3D[2] - eyePosition3D[2];
   NormalizeVector(forward);
   // --------------------
   // Side = forward x up
   ComputeNormalOfPlane(side, forward, upVector3D);
   NormalizeVector(side);
   --------------------
   // Recompute up as: up = side x forward
   ComputeNormalOfPlane(up, side, forward);
   // --------------------
   matrix2[0] = side[0];
   matrix2[4] = side[1];
   matrix2[8] = side[2];
   matrix2[12] = 0.0;
   // --------------------
   matrix2[1] = up[0];
   matrix2[5] = up[1];
   matrix2[9] = up[2];
   matrix2[13] = 0.0;
   // --------------------
   matrix2[2] = -forward[0];
   matrix2[6] = -forward[1];
   matrix2[10] = -forward[2];
   matrix2[14] = 0.0;
   // --------------------
   matrix2[3] = matrix2[7] = matrix2[11] = 0.0;
   matrix2[15] = 1.0;
   // --------------------
   MultiplyMatrices4by4OpenGL_FLOAT(resultMatrix, matrix, matrix2);
   glhTranslatef2(resultMatrix,
                  -eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]);
   // --------------------
   memcpy(matrix, resultMatrix, 16*sizeof(float));
}

The matrix you get can be uploaded with a call to glLoadMatrixf(matrix) or if you are using shaders, use glUniformMatrix4fv(location, 1, GL_FALSE, matrix).