34. Orthogonal Projections

Welcome to another in my slowly building long line of OpenGL tutorials.
Here we will be looking at how to implement orthogonal projections to
incorporate 2D into our program. This will draw our shape in a space that
will not move when our 3D scene is rotated. This is perfect when
implementing a display system into your game that displays health, ammo
etc. So lets get started now.

————————————————————————–
Section 1: Variables

The only global variables I am going to be using in this are:
int w1;
int h1;

These will simply hold our window width and height as gathered in our
reshape function.

————————————————————————-
Section 2: Starting the orthogonal projection.

This call, no matter when it is called, will start our orthogonal
projection, I have called it orthogonalStart:

void orthogonalStart (void) {
First of all, we need to switch to our projection matrix
glMatrixMode(GL_PROJECTION);
Start our projection modifications
glPushMatrix();
Then we need to clear it of all previous information
glLoadIdentity();
Now I am calling: gluOrtho2D instead of the previous gluPerspective
which was in our reshape function. This takes our parameters which
set the view space from 0,0 in the window, to the width and height of the
window which we collect in our reshape function
gluOrtho2D(0, w1, 0, h1);
Now we need to flip our scene upside down
glScalef(1, -1, 1);
And translate it to display our scene correctly
glTranslatef(0, -h1, 0);
Now we switch back to our model matrix so we can draw our 2D shapes
glMatrixMode(GL_MODELVIEW);
}

———————————————————————
Section 3: Ending the orthogonal projection and restoring our perspective
projection

To end our orthogonal projection, I am calling the function, which I have
called orthogonalEnd which will set our scene back to how it was
void orthogonalEnd (void) {
Switch back to our projection mode
glMatrixMode(GL_PROJECTION);
Finish our calls above
glPopMatrix();
Switch back to our model matrix to continue with out 3D scene
glMatrixMode(GL_MODELVIEW);
}

———————————————————————
Section 4: Display

Now to draw our information, I have called the following from within
my display function:

Call our function to start our orthogonal projections
orthogonalStart();

Begin drawing a quad, note here that in orthogonal space, we work with
pixels as opposed to units in 3D space which have no length of measurement
glBegin(GL_QUADS);
Now I am drawing our vertices in 2D as opposed to 3D vertices which
are called with glVertex3f. The following coordinates will draw a square right
in the middle of our 500×500 window.
glVertex2f(125, 125);
glVertex2f(125, 375);
glVertex2f(375, 375);
glVertex2f(375, 125);
glEnd();

Now we call our function to end our orthogonal projections
orthogonalEnd();

——————————————————————–
Section 5: Reshape

In our reshape function I am using the following lines:
w1 = w;
h1 = h;

Which I have called after our gluPerspective call. This will set
our variables to the width and the height of our window.

——————————————————————-

And there we have it, if you have any questions, please email me at
swiftless@gmail.com

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
    #include <GL/gl.h>
#include <GL/glut.h>
#include <windows.h>
#include <stdio.h>

int w1;
int h1;

void orthogonalStart (void) {
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D(0, w1, 0, h1);
    glScalef(1, 1, 1);
    glTranslatef(0, h1, 0);
    glMatrixMode(GL_MODELVIEW);
}

void orthogonalEnd (void) {
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
}

void display (void) {
    glClearColor (1.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    orthogonalStart();

    glBegin(GL_QUADS);
    glVertex2f(125, 125);
    glVertex2f(125, 375);
    glVertex2f(375, 375);
    glVertex2f(375, 125);
    glEnd();

    orthogonalEnd();

    glutSwapBuffers();
}

void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 1000.0);
    w1 = w;
    h1 = h;
    glMatrixMode (GL_MODELVIEW);
}

int main (int argc, char **argv) {
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA
);
    glutInitWindowSize (500, 500);
    glutInitWindowPosition (100, 100);
    glutCreateWindow (“A Basic Window);
    glutDisplayFunc (display);
    glutIdleFunc (display);
    glutReshapeFunc (reshape);
    glutMainLoop ();
    return 0;
}

  • March 25, 2010
  • 10