2018-09-06 01:48:27 +00:00
|
|
|
#include "camera.h"
|
2018-09-06 01:53:11 +00:00
|
|
|
#include "color.h"
|
2018-09-05 01:50:14 +00:00
|
|
|
#include "engine.h"
|
2018-09-06 01:53:11 +00:00
|
|
|
#include "geometry.h"
|
2018-09-06 02:26:54 +00:00
|
|
|
#include "light.h"
|
2018-09-05 02:50:27 +00:00
|
|
|
#include "loader.h"
|
2018-09-06 01:48:27 +00:00
|
|
|
#include "matrix.h"
|
|
|
|
#include "transform.h"
|
|
|
|
#include "util.h"
|
2018-09-06 02:26:54 +00:00
|
|
|
#include "vec.h"
|
2018-09-07 01:32:15 +00:00
|
|
|
#include <cstring>
|
2018-09-05 02:50:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
// GLOBALS
|
|
|
|
static Mesh mesh;
|
2018-09-06 01:48:27 +00:00
|
|
|
static Camera camera;
|
2018-09-06 02:26:54 +00:00
|
|
|
static LightList lights;
|
2018-09-14 01:57:06 +00:00
|
|
|
static Texture texture;
|
2018-09-05 02:50:27 +00:00
|
|
|
|
2018-09-05 01:50:14 +00:00
|
|
|
|
2018-09-06 01:48:27 +00:00
|
|
|
// PRIVATE PROTOTYPES
|
|
|
|
static void CheckInputs(uint32_t input);
|
|
|
|
|
|
|
|
|
|
|
|
// PUBLIC FUNCTIONS
|
|
|
|
int Engine_Init(Engine_Buffer &buffer, char *filename)
|
2018-09-05 01:50:14 +00:00
|
|
|
{
|
2018-09-05 02:50:27 +00:00
|
|
|
int result = LoadMesh(filename, mesh);
|
|
|
|
|
|
|
|
if (result < 0)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-09-06 01:48:27 +00:00
|
|
|
mesh.position.z = 250;
|
2018-09-06 02:26:54 +00:00
|
|
|
mesh.material.kDiffuse = {1.0,1.0,1.0,1.0};
|
|
|
|
mesh.material.kAmbient = {1.0,1.0,1.0,1.0};
|
2018-09-06 01:48:27 +00:00
|
|
|
|
|
|
|
camera.SetFOV(90.0f, buffer.width, buffer.height);
|
|
|
|
|
2018-09-06 02:26:54 +00:00
|
|
|
lights.diffuse = (LightDiffuse*)malloc(sizeof(LightDiffuse));
|
|
|
|
lights.diffuseCount = 1;
|
|
|
|
lights.ambient.intensity = 1.0;
|
|
|
|
lights.diffuse[0].intensity = 0.5;
|
|
|
|
lights.diffuse[0].direction = Vector(1,1,1);
|
|
|
|
|
2018-09-05 01:50:14 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Engine_Render(Engine_Buffer &buffer, uint32_t input)
|
|
|
|
{
|
2018-09-06 01:48:27 +00:00
|
|
|
CheckInputs(input);
|
|
|
|
|
2018-09-08 01:30:02 +00:00
|
|
|
|
|
|
|
// Clear the z-buffer
|
2018-09-07 01:32:15 +00:00
|
|
|
unsigned long bufferSize = (unsigned long)(buffer.width * buffer.height);
|
|
|
|
memset(buffer.zbuffer, 0, bufferSize * sizeof(float));
|
2018-09-06 02:26:54 +00:00
|
|
|
|
2018-09-08 01:30:02 +00:00
|
|
|
|
2018-09-06 02:26:54 +00:00
|
|
|
// Local space to world space
|
2018-09-06 01:48:27 +00:00
|
|
|
Matrix tTranslate = Transform_Translate(
|
|
|
|
mesh.position.x, mesh.position.y, mesh.position.z);
|
|
|
|
|
|
|
|
Matrix tRotate = Transform_Rotate(
|
|
|
|
mesh.rotation[0], mesh.rotation[1], mesh.rotation[2]);
|
|
|
|
|
2018-09-06 02:26:54 +00:00
|
|
|
Matrix tScale = Transform_Scale(mesh.scale);
|
|
|
|
|
2018-09-11 03:11:52 +00:00
|
|
|
for (size_t v = 0; v < mesh.local.verts.size(); ++v)
|
2018-09-06 02:26:54 +00:00
|
|
|
{
|
2018-09-11 03:11:52 +00:00
|
|
|
mesh.transformed.verts[v].point = mesh.local.verts[v].point * tScale * tRotate * tTranslate;
|
|
|
|
mesh.transformed.verts[v].normal = mesh.local.verts[v].normal * tScale * tRotate * tTranslate;
|
2018-09-06 02:26:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Cull backfaces before computing colors
|
2018-09-11 03:11:52 +00:00
|
|
|
CullBackfaces(mesh.local, mesh.transformed, camera.position);
|
2018-09-06 02:26:54 +00:00
|
|
|
|
|
|
|
|
2018-09-11 02:51:59 +00:00
|
|
|
// Color the vertices for Gouraud shading
|
2018-09-11 03:11:52 +00:00
|
|
|
if (mesh.smooth)
|
2018-09-06 02:26:54 +00:00
|
|
|
{
|
2018-09-11 03:11:52 +00:00
|
|
|
for (size_t f = 0; f < mesh.transformed.faces.size(); ++f)
|
2018-09-11 02:51:59 +00:00
|
|
|
{
|
|
|
|
for (int i = 0; i < 3; ++i)
|
|
|
|
{
|
2018-09-11 03:11:52 +00:00
|
|
|
unsigned int v = mesh.transformed.faces[f].vertIndex[i];
|
2018-09-06 01:48:27 +00:00
|
|
|
|
2018-09-11 02:51:59 +00:00
|
|
|
ColorF32 totalColor = lights.ambient.ComputeColor(mesh.material.kAmbient);
|
2018-09-06 01:48:27 +00:00
|
|
|
|
2018-09-11 02:51:59 +00:00
|
|
|
for (int c = 0; c < lights.diffuseCount; ++c)
|
|
|
|
{
|
|
|
|
totalColor += lights.diffuse[c].ComputeColor(
|
2018-09-11 03:11:52 +00:00
|
|
|
mesh.material.kDiffuse, mesh.transformed.verts[v].normal);
|
2018-09-11 02:51:59 +00:00
|
|
|
}
|
2018-09-06 02:26:54 +00:00
|
|
|
|
2018-09-11 03:11:52 +00:00
|
|
|
mesh.transformed.verts[v].color = totalColor;
|
2018-09-11 02:51:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-09-06 02:26:54 +00:00
|
|
|
|
2018-09-11 02:51:59 +00:00
|
|
|
// Color the face for flat shading
|
|
|
|
else
|
|
|
|
{
|
2018-09-11 03:11:52 +00:00
|
|
|
for (size_t f = 0; f < mesh.transformed.faces.size(); ++f)
|
2018-09-06 02:26:54 +00:00
|
|
|
{
|
2018-09-11 02:51:59 +00:00
|
|
|
ColorF32 totalColor = lights.ambient.ComputeColor(mesh.material.kAmbient);
|
|
|
|
|
|
|
|
for (int c = 0; c < lights.diffuseCount; ++c)
|
|
|
|
{
|
|
|
|
totalColor += lights.diffuse[c].ComputeColor(
|
2018-09-11 03:11:52 +00:00
|
|
|
mesh.material.kDiffuse, mesh.transformed.faces[f].normal);
|
2018-09-11 02:51:59 +00:00
|
|
|
}
|
2018-09-06 02:26:54 +00:00
|
|
|
|
2018-09-11 03:11:52 +00:00
|
|
|
mesh.transformed.faces[f].color = totalColor;
|
2018-09-11 02:51:59 +00:00
|
|
|
}
|
2018-09-06 02:26:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// World space to camera (view) space
|
|
|
|
Matrix tView = Transform_View(camera.position, camera.rotation);
|
|
|
|
|
|
|
|
// Camera space to perspective
|
2018-09-06 01:48:27 +00:00
|
|
|
Matrix tPersp = Transform_Perspective(
|
|
|
|
camera.xZoom, camera.yZoom, camera.nearClip, camera.farClip);
|
|
|
|
|
2018-09-06 02:26:54 +00:00
|
|
|
// Perspective to screen
|
2018-09-06 01:48:27 +00:00
|
|
|
Matrix tScreen = Transform_Screen(camera.xScale, camera.yScale);
|
|
|
|
|
2018-09-11 03:11:52 +00:00
|
|
|
for (size_t v = 0; v < mesh.transformed.verts.size(); ++v)
|
2018-09-06 01:48:27 +00:00
|
|
|
{
|
2018-09-11 03:11:52 +00:00
|
|
|
mesh.transformed.verts[v].point *= tView * tPersp * tScreen;
|
2018-09-14 01:57:06 +00:00
|
|
|
mesh.transformed.verts[v].point.x /= mesh.transformed.verts[v].point.w;
|
|
|
|
mesh.transformed.verts[v].point.y /= mesh.transformed.verts[v].point.w;
|
|
|
|
mesh.transformed.verts[v].point.z /= mesh.transformed.verts[v].point.w;
|
2018-09-06 01:48:27 +00:00
|
|
|
}
|
|
|
|
|
2018-09-14 01:57:06 +00:00
|
|
|
RenderMesh(buffer, mesh.transformed, mesh.smooth, texture, mesh.local.uvs);
|
2018-09-05 01:50:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Engine_Shutdown(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-09-06 01:48:27 +00:00
|
|
|
|
|
|
|
// PRIVATE FUNCTIONS
|
|
|
|
static void CheckInputs(uint32_t input)
|
|
|
|
{
|
|
|
|
if (CHECK_BIT(input, TRANSLATE_X_POS))
|
|
|
|
{
|
|
|
|
mesh.position.x += 10;
|
|
|
|
}
|
|
|
|
else if (CHECK_BIT(input, TRANSLATE_X_NEG))
|
|
|
|
{
|
|
|
|
mesh.position.x -= 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CHECK_BIT(input, TRANSLATE_Z_POS))
|
|
|
|
{
|
|
|
|
mesh.position.z += 10;
|
|
|
|
}
|
|
|
|
else if (CHECK_BIT(input, TRANSLATE_Z_NEG))
|
|
|
|
{
|
|
|
|
mesh.position.z -= 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CHECK_BIT(input, TRANSLATE_Y_POS))
|
|
|
|
{
|
|
|
|
mesh.position.y += 10;
|
|
|
|
}
|
|
|
|
else if (CHECK_BIT(input, TRANSLATE_Y_NEG))
|
|
|
|
{
|
|
|
|
mesh.position.y -= 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CHECK_BIT(input, ROTATE_X_POS))
|
|
|
|
{
|
|
|
|
mesh.rotation[0] += .10;
|
|
|
|
}
|
|
|
|
else if (CHECK_BIT(input, ROTATE_X_NEG))
|
|
|
|
{
|
|
|
|
mesh.rotation[0] -= .10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CHECK_BIT(input, ROTATE_Z_POS))
|
|
|
|
{
|
|
|
|
mesh.rotation[1] += .10;
|
|
|
|
}
|
|
|
|
else if (CHECK_BIT(input, ROTATE_Z_NEG))
|
|
|
|
{
|
|
|
|
mesh.rotation[1] -= .10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CHECK_BIT(input, ROTATE_Y_POS))
|
|
|
|
{
|
|
|
|
mesh.rotation[2] += .10;
|
|
|
|
}
|
|
|
|
else if (CHECK_BIT(input, ROTATE_Y_NEG))
|
|
|
|
{
|
|
|
|
mesh.rotation[2] -= .10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CHECK_BIT(input, SCALE_UP))
|
|
|
|
{
|
|
|
|
mesh.scale += 0.1f;
|
|
|
|
}
|
|
|
|
else if (CHECK_BIT(input, SCALE_DOWN))
|
|
|
|
{
|
|
|
|
mesh.scale -= 0.1f;
|
|
|
|
}
|
2018-09-11 02:51:59 +00:00
|
|
|
|
|
|
|
if (CHECK_BIT(input, SHADING_TOGGLE))
|
|
|
|
{
|
2018-09-11 03:11:52 +00:00
|
|
|
mesh.smooth = true;
|
2018-09-11 02:51:59 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-09-11 03:11:52 +00:00
|
|
|
mesh.smooth = false;
|
2018-09-11 02:51:59 +00:00
|
|
|
}
|
2018-09-06 01:48:27 +00:00
|
|
|
}
|