Perspective projection matrices

From the “OpenGL Reference Manual” & gluPerspective manual page, I can find the algorithm for calculating perspective projection matrix.

When I calculate this projection matrix of my own in my program, I however get a different kind of projection than by using gluPerspective, eventhought I’m using the same algorithm that this function is supposedly using.

I wonder why?

Maybe you’re storing the matrix in row-major format while the OpenGL matrix calls require column-major matrices. Try using glLoadTransposeMatrix instead of glLoadMatrix.


No, this is not the problem. The projection is valid, but it seems like it has different field of view or something. Objects appear larger and closer to the camera than by using gluPerspective.

What formula are you using? Maybe you forgot to convert from degrees to radians or vice versa?


Well yes, I did forget to convert from degrees to radians but it didn’t help.

Here is a code snipset from my program:


#define DEG2RAD(x) ((x) * 0.0174532925f)
#define M_PI_2 6.28318531f

float fieldOfView = 60.0f;
float aspectRatio = 800.0f / 600.0f;
float nearPlane = 1.0f;
float farPlane = 1000.0f;

float f = tanf( M_PI_2 - DEG2RAD( fieldOfView ) * 0.5f );

GLfloat mat[16];
mat[0] = f / aspectRatio;
mat[1] = 0.0f;
mat[2] = 0.0f;
mat[3] = 0.0f;
mat[4] = 0.0f;
mat[5] = f;
mat[6] = 0.0f;
mat[7] = 0.0f;
mat[8] = 0.0f;
mat[9] = 0.0f;
mat[10] = ( farPlane + nearPlane ) / ( nearPlane - farPlane );
mat[11] = -1.0f;
mat[12] = 0.0f;
mat[13] = 0.0f;
mat[14] = ( 2.0f * farPlane * nearPlane ) / ( nearPlane - farPlane );
mat[15] = 0.0f;

glMatrixMode( GL_PROJECTION );
glLoadMatrixf( mat );
//gluPerspective( 60.0f, 800.0f / 600.0f, 1.0f, 1000.0f );

glMatrixMode( GL_MODELVIEW );
glTranslatef( 0.0f, 0.0f, -10.0f );

glBegin( GL_LINES );
glColor3f( 0.0f, 1.0f, 1.0f );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 1.0f, 0.0f, 0.0f );
glColor3f( 1.0f, 0.0f, 1.0f );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 0.0f, 1.0f, 0.0f );
glColor3f( 1.0f, 1.0f, 0.0f );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 0.0f, 0.0f, 1.0f );

The matrix formula was taken from “OpenGL Reference Manual” 3rd edition.

Here is a screenshot if I use gluPerspective instead of my own matrix.

Here is a screenshot when I use my own matrix without DEG2RAD.

And here is a screenshot when I use DEG2RAD.

Any ideas?

I got it working now by replacing

float f = tanf( M_PI_2 - DEG2RAD( fieldOfView ) * 0.5f );


float f = 1.0f / tanf( DEG2RAD( fieldOfView ) * 0.5f );

Thanks and sorry for the trouble.

Indeed, you should have used the cotangent which is the reciprocal of the tangent. If I were you, I’d remove the #define M_PI_2 6.28318531f because M_PI_2 is already defined in math.h as half of Pi instead of twice Pi.


Actually, my algorithm was correct all the time, since:

cotangent(x) = 1 / tan(x) = tan(pi/2 - x)

What was incorrect was the value of M_PI_2. I had misunderstood that it was pi * 2. M_PI_2 is not defined in my system’s math.h (I’m using Visual Studio 2008).


Can you tell me a formula to calculate perspective projection matrix inverse? It was not given in the Reference manual. I need this in order to project coordinates back and forth between object space and window space.


Matrix Inverse

Or just use gluProject/gluUnProject.


Yes, thats one way to solve generic inverse matrix but there is optimal solution which takes into consideration the nature of perspective projections. I will dwelve into projection matrix theory and see what comes up.