Tutorial 17 :
Viewing Volume - Perspective & Orthographic

Tutorial Advanced Download Section

This tutorial is an introduction to the font tutorials (Tutorial 18 to 20). We will see how the orthographic projection is usefull for position an object to a desirate pixel, which is necessary for rendering font.

This kind of projection was use in some previous tutorials, without really talking about it. This will be done here.
 

The theory about viewing volume and projection matrix are explained in Lesson 1 & 2.

The projection that we have used in all previous tutorials is the Perspective projection. Objects drawn in this projection are affected by their distance from the view point. When an abject move away, it look smaller. This is due to the shape of the Viewing Volume, which is a pyramid truncated.

In the Orthographic projection, the Viewing Volume is a parallelepiped. Due to this, an object is not affected by their distance from the view point. The size of the object is independant of it position.
Another usefull difference is the coordinate system. The origin of the coordinate system is at the bottom left corner of the window (or more precisely of the viewport). The most interesting thing is the unit of X and Y axis : unit is in PIXELS. This means, if we want to draw something at the pixel (10, 10) from the bottom left, we just do the translation with glTranslate(10, 10, 0).
So, the bottom left corner of the viewport is (0, 0) and the top right corner is (viewportWidth, viewportHeight). This feature is really usefull to position a text, draw a GUI ...
 

As the switching from perspective to orthographic projection is a usefull, I put the code in the class ViewingTools (package tools).

You probably notice the use of this class in previous tutorials, it is detailled below.
 

To change the projection, we need to selection GL_PROJECTION with glMatrixMode. Then, we can select the orthographic projection. Also, don't forgot to reset the current matrix to identity.

Now that we are on our 2D projection mode, we go back to GL_MODELVIEW matrix mode. The modelview matrix is resetted to initialize the transformation to identity (ie default axis system).

Note: The projection and modelview matrix, associated to the 3D mode, are pushed for a later (when the switch back).
 

This method load projection and modelview matrix previously pushed. This is usefull to go back to the 3D mode.
 

 

ViewingTools class

public static float NEAR = -1;
public static float FAR = 1;

/**
 * Switch to orthographic projection<BR>
 * The current projection and modelview matrix are saved (push).<BR>
 * You can loads projection and modelview matrices with endOrtho
 * @see #endOrtho()
 */

public static void beginOrtho()
{
    final GLDrawable glDrawable = GLContext.getCurrent().getGLDrawable();
    final GL gl = GLContext.getCurrent().getGL();
   
    /*
     * We save the current projection matrix and we define a viewing volume
     * in the orthographic mode.
     * Projection matrix stack defines how the scene is projected to the screen.
     */

    gl.glMatrixMode(GL.GL_PROJECTION);   //select the Projection matrix
    gl.glPushMatrix();                   //save the current projection matrix
    gl.glLoadIdentity();                 //reset the current projection matrix to creates a new Orthographic projection
    //Creates a new orthographic viewing volume
    gl.glOrtho(0, glDrawable.getWidth(), 0, glDrawable.getHeight(), NEAR, FAR);
   
    /*
     * Select, save and reset the modelview matrix.
     * Modelview matrix stack store transformation like translation, rotation ...
     */

    gl.glMatrixMode(GL.GL_MODELVIEW);
    gl.glPushMatrix();
    gl.glLoadIdentity();
}

/**
 * Load projection and modelview matrices previously saved by the method beginOrtho
 * @see #beginOrtho()
 */

public static void loadMatrix()
{
    final GL gl = GLContext.getCurrent().getGL();
   
    //Select the Projection matrix stack
    gl.glMatrixMode(GL.GL_PROJECTION);
    //Load the previous Projection matrix (Generaly, it is a Perspective projection)
    gl.glPopMatrix();
   
    //Select the Modelview matrix stack
    gl.glMatrixMode(GL.GL_MODELVIEW);
    //Load the previous Modelview matrix
    gl.glPopMatrix();
}

 

To draw some objects into orthographic projection, you only need to put the code into the block switchToOrthoProjection/loadMatrix. The current projection is not affect by the drawing of all thing you want.

After loadMatrix, the current settings is exactly the same than before switchToOrthoProjection.

You can remarks that (30, 30) is the size in pixels of the two quads. Moreover, (20, glDrawable.getSize().height-45) is the (x, y) position of the object in pixels from the bottom left point.
 

Drawing

    /*
     * Draw into the 3D projection mode (perspective projection).
     * In this projection, the (0, 0) point is the center of the scene.
     */

    Drawer.drawVerticalRectCentered(gl, 1.5f, 1.5f);
   
    /*
     * Switch to 2D mode (orthographic projection) to draw some object at a known
     * location in pixels and a known size in pixels.
     *
     * The (0, 0) point is the BOTTOM-LEFT point. The position unit is in pixels,
     * so a size of (30, 30) means 30 pixels width and 30 pixels height.
     */

    ViewingTools.beginOrtho();
        SimpleShape.drawXYRectAt(30, 30,  20, glDrawable.getHeight()-45, 0);
        SimpleShape.drawXYRectAt(30, 30,  60, glDrawable.getHeight()-45, 0);
        SimpleShape.drawXYRectAt(30, 30, 100, glDrawable.getHeight()-45, 0);
    ViewingTools.endOrtho();

 

The orthographic projection will be used in next tutorials, and especially in Tutorial 20.
 

Remember to download the GraphicEngine-1.1.2 to run this tutorial !


If you've got any remarks on this tutorial, please let me know to improve it.
Thanks for your feedback.
 

Previous Tutorial

Back

Next turorial

Copyright © 2004-2012 Jérôme Jouvie - All rights reserved. http://jerome.jouvie.free.fr/