CSC3223_Graphics_For_Games_OpenGL_Rasteriser / OpenGLGraphics / main.cpp
main.cpp
Raw
#pragma comment(lib, "nclgl.lib")
#include "Renderer.h"
#include "RenderObject.h"
#define SHADERS 8

Shader *generateShaders[SHADERS];

void loadShaders() {
	for (int i = 0; i < SHADERS; i++) {
		generateShaders[i] = NULL;
	}
	/**/
	generateShaders[0] = new Shader("../Shaders/basic_vertex.glsl", "../Shaders/basic_fragment.glsl");
	generateShaders[1] = new Shader("../Shaders/shrink_vertex.glsl", "../Shaders/basic_fragment.glsl");
	generateShaders[2] = new Shader("../Shaders/basic_vertex.glsl", "../Shaders/texfade_fragment.glsl");
	generateShaders[3] = new Shader("../Shaders/basic_vertex.glsl", "../Shaders/fade_fragment.glsl");
	generateShaders[4] = new Shader("../Shaders/nomvp_vertex.glsl", "../Shaders/basic_fragment.glsl", "../Shaders/split_geometry.glsl");
	generateShaders[5] = new Shader("../Shaders/nomvp_vertex.glsl", "../Shaders/basic_fragment.glsl", "", "../Shaders/detail_tcs.glsl", "../Shaders/detail_tes.glsl");
	generateShaders[6] = new Shader("../Shaders/lighting_vertex.glsl", "../Shaders/lighting_fragment.glsl");
	generateShaders[7] = new Shader("../Shaders/nomvp_vertex.glsl", "../Shaders/lighting_fragment.glsl", "", "../Shaders/detail_tcs.glsl", "../Shaders/detail_tes.glsl");
	/**/
	int unsuccessful = 0;
	for (int i = 0; i < SHADERS; i++){
		if (generateShaders[i] != NULL && generateShaders[i]->UsingDefaultShader()) {
			unsuccessful++;
			cout << "Shader number" << i << " failed to load or compile" << endl;
		}
	}
	if (unsuccessful == 0) {
		cout << "All shaders successfully loaded and compiled" << endl;
	}
}

void deleteShaders() {
	for (int i = 0; i < SHADERS; i++) {
		if (generateShaders[i] != NULL) {
			delete generateShaders[i];
		}
		generateShaders[i] = NULL;
	}
}

void main(void)
{
	bool rotateCube = true;
	bool disableDepth = false;

	Window w = Window(800, 600);
	Renderer r(w);

	//Load cube mesh and textures for the cube
	Mesh *cubeMesh = Mesh::LoadMeshFile("cube.asciimesh");
	GLuint normalCube = r.LoadTexture("../Textures/perlin.png");
	GLuint destroyedCube = r.LoadTexture("../Textures/noise.png");
	GLuint  tessellationCube = r.LoadTexture("../Textures/noise.png");

	//Create cube 
	RenderObject cube(cubeMesh, generateShaders[0], normalCube);
	cube.SetTexture(1, destroyedCube);
	cube.SetTexture(2, tessellationCube);

	//Create laser beam
	Mesh *fixedLaserBeamMesh = Mesh::GenerateLine(Vector3(-2.0, 0.0, 10.0), Vector3(0.0, 0.0, -10.0));
	Mesh *movingLaserBeamMesh = Mesh::GenerateLine(Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 10.0));
	Shader *laserBeamShader = new Shader("../Shaders/basic_vertex.glsl", "../Shaders/notex_fragment.glsl");
	RenderObject fixedLaserBeam(fixedLaserBeamMesh, laserBeamShader);
	RenderObject movingLaserBeam(movingLaserBeamMesh, laserBeamShader);
	cube.AddChild(movingLaserBeam);

	//Load and try to compile the shaders
	loadShaders();

	cube.SetModelMatrix(Matrix4::Translation(Vector3(0.0, 0.0, -10.0)));
	fixedLaserBeam.SetModelMatrix(Matrix4::Translation(Vector3(0.0, 1000.0, 0.0)));
	movingLaserBeam.SetModelMatrix(Matrix4::Translation(Vector3(0.0, 1000.0, 0.0)));
	r.AddRenderObject(cube);
	r.AddRenderObject(fixedLaserBeam);
	
	//Create prespective
	r.SetProjectionMatrix(Matrix4::Perspective(1, 100, 1.33f, 45.0f));
	r.SetViewMatrix(Matrix4::BuildViewMatrix(Vector3(0, 0, 0), Vector3(0, 0, -10)));

	r.SetShaderLight(0, Vector3(5.0f, 10.0f, 10.0f), Vector3(1, 1, 1), 1000.0f);
	//Create second laser beam light
	r.SetShaderLight(1, Vector3(0.0f, 1000.0f, 0.0f), Vector3(0, 0, 0), 0.0f);

	cube.SetShader(generateShaders[0]);

	//Print commands
	cout << endl
		<< "Key:" << endl
		<< "s - Shrink the cube then let the cube vanish" << endl
		<< "d - Blend the normal texture to a destroyed texture" << endl
		<< "f - Fade the cube" << endl
		<< "q - Cube appear to fall to pieces" << endl
		<< "w - Add more detail to each face" << endl
		<< "W - Add more detail to each face with lighting" << endl
		<< "e - Fixed laser beam with rel-time lighting" << endl
		<< "E - Moving laser beam with rel-time lighting" << endl
		<< "r - Reset scene" << endl
		<< "p - Pause animation" << endl
		<< "P - Pause rotation" << endl
		<< "+ - Zoom in" << endl
		<< "- - Zoom out" << endl;

	while (w.UpdateWindow())
	{
		float msec = w.GetTimer()->GetTimedMS();

		//Rotate the cube
		if (rotateCube) {
			cube.SetModelMatrix(cube.GetModelMatrix() * Matrix4::Rotation(0.20f * msec, Vector3(0, 0.5f, 0.5f)));
		}

		//Shrink the cube and then let it vanish
		if (Keyboard::KeyTriggered(KEY_S)) {
			cube.SetShader(generateShaders[1]);
			r.startAnimation();
		}

		//Blend the normal texture to a destroyed texture
		if (Keyboard::KeyTriggered(KEY_D)) {
			cube.SetShader(generateShaders[2]);
			r.startAnimation();
		}

		// Fade the cube
		if (Keyboard::KeyTriggered(KEY_F)) {
			disableDepth = true;
			cube.SetShader(generateShaders[3]);
			r.startAnimation();
		}

		//Cube appear to fall to pieces (geometry shader)
		if (Keyboard::KeyTriggered(KEY_Q)) {
			cube.SetShader(generateShaders[4]);
			r.startAnimation();
		}

		//Add more detail to each face (tessellation shader)
		if (Keyboard::KeyTriggered(KEY_W)) {
			if (Keyboard::KeyHeld(KEY_SHIFT)) {
				//Add light
				cubeMesh->type = GL_PATCHES;
				cube.SetShader(generateShaders[7]);
			}
			else {
				//No light
				cubeMesh->type = GL_PATCHES;
				cube.SetShader(generateShaders[5]);
			}
		}

		//Creat laser beam (fragment shader)
		if (Keyboard::KeyTriggered(KEY_E)) {
			cube.SetShader(generateShaders[6]);
			if (Keyboard::KeyHeld(KEY_SHIFT)) {
				// Position the moving laser into the scene
				movingLaserBeam.SetModelMatrix(Matrix4::Translation(Vector3(0.0, 0.0, 0.0)));
			}
			else {
				// Position the static laser into the scene
				fixedLaserBeam.SetModelMatrix(Matrix4::Translation(Vector3(0.0, 0.0, 0.0)));
				//Add the light source
				r.SetShaderLight(1, Vector3(-5.0f, 0.0f, 5.0f), Vector3(2, 0, 0), 25.0f);
			}
		}

		//Pause the animation
		if (Keyboard::KeyTriggered(KEY_P)) {   // Pause rotation
			if (Keyboard::KeyDown(KEY_SHIFT)) {
				rotateCube = !rotateCube;
			}
			else {
			r.pauseAnimation();
			}
		}

		//Reset thescene
		if (Keyboard::KeyTriggered(KEY_R)) {
			r.SetShaderLight(1, Vector3(0.0f, 1000.0f, 0.0f), Vector3(0, 0, 0), 0.0f);
			fixedLaserBeam.SetModelMatrix(Matrix4::Translation(Vector3(0.0, 1000.0, 0.0)));
			movingLaserBeam.SetModelMatrix(Matrix4::Translation(Vector3(0.0, 1000.0, 0.0)));
			cubeMesh->type = GL_TRIANGLES;
			glEnable(GL_DEPTH_TEST);
			r.stopAnimation();
			cube.SetShader(generateShaders[0]);
		}

		//Zoom into the scene
		if (Keyboard::KeyTriggered(KEY_PLUS)) {
			cube.SetModelMatrix(Matrix4::Translation(Vector3(0.0f, 0.0f, 1.0f)) * cube.GetModelMatrix());
		}

		//Zoom out the scene
		if (Keyboard::KeyTriggered(KEY_MINUS)) {
			cube.SetModelMatrix(Matrix4::Translation(Vector3(0.0f, 0.0f, -1.0f)) * cube.GetModelMatrix());
		}

		//Disable the depth of the cube 
		if (disableDepth && glIsEnabled(GL_DEPTH_TEST) && r.getAnimPosition() > 0.20) {
			glDisable(GL_DEPTH_TEST);
			disableDepth = false;
		}

		r.UpdateScene(msec);
		r.ClearBuffers();
		r.RenderScene();
		r.SwapBuffers();
	}
}