PDA

View Full Version : How to choose between glOrtho/Perspective/Frustum?



jacksmash
12-11-2007, 07:44 AM
I'm sure each of these works well for different situations, but is there a rule of thumb for when to use which call? I understand what each of them does, but am unsure of (perhaps) what the standard is.

For example, if I'm making a 1st-person shooter, and the player is walking forward, does that mean his perspective is just changing (ie. gluPerspective), or is everything translated towards him? I would guess the first, but am having a hard time finding anything concrete on the subject.

Thanks.

Trenki
12-11-2007, 07:56 AM
glOrtho is typically used in CAD application or for 2D graphics, where this projection is useful.

glPerspective on the other hand create a perspective transformation where things further away will have a smaller projected area and thus look smaller. For a FPS you would use a perspective projection, but you don't have to change it all the time. When the player moves you would change the modelview matrix but leave the projection matrix as is.


[ www.trenki.net (http://www.trenki.net) | vector_math (3d math library) (http://www.trenki.net/content/view/16/36/) | software renderer (http://www.trenki.net/content/view/18/38/) ]

Relic
12-11-2007, 08:00 AM
First, glOrtho and glFrustum are core OpenGl calls. gluPerspective is a GL-Utility function generating a glFrustum call from a simpler description of field-of-view and aspect ratio values.

In a first person shooter you won't use glOrtho for the player's view. That would look totally unreal. But it's used for maps and onscreen head-up displays

For the perspective, you'll set this up for two cases only:
Once for the basic view of the player (field-of-view setting and screen aspect ratio) and whenever you would zoom-in to something like with a sniper scope.

Everything else needs to be done with the modelview matrix!

OpenGL has no notion of a "camera matrix" or world coordinate system.
The transformation after the modelview (i.e. model-to-view) coordinate transformation has been applied your eye is in the origin of that coordinate system (alas that's called eye-coordinate system).

To move your player forward you just transform the whole world in the opposite direction. Same for rotation of your player rotates to the left, just rotate the whole world to the right.

The only thing you need to consider for that is that the model- and eye-coordinates are right handed in OpenGL Moving the player forward means moving the world in +z-axis direction and so on...

k_szczech
12-11-2007, 08:08 AM
I understand what each of them does, but am unsure of (perhaps) what the standard is.

If you would really understand what these functions do you wouldn't be asking this question :)
And no, there is no "standard" here.

You use glOrtho when you want to render images without perspective.
You use glFrustum if you want perspective.

gluPerspective is just an utility function that calls glFrustum. It has different set of parameters so it's up to you which one you prefer.


As for moving observer in 3D space. First mistake made by many beginners is to keep player's position somewhere in the OpenGL matrices and use glTranslatef whenever someone presses movement key.
What you really need is player's position stored in some variable in your application and each frame prepare matrices for that position:


//rendering a scene:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(...);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(-cameraRoll, 0, 0, 1);
glRotatef(-cameraPitch, 1, 0, 0);
glRotatef(-cameraHeading, 0, 1, 0);
glTranslatef(-cameraPosition.x, -cameraPosition.y, -cameraPosition.z);

RenderWorld(); //static world

//repeat this for any movable object in the scene
glPushMatrix();
glTranslatef(objectPosision.x, objectPosision.y, objectPosision.z);
glRotatef(objectHeading, 0, 1, 0);
glRotatef(objectPitch, 1, 0, 0);
glRotatef(objectRoll, 0, 0, 1);
DrawObject(); //movable object
glPopMatrix();

jacksmash
12-11-2007, 10:28 AM
Thanks for all of your responses. Much appreciated.