CSC3223_Graphics_For_Games_Software_Rasteriser / SoftwareRasteriser / main.cpp
main.cpp
Raw
#include "SoftwareRasteriser.h"
#include "Mesh.h"
#include "Texture.h"

// Create Field of stars
void generateRandomStars(vector<RenderObject *> &output, const int numOfAsteroids = 100,
                             const float xySpan = 1.0f, const float zSpan = 1.0f);
// Create field of asteroids
void generateRandomAsteroids(vector<RenderObject *> &output, const int numOfAsteroids = 100,
                             const float xySpan = 1.0f, const float zSpan = 1.0f);
// Create field of asteroids
void generateAsteroids(vector<RenderObject *> &output, const Vector3 &position, const float scale);

int main()
{
  const int screenX = 800;
  const int screenY = 600;
  SoftwareRasteriser r(screenX, screenY);

  //Set the scene
  const float aspect = (float)screenX / (float)screenY;
  r.SetProjectionMatrix(Matrix4::Perspective(0.1f, 100.0f, aspect, 50.0f));
  r.SetTextureSamplingMode(SAMPLE_BILINEAR);
  r.SetBlendSamplingMode(SAMPLE_BLEND_ALPHA);

  vector<RenderObject *> object;

  // Planet (triangle fan)
  RenderObject *planet = new RenderObject();
  planet->mesh = Mesh::GeneratePlanetCircle(7.0f, 30);
  planet->texture = Texture::TextureFromTGA("../planet.tga");
  planet->modelMatrix = Matrix4::Translation(Vector3(-6.0f, -8.0f, -15.0f));
  object.push_back(planet);
  
  // Blue moon (textured sphere) // textures of 256x256 pixels
  RenderObject *moon = new RenderObject();
  moon->mesh = Mesh::GenerateMoonSphere(2.5f, 15, Colour(255, 0, 0, 255));
  moon->texture = Texture::TextureFromTGA("../moon.tga");
  moon->modelMatrix = Matrix4::Translation(Vector3(-4.0f, -4.0f, -8.0f));
  object.push_back(moon);

  // Planet asteroid belt (triangle strip)
  RenderObject *spaceDebris = new RenderObject();
  spaceDebris->mesh = Mesh::GenerateSpaceDebrish(10, 8, 16);
  spaceDebris->texture = Texture::TextureFromTGA("../space_debris.tga");
  spaceDebris->modelMatrix = Matrix4::Translation(Vector3(-6.0f, -8.0f, -15.0f)) *
                              Matrix4::Rotation(90.0f, Vector3(1.0f, 0.0f, 0.0f));
  object.push_back(spaceDebris);

  // Spaceship 1 (triangles with interpolated colours and semi-transparency on back window)
  RenderObject *spaceship = new RenderObject();
  spaceship->mesh = Mesh::LoadMeshFile("../spaceshipV2.asciimesh");
  spaceship->modelMatrix = Matrix4::Scale(Vector3(1.0, 1.0, 1.0)) *
                           Matrix4::Translation(Vector3(2.0f, 2.0f, -2.0f)) *
                           Matrix4::Rotation(40.0f, Vector3(1.0, 1.0, 0.0)) *
                           Matrix4::Rotation(-100.0f, Vector3(0.0, 1.0, 0.0));
  object.push_back(spaceship);

  // Spaceship 2
  RenderObject *spaceship2 = new RenderObject();
  spaceship2->mesh = Mesh::LoadMeshFile("../spaceshipV1.asciimesh");
  spaceship2->modelMatrix = Matrix4::Scale(Vector3(1.5, 1.5, 1.5)) *  
  Matrix4::Translation(Vector3(3.0f, 3.0f, -3.0f));
  object.push_back(spaceship2);
  
  // Spaceship 3
  RenderObject *spaceship3 = new RenderObject();
  spaceship3->mesh = Mesh::LoadMeshFile("../spaceship.asciimesh");
  spaceship3->modelMatrix = Matrix4::Scale(Vector3(1.5, 1.5, 1.5));
  Matrix4::Translation(Vector3(4.0f, 4.0f, -4.0f));
  object.push_back(spaceship3);

  
  // Create field of starts (random point primitives)
  generateRandomStars(object, 7500);

  // Create Asteroids (random line primitive shapes)
  generateRandomAsteroids(object, 75);

  // Create asteroids closer to the scene (random line primitive shapes)
  generateRandomAsteroids(object, 35, 0.5);
 
  Matrix4 viewMatrix = Matrix4::Translation(Vector3(0.0f, 0.0f, -15.0f));
  Matrix4 cameraRotation;

  while (r.UpdateWindow())
  {
	  // Move faster when holding Space
	  float cameraSpeed = 0.25f;
	  if (Keyboard::KeyHeld(KEY_SPACE)) {
		  cameraSpeed = 0.5f;
	  }
	  //Used for debugging
	  /*
	  //when button pressed destroy planet
	  if (Keyboard::KeyTriggered(KEY_1)) {
		  planet->~RenderObject();  
	  }
	  //when button pressed destroy moon
	  if (Keyboard::KeyTriggered(KEY_2)) {
		  moon->~RenderObject();
	  }
	  //when button pressed destroy space debris
	  if (Keyboard::KeyTriggered(KEY_3)) {
		  spaceDebris->~RenderObject();
	  }*/

	  // Blend mode
	  if (Keyboard::KeyTriggered(KEY_B)) {
		  string mode;

		  if (r.GetBlendSamplingMode() == SAMPLE_BLEND_ALPHA)
		  {
			  r.SetBlendSamplingMode(SAMPLE_BLEND_ADDITION);
			  mode = "mode: Addition";
		  }
		  else
		  {
			  r.SetBlendSamplingMode(SAMPLE_BLEND_ALPHA);
			  mode = "mode: Alpha";
		  }
		  std::cout << "Blend sampling mode: " << mode << std::endl;
	  }
		if (Keyboard::KeyDown(KEY_A)) {
		  viewMatrix = viewMatrix * Matrix4::Translation(Vector3(cameraSpeed, 0.0f, 0.0f));
	  }
		if (Keyboard::KeyDown(KEY_D)) {
		  viewMatrix = viewMatrix * Matrix4::Translation(Vector3(-cameraSpeed, 0.0f, 0.0f));
	  }
		if (Keyboard::KeyDown(KEY_W)) {
		viewMatrix = viewMatrix * Matrix4::Translation(Vector3(0.0f, -cameraSpeed, 0.0f));
	 }
		if (Keyboard::KeyDown(KEY_S)) {
		viewMatrix = viewMatrix * Matrix4::Translation(Vector3(0.0f, cameraSpeed, 0.0f));
	 }
		if (Keyboard::KeyDown(KEY_E)) {
			viewMatrix = viewMatrix * Matrix4::Translation(Vector3(0.0f, 0.0f, cameraSpeed));
	}
		if (Keyboard::KeyDown(KEY_Q)) {
		viewMatrix = viewMatrix * Matrix4::Translation(Vector3(0.0f, 0.0f, -cameraSpeed));
	}

    const Vector2 mouseRelativePosition = Mouse::GetRelativePosition();
	cameraRotation = cameraRotation * Matrix4::Rotation(mouseRelativePosition.x, Vector3(0.0f, 1.0f, 0.0f)) *
                  Matrix4::Rotation(mouseRelativePosition.y, Vector3(1.0f, 0.0f, 0.0f));

    r.SetViewMatrix(viewMatrix * cameraRotation);

    // Make the space ship fly
    spaceship->modelMatrix = spaceship->modelMatrix *
                             Matrix4::Rotation(0.8f, Vector3(0.0f, 15.0f, 0.0f)) *
                             Matrix4::Translation(Vector3(0.0f, 0.0f, 0.10f));

    r.ClearBuffers();

    // Draw scene objects
    for (vector<RenderObject *>::iterator scene = object.begin(); scene != object.end(); ++scene)
      r.DrawObject(*scene);
    r.SwapBuffers();
  }

  // Remove all objects
  object.clear();
  return 0;
}

//Generates a star field of points at random positions.
void generateRandomStars(vector<RenderObject *> &output, const int numOfAsteroids, const float xySpan, const float zSpan) {
  for (int i = 0; i < numOfAsteroids; ++i) {
    const float x = ((float)((rand() % 100) - 50)) * xySpan;
    const float y = ((float)((rand() % 100) - 50)) * xySpan;
    const float z = ((float)((rand() % 100) - 50)) * zSpan;

    // Generate random colour
    const int red = (rand() % 100) + 122;
    const int green = (rand() % 100) + 122;
    const int blue = (rand() % 100) + 122;
    Colour colour = Colour(red, green, blue, 223);

    RenderObject *randomStarsObject = new RenderObject();
	randomStarsObject->mesh = Mesh::GeneratePoints(Vector3(), colour);
	randomStarsObject->modelMatrix = Matrix4::Translation(Vector3(x, y, z));
	output.push_back(randomStarsObject);
  }
}

// Random asteroids of random sizes
void generateRandomAsteroids(vector<RenderObject *> &output, const int numOfAsteroids, const float xySpan, const float zSpan) {
  for (int i = 0; i < numOfAsteroids; ++i) {
    const float x = ((float)((rand() % 100) - 50)) * xySpan;
    const float y = ((float)((rand() % 100) - 50)) * xySpan;
    const float z = ((float)((rand() % 100) - 50)) * zSpan;
    const float scale = ((float)(rand() % 100)) / 100.0f;

	generateAsteroids(output, Vector3(x, y, z), scale);
  }
}

 //Generates asteroids
void generateAsteroids(vector<RenderObject *> &output, const Vector3 &position, const float scale) {
  const Matrix4 modelMat = Matrix4::Translation(position) * Matrix4::Scale(Vector3(scale, scale, scale));
  const float rotation = (float)((rand() % 35) + 160);
  RenderObject *asteroidObject1 = new RenderObject();
  asteroidObject1->mesh = Mesh::GenerateNSidedShape(7);
  asteroidObject1->modelMatrix = modelMat;
  RenderObject *asteroidObject2 = new RenderObject();
  asteroidObject2->mesh = Mesh::GenerateNSidedShape(9);
  asteroidObject2->modelMatrix = modelMat * Matrix4::Scale(Vector3(0.75f, 0.75f, 0.75f)) * Matrix4::Rotation(rotation, Vector3(0.0f, 0.0f, 0.8f));
  output.push_back(asteroidObject1);
  output.push_back(asteroidObject2);
}