Java-Gaming.org
 Featured games (90) games approved by the League of Dukes Games in Showcase (555) games submitted by our members Games in WIP (476) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 LWJGL Tutorial Series - Perspective Projection  (Read 1615 times) 0 Members and 1 Guest are viewing this topic.
SHC
 « Posted 2013-09-14 11:14:01 »

# LWJGL Tutorial Series - Perspective Projection

Welcome to the tenth part of the LWJGL Tutorial Series. In the previous tutorial, I've showed you how to render a pyramid in Orthographic Projection. In this tutorial, let's learn how to create a Perspective Projection which gives more natural 3D effect. So let's get started and first learn what Perspective Projection is.

# Difference between Orthographic and Perspective projections

Why should we move to another type of projection? Our pyramid is rendering fine? The problem with Orthographic projection which we are using till now is that it uses the z-coordinate only to select which vertices should come first, that is even if an object has a large depth into the scene, it appears nearer. This is because the sizes of near and far planes being equal. This is how the orthographic looks like.

And this is how the Perspective projection looks like. The main difference is the size of the near plane which distinguishes the two types of projections.

Since the size of the near plane and far planes are equal in the Orthographic projection, it shows distant objects at the same depth of the nearer objects. To solve this problem, Perspective projection was invented. Since the size of the near plane is now smaller than the far plane, the distant objects now appear smaller than the nearer objects. Now that we have understood the difference between the two types of projections, let's now get into some code to change to perspective projection.

# Perspective Projection

Now that we have understood the working of the Perspective projection, let's now set the projection. There are two methods that can setup the perspective projection for us. One of them is the actual OpenGL function called
 `glFrustum()`
and the other is a utility method called
 `gluPerspective()`
which exists in
 `org.lwjgl.util.glu.GLU`
class. Personally I'm more comfortable with
 `gluPerspective()`
so that I'm going to use it for the example at the end but I'm going to explain both of the methods for you. At first let me explain the
 `gluPerspective()`
method.

# gluPerspective function

The
 `gluPerspective()`
is just a variation of the
 `glFrustum()`
function and it takes an angle in degrees called 'Field Of View' and takes aspect ratio of the window size to setup the coordinate axis. This is the syntax of it.

 1  2  3  4  5  6  7  8  9  10  11  12  13  14 `/** * gluPerspective specifies a viewing frustum into the world coordinate system. * In general, the aspect ratio in gluPerspective should match the aspect ratio * of the associated viewport. For example, aspect = 2.0 means the viewer's * angle of view is twice as wide in x as it is in y. If the viewport is twice as wide * as it is tall, it displays the image without distortion. * * @param fovy   Specifies the field of view angle, in degrees, in the y direction. * @param aspect Specifies the aspect ratio that determines the field of view in the x *                direction. The aspect ratio is the ratio of x (width) to y (height). * @param zNear  Specifies the distance from the viewer to the near clipping plane. * @param zFar   Specifies the distance from the viewer to the far clipping plane. */void gluPerspective(float fovy, float aspect, float zNear, float zFar);`

You may confuse what is field of view. So here is a visual defining the angle.

This means if you draw two lines from the eye to the top and bottom of the near plane, then the angle between those two lines is called the field of view. There is no perfect value for this but the actual angle in the real world lies around 70 degrees. You can change it to change the area of the scene which can be viewed. Then the aspect ratio is nothing but the quotient of the division of screen width by the screen height. There is no need to define
 `zNear`
and
 `zFar`
since these are already explained in the previous tutorial. So to change to the perspective projection using
 `gluPerspective()`
function, we use

 1  2  3  4  5 `glMatrixMode(GL_PROJECTION);gluPerspective(70f, 800f / 600f, 1, 1000);glMatrixMode(GL_MODELVIEW);glLoadIdentity();`

This creates a perspective projection with the camera at the origin. So if you are having problems viewing your model, you'll have to translate it further into the screen to view it perfectly. Now let me explain the
 `glFrustum()`
function to create the perspective projection.

# glFrustum function

Now let use see how to create a perspective projection using the
 `glFrustum()`

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15 `/** * glFrustum describes a perspective matrix that produces a perspective projection. * The current matrix is multiplied by this matrix and the result replaces the current * matrix. * * @param left   The left most coordinate on the x-axis. * @param right  The right most coordinate on the x-axis. * @param bottom The bottom most coordinate on the y-axis. * @param top    The top most coordinate on the y-axis. * @param zNear  The distances to the near-depth clipping plane. Must be positive. * @param zFar   The distances to the far-depth clipping planes. Must be positive. */void glFrustum(double left, double right,               double bottom, double top,               double zNear, double zFar);`

If you are confused what are the values, the values are clearly defined in this visual.

There is nothing to explain this function since it's so similar to the
 `glOrtho()`
function we used till now. So I'm going to just show you the code which sets up perspective projection by taking the values we passed till now to the
 `glOrtho()`
function.

 1  2 `glMatrixMode(GL_PROJECTION);glFrustum(-1, 1, -1, 1, 1, 1000);`

The drawback is that you have to calculate the coordinates for the aspect ratio of the window.  So for future tutorials, we'll be using
 `gluPerspective()`
function. That's the end of this concept and in the next part, I'll show you a demo using this which creates a rotating cube using triangles.

If there are any corrections or improvements that needs to be made, please notify them to me using comments.

# Source Code

There is no source code associated with this tutorial since this tutorial intended to cover some concepts we will be using in the next part of the tutorial.

quew8

JGO Coder

Medals: 23

 « Reply #1 - Posted 2013-09-14 13:23:50 »

Um, glFrustum() can't have a negative farValue, I'm sure that was just an innocent mistake but best to change it.
SHC
 « Reply #2 - Posted 2013-09-14 13:33:10 »

@quew8 That's right! Just a typo.

SHC
 « Reply #3 - Posted 2013-09-14 19:18:54 »

@quew8

Do you know how can we set the display to the aspect ratio in glFrustum? I'm switching to gluPerspective since it seems easy now.

quew8

JGO Coder

Medals: 23

 « Reply #4 - Posted 2013-09-14 19:29:18 »

You can change the aspect ratio exactly as you would with an orthographic projection. So if you have an x/y aspect ratio of a, then your above projection could be modified as follows:

 1 `gFrustum(-1, 1, -a, a, 1, 100);`
Pages: [1]
 ignore  |  Print

 Add your game by posting it in the WIP section, or publish it in Showcase. The first screenshot will be displayed as a thumbnail.
 Rayvolution (18 views) 2014-03-13 00:02:00 The Lion King (43 views) 2014-03-11 04:35:53 Screem (63 views) 2014-03-08 05:04:17 Screem (66 views) 2014-03-08 05:01:59 Gibbo3771 (76 views) 2014-03-05 15:13:19 Conzar (78 views) 2014-03-05 09:59:23 Conzar (76 views) 2014-03-05 09:57:20 GamerIDGoesHere (109 views) 2014-03-02 10:31:15 GamerIDGoesHere (95 views) 2014-03-02 10:30:27 GamerIDGoesHere (93 views) 2014-03-02 10:29:54
 opiop65 30x kpars 26x HeroesGraveDev 20x BurntPizza 20x Rayvolution 20x jonjava 17x Grunnt 17x saucymeatman 15x theagentd 14x revers 13x reymantha 13x Riven 12x Gibbo3771 11x LiquidNitrogen 11x Troubleshoots 10x princec 9x
 Anonymous/Local/Inner class gotchasby Roquen2014-03-11 15:22:30Anonymous/Local/Inner class gotchasby Roquen2014-03-11 15:05:20Anonymous/Local/Inner class gotchasby Roquen2014-03-10 14:19:36HotSpot Optionsby Roquen2014-02-26 17:00:23HotSpot Optionsby Roquen2014-02-26 11:27:03HotSpot Optionsby Dxu19942014-02-18 01:05:35HotSpot Options2014-02-16 03:47:31Mainby Roquen2014-02-10 11:17:06
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org