#ifdef _WIN32
#include <windows.h>
#endif
#include "stdafx.h"
#include <GL/glut.h>

enum DISPLAYMODE
{
	DM_POINTS,
	DM_TRIANGLES,
	DM_FACECOLOUREDTRIANGLES,
	DM_VERTEXCOLOUREDTRIANGLES,
	DM_INDEXEDVERTEXCOLOUREDTRIANGLES
};

void RenderTetrahedronPoints();
void RenderTetrahedronTriangles();
void RenderTetrahedronFaceColouredTriangles();
void RenderTetrahedronVertexColouredTriangles();
void RenderIndexedTetrahedronVertexColouredTriangles();

static float	   CurrentAngle = 0.0f;			
static DISPLAYMODE DisplayMode  = DM_INDEXEDVERTEXCOLOUREDTRIANGLES;

void init()
{
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

	glEnable(GL_DEPTH_TEST);
}

void Display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(0.0f, 0.0f, -5.0f);

	glRotatef(CurrentAngle, 1.0f, 1.0f, 1.0f);
	glScalef(2.5f, 2.5f, 2.5f);
	glTranslatef(-0.5f, -0.45f, 0.0f);

	switch (DisplayMode)
	{
	case DM_POINTS:
		RenderTetrahedronPoints();                        
		break;
	case DM_TRIANGLES:
		RenderTetrahedronTriangles();                     
		break;
	case DM_FACECOLOUREDTRIANGLES:
		RenderTetrahedronFaceColouredTriangles();         
		break;
	case DM_VERTEXCOLOUREDTRIANGLES:
		RenderTetrahedronVertexColouredTriangles();       
		break;
	case DM_INDEXEDVERTEXCOLOUREDTRIANGLES:
		RenderIndexedTetrahedronVertexColouredTriangles();
		break;
	}

	glFinish();

	glutSwapBuffers();
}

void IdleAnimate()
{
	CurrentAngle += 0.1f;

	if (CurrentAngle > 360.0f)
	{
		CurrentAngle -= 360.0f;
	}

	glutPostRedisplay();
}

void Reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0f, (GLfloat)w / (GLfloat) h, 1.0f, 20.0f);
}

void Keyboard(unsigned char Key, int x, int y)
{
	switch (Key)
	{
	case '1':
		DisplayMode = DM_POINTS;
		break;

	case '2':
		DisplayMode = DM_TRIANGLES;
		break;

	case '3':
		DisplayMode = DM_FACECOLOUREDTRIANGLES;
		break;

	case '4':
		DisplayMode = DM_VERTEXCOLOUREDTRIANGLES;
		break;

	case '5':
		DisplayMode = DM_INDEXEDVERTEXCOLOUREDTRIANGLES;
		break;
	}
}
   
int main2(int argc, char ** argv)
{
	glutInit(&argc, argv);

	glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
	glutInitWindowSize(640, 480);
	glutInitWindowPosition(0, 0);
	glutCreateWindow(argv[0]);

	init();

	glutDisplayFunc(Display);
	glutReshapeFunc(Reshape);
	glutKeyboardFunc(Keyboard);
	glutIdleFunc(IdleAnimate);

	glutMainLoop();

	return 0;
}


void RenderTetrahedronPoints()
{
	glColor3f(1.0f, 1.0f, 1.0f);	
	
	glBegin(GL_POINTS);
	glVertex3f(0.0f, 0.0f, 0.0f);
	glVertex3f(1.0f, 0.0f, 0.0f);    
	glVertex3f(0.5f, 0.0f, 0.8660f);
	glVertex3f(0.5f, 0.9014f, 0.4330f);
	glEnd();
}

void RenderTetrahedronTriangles()
{
	glColor3f(1.0f, 1.0f, 1.0f);		glBegin(GL_TRIANGLES);

	glVertex3f(0.0f, 0.0f, 0.0f);		// Trian ACB 
	glVertex3f(0.5f, 0.0f, 0.8660f);
	glVertex3f(1.0f, 0.0f, 0.0f);    

	glVertex3f(0.0f, 0.0f, 0.0f);		// Trian ADC
	glVertex3f(0.5f, 0.9014f, 0.4330f);
	glVertex3f(0.5f, 0.0f, 0.8660f);

	glVertex3f(0.5f, 0.0f, 0.8660f);	// Trian CDB
	glVertex3f(0.5f, 0.9014f, 0.4330f);
	glVertex3f(1.0f, 0.0f, 0.0f);    

	glVertex3f(0.0f, 0.0f, 0.0f);		// Trian ADB
	glVertex3f(0.5f, 0.9014f, 0.4330f);
	glVertex3f(1.0f, 0.0f, 0.0f);    

	glEnd();
}

void RenderTetrahedronFaceColouredTriangles()
{
	glShadeModel(GL_FLAT); 

	glBegin(GL_TRIANGLES);

	glColor3f(1.0f, 0.0f, 0.0f);	
	glVertex3f(0.0f, 0.0f, 0.0f);		// Tri ACB 
	glVertex3f(0.5f, 0.0f, 0.8660f);
	glVertex3f(1.0f, 0.0f, 0.0f);    

	glColor3f(0.0f, 1.0f, 0.0f);	
	glVertex3f(0.0f, 0.0f, 0.0f);		// Tri ADC
	glVertex3f(0.5f, 0.9014f, 0.4330f);
	glVertex3f(0.5f, 0.0f, 0.8660f);

	glColor3f(0.0f, 0.0f, 1.0f);	
	glVertex3f(0.5f, 0.0f, 0.8660f);	// Tri CDB
	glVertex3f(0.5f, 0.9014f, 0.4330f);
	glVertex3f(1.0f, 0.0f, 0.0f);    

	glColor3f(1.0f, 1.0f, 0.0f); 	
	glVertex3f(0.0f, 0.0f, 0.0f);		// Tri ADB
	glVertex3f(0.5f, 0.9014f, 0.4330f);
	glVertex3f(1.0f, 0.0f, 0.0f);    

	glEnd();
}

void RenderTetrahedronVertexColouredTriangles()
{
	glShadeModel(GL_SMOOTH);

	glBegin(GL_TRIANGLES);

	glColor3f(1.0f, 0.0f, 0.0f);	
	glVertex3f(0.0f, 0.0f, 0.0f);		// Tri ACB 
	glColor3f(0.0f, 0.0f, 1.0f);
	glVertex3f(0.5f, 0.0f, 0.8660f);
	glColor3f(0.0f, 1.0f, 0.0f);
	glVertex3f(1.0f, 0.0f, 0.0f);    

	glColor3f(1.0f, 0.0f, 0.0f);	
	glVertex3f(0.0f, 0.0f, 0.0f);		// Tri ADC
	glColor3f(1.0f, 1.0f, 0.0f); 			
	glVertex3f(0.5f, 0.9014f, 0.4330f);
	glColor3f(0.0f, 0.0f, 1.0f);			
	glVertex3f(0.5f, 0.0f, 0.8660f);

	glColor3f(0.0f, 0.0f, 1.0f);		
	glVertex3f(0.5f, 0.0f, 0.8660f);	// Tri CDB
	glColor3f(1.0f, 1.0f, 0.0f); 		
	glVertex3f(0.5f, 0.9014f, 0.4330f);
	glColor3f(0.0f, 1.0f, 0.0f);		
	glVertex3f(1.0f, 0.0f, 0.0f);    

	glColor3f(1.0f, 0.0f, 0.0f); 		
	glVertex3f(0.0f, 0.0f, 0.0f);		// Tri ADB
	glColor3f(1.0f, 1.0f, 0.0f); 		
	glVertex3f(0.5f, 0.9014f, 0.4330f);
	glColor3f(0.0f, 1.0f, 0.0f);			
	glVertex3f(1.0f, 0.0f, 0.0f);    

	glEnd();
}

void RenderIndexedTetrahedronVertexColouredTriangles()
{
	static float VertexPositions[][3] = 
	{
		{0.0f, 0.0f, 0.0f},
		{1.0f, 0.0f, 0.0f},
		{0.5f, 0.0f, 0.8660f},
		{0.5f, 0.9014f, 0.4330f}
	};

	static float VertexColors[][3] = 
	{
		{1.0f, 0.0f, 0.0f},
		{0.0f, 1.0f, 0.0f},
		{0.0f, 0.0f, 1.0f},
		{1.0f, 1.0f, 0.0f}
	};

	static short Triangles[][3] = 
	{
		{0, 2, 1},
		{0, 3, 2},
		{2, 3, 1},
		{0, 3, 1}
	};

	glShadeModel(GL_SMOOTH);

	glBegin(GL_TRIANGLES);

	for (int TriangleNum = 0; TriangleNum < 4; TriangleNum++)
	{
		for (int VertexNum = 0; VertexNum < 3; VertexNum++)
		{
			short VertexIndex = Triangles[TriangleNum][VertexNum];

			glColor3fv(VertexColors[VertexIndex]);
			glVertex3fv(VertexPositions[VertexIndex]);
		}
	}

	glEnd();
}

