The Allegro Wiki is migrating to github at https://github.com/liballeg/allegro_wiki/wiki

3D using OpenGL

From Allegro Wiki
Jump to: navigation, search
Creating 3D graphics via OpenGL and allegro 5 is fairly simple . Here's a short guide for the basic setup.

Initializations for allegro

First of all declare an allegro display and initialize allegro:

ALLEGRO_DISPLAY * display;
if(!al_init()){  
    fprintf(stderr, "failed to initialize allegro!\n");
    return -1;
}

//Now you need to initialize an allegro display with the flags for OPENGL :

al_set_new_display_flags(ALLEGRO_OPENGL); 
display = al_create_display(640, 480); 
if(!display){ 
    fprintf(stderr, "failed to create display!\n");
    return -1;
}

That is it on the allegro side of things . OpenGL will automatically operate on the backbuffer of our display (so we only need to call al_flip_display(); after everything is drawn ).

Note that from here on out everything is pure OpenGL . Allegro only swaps the buffers and displays the image. That is not that scary thow - turns out that OpenGl is not that complicated (to use at least) .

Setting up the OpenGL matrices

Basically OpenGL operates with objects in 3D space (described in points which have, as you could imagine ,3 coordinates : x,y,z). The objects get processed with a series of matrices (as they're "going through the pipeline" - the term that everyone loves using ). You need to know about 2 matrices + whatever you create . This system of processing is vital for speeding up the rendering . Why? Because the graphics processing units can do parallel operations which means applying a matrix to numerous points at once .

A matrix : you can dig into the mathematics of it but here's what you need to be able to use them :

They store the information for transforming an object by a certain model . Two basic types of transformations are translation and rotation :

-Translation simply means moving a point (respectively object) . glTranslate3f(0,20,0); is a func. to add this transformation to the current matrix (3f means 3 arguments type float). So everything that you draw after calling that func. will be with y+20 (as in higher) .

-Rotation is self explanatory . The math behind it is trickier than simple addition (as the prior example) but the principle's the same . You call glRotate and it applies itself on the current matrix , so that it affects all the objects described after that .

As mentioned before : the matrices that apply them selfs on the objects have an order . Lets imagine a stack of disks on your desk (disk=matrix) . When operating with them you take them 1 by 1 from top to bottom . OpenGL applies all matrices in top-bottom order when you draw an object (we'll get to that) . And when you use transformations they apply to the top matrix .

You need to know about two types of matrices that OpenGL applies to the objects that you will draw .

1.The projection matrix - it's the bottom matrix that has the information about the shape of the window that you'll display on (ratio (=Ratio ) of it's sides , clearly it rectangular) , the angle of sight of the imaginary camera (= Angle) and how far ahead would the camera see (=ClippingBorder1,ClippingBorder2 - the front and back border of sight)( if an object's out of that range it won't get drawn) . Here's how you set that matrix .

glMatrixMode(GL_PROJECTION); //Open the projection matrix as current
glLoadIdentity(); //clear its contents to an identity matrix (which doesn't change anything when applied)
gluPerspective( Angle, Ratio, ClippingBorder1, ClippingBorder2); 
//this function is from the very useful glu library . 
//It configures the projection matrix to the desired parameters

2.The modelview matrix - In real life you move the camera to look at a model (object) . In OpenGl you move (recalculate the position of) the object to get a different view . If you look at your mouse from one angle and then from another or if you look at it from the first angle but rotate it properly it's the same thing .

 That's what the modelview matrix is for it compensates the position of the camera with transformations on the model to get a proper view .

The properties of the camera that we haven't set with the projection matrix are : position , direction of sight and if it's tilted to some extent (the Up-Vector points to where is up for the camera).


Here's the setup:

glMatrixMode(GL_MODELVIEW); //select the matrix
glLoadIdentity(); //clear ...

gluLookAt ( CameraX , CameraY, CameraZ, SceneX, SceneY, SceneZ, UpVectorApexX, UpVectorApexY, UpVectorApexZ ); 
//(the origin of the upvector is 0,0,0 so if you set it on 0,1,0 it's pointing up)

//So that function is again from glu , it applies the needed transformations to the modelview matrix without you bothering with that

Drawing objects

So you have your matrices set and you want to draw something . The basic drawing with pure OpenGl is done via vectors between glBegin and glEnd:

glBegin(GL_LINES); //lookup for more options but GL_LINES tels GL that you'll be supplying a series of lines (via points)

glVertex3f(0,0,0);
glVertex3f(30,30,30); 

glEnd(); //this will draw a single line watched from the camera that we just set up

That way of creating objects is useful for understanding the mechanics but there are functions for drawing spheres ,cylinders etc. that will be more effective (lookup gluCylinder,gluSphere...).

Using your own matrices

If you want to move an object you can add a matrix to the pipeline (add a disk on the top of your stack) , draw an object (the pipeline processing is applied upon entering the vertexes ) , then throw the matrix away so it won't affect other objects :

glPushMatrix();//add matrix to stack

glTranslate(x,y,z); //move the objects that you'll draw before you delete your matrix with x,y,z

glBegin(GL_LINES);

//...
//...

glEnd();

glPopMatrix(); // remove the matrix from the stack