The projection matrix transforms all vertex data from the eye coordinates to the clip coordinates.
Then, these clip coordinates are also transformed to the normalized device coordinates (NDC) by dividing with w
component of the clip coordinates.
The normalized device coordinates is in range (-1, -1, -1) to (1, 1, 1).
With the orthographic projection, the eye space coordinates are linearly mapped to the NDC.
The orthographic projection can be set up by glOrtho
. If you want to set up a projection that allows you to draw in window size scales, then you have to do it like this:
int wndWidth = 800;
int wndHeight = 400;
glOrtho( 0.0, (float)wndWidth, 0.0, (float)wndHeight, -1.0, 1.0 );
If the viewport is rectangular this has to be considerd by mapping the coordinates.
float aspect = (float)widht/height;
glOrtho(-aspect, aspect, -1.0f, 1.0f, -1.0f, 1.0f);
You set up a proper window size projection matrix before you draw the rectangles (drawRect
)
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, 800, 0.0f, 400, 0.0f, 1.0f);
.....
drawRect( ..... );
But you "clear" the projection matrix and do not care about the aspect of the view before you draw the circle (drawBall
).
Change your code somehow like this:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float aspect = 800.0f/400.0f;
glOrtho(-aspect, aspect, -1.0f, 1.0f, -1.0f, 1.0f);
drawBall();
By the way, while glPushMatrix
push an element to the matrix stack, glPopMatrix
pop an element from the matrix stack. In OpenGL there is one matrix stack for each matrix mode (See glMatrixMode
). The matrix modes are GL_MODELVIEW
, GL_PROJECTION
, and GL_TEXTURE
and all matrix operations, are applied to the matrix stack you have specified by glMatrixMode
.
This means the both glPopMatrix
instructions at the end of your code snippet should not be there.