GLProgramming.com

home :: about :: development guides :: irc :: forums :: search :: paste :: links :: contribute :: code dump

-> Click here to learn how to get live help <-



 
 

Development Guide Library


An Alternative to gluPerspective by Dranith

Motive

gluPerspective is a very very handy function for setting up the projection matrix. The only problem it has that I see is the FOV it takes is the FOV in the Y direction. So either you have no control over the FOV in the X direction, or you have the source to gluPerspective and you do some fancy trig to figure out the Y FOV value you need to input to get the desired X FOV.

Both these ways suck. So heres the code that lets you specify the FOV in the X direction. Code is based off the MESA implementation of gluPerspective.

Not to mention this is a point of confusion for people new to OpenGL. I didn't even notice that it took the Y FOV till a few days ago when I was doing something that I needed to be able to specify in X and things weren't working =).

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
void gldPerspective(GLdouble fovx, GLdouble aspect, GLdouble zNear, GLdouble zFar)
{
   // This code is based off the MESA source for gluPerspective
   // *NOTE* This assumes GL_PROJECTION is the current matrix

   
   GLdouble xmin, xmax, ymin, ymax;
   GLdouble m[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

   xmax = zNear * tan(fovx * M_PI / 360.0);
   xmin = -xmax;
   
   ymin = xmin / aspect;
   ymax = xmax / aspect;

   // Set up the projection matrix
   M(0,0) = (2.0 * zNear) / (xmax - xmin);
   M(1,1) = (2.0 * zNear) / (ymax - ymin);
   M(2,2) = -(zFar + zNear) / (zFar - zNear);

   M(0,2) = (xmax + xmin) / (xmax - xmin);
   M(1,2) = (ymax + ymin) / (ymax - ymin);
   M(3,2) = -1.0;

   M(2,3) = -(2.0 * zFar * zNear) / (zFar - zNear);
   
   // Add to current matrix
   glMultMatrixd(m);
}

Notes

Usage syntax is exactly the same as gluPerspective. This function assumes that GL_PROJECTION is the current matrix. This code is not optimised at all, but should only need to be called once.

--Dranith