PDA

View Full Version : Simple Explanation of Projection Transformation



openujs
09-16-2005, 07:30 PM
I have noticed many newbies to OPENGL are struggling to understand Projection. I am a beginner myself. I also struggled to understand GL_PROJECTION concept. I wrote a small program that only
rendered a small triangle. For few days, I could not render anything. After researching and playing with the coordinates and matrices, finally I could render. I really think that there is hardly any resource that does a good job explaining this concept without making things complicated. So I am going to share what I understood, hoping to help those who are confused with projection.

I will try to explain with an example - my triangle program. First of all, Projection transformation is basically an attempt to convert the object coordinates into a viewing volume called frustum. This volume is conical instead of orthographic so that it bring out the concept of near and far in 3D world. As the object is far away from viewer, it tends to get smaller.

x,y,z axis sits in the center of monitor, x is positive on right, y is positive on top and z is positive towards you. So the coordinates where x, y and z axis intersect are 0,0 and 0. My understanding is 0,0,0 can be moved from center of screen to elsewhere by using GluLookat function.

Lets look at my triangle program.
// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Set drawing color to black
glColor3f( 0.0,0.0, 0.0 );
glBegin( GL_TRIANGLES );
glVertex3f(0.0f, 0.0f, 60.0f);
glVertex3f(-15.0f, 0.0f, 30.0f);
glVertex3f(15.0f,10.0f,30.0f);
glEnd();
glFlush();
glutSwapBuffers();
}

// Setup the rendering state
void SetupRC(void)
{
// Set clear color to white
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}
void ChangeSize(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0, 1024.0/768.0, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -71.0f);
}

// Main program entry point
void main(void)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("Test");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();
}

In the program, I am setting viewport using glViewport(). Then I am setting Matrix Mode to Projection using glMatrixMode( GL_PROJECTION) and setting identity matrix glLoadIdentity(), These are pretty standard functions.
After that I am using gluPerspective(90.0, 1024.0/768.0, 1.0, 100.0);
90.0 is just a viewing angle in y plane ( fovy), 90 degree is pretty much standard.
then aspect viewing screen width/length.
After that 1.0 is near value, which is the distance between viewer and near plane, 100.0 is the distance between viewer and far plane. That means whatever you draw you should draw with width less than 99 (pixels i guess). And also the object is better be inside this frustum just created using gluPerspective(). now lets look at RenderScene function. Oh yes, after calling gluPerspective(), you have to set matrix mode to MODEL VIEW and reset the matrix by calling glLoadIdentity().
In RenderScene() I am drawing a triangle, with coordinates (0,0,60), (-15,0,30) and (15,10,30).
Now Remember I created frustum using near =1 and far = 100, that means the frustrum starts from 1 unit away from 0,0,0 ( negative z = -1 ) to 100 ( z = -100).
However, if you look at the triangle, the point A has coordinates of (0,0,60), z axis of positive 60. That means the triangle is outside the furstum. So it WILL NOT render. So what you have to do in order to draw is - call glTranslatef( 0.0,0.0, -71.0), what this function does is- it pushes our object towards certain axis. I have -71.0 for z-axis, that means I am pushing the triangle back to negative z axis, so that the triangle falls in frustum and will render.

dorbie
09-16-2005, 09:04 PM
Cool, if you want to do this seriously I encourage you to get yourself a web site and start posting tutorials there, they will have a more permanent record :)

If you post articles the webmaster will link to your site on the front page.

In the mean time it is worth reviewing some of the excellent interractive tutorials Nate Robins wrote and posted online I think he even covers transformation and projection although he omitted some of your detail on loading identity etc.;

http://www.xmission.com/~nate/tutors.html

Have fun and let us know what you create.