// 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 space as opposed to 3D vertices which
// are called with glVertex3f. The following coordinates will draw a square right 
// in the middle of our 500x500 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

#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;
}

