#include "Rasteriser.h" Rasteriser app; bool Rasteriser::Initialise() { Model modelA; Model modelB; Model modelC; if (MD2Loader::LoadModel(".\\marvin.MD2", modelA, &Model::AddPolygon, &Model::AddVertex)) { _sceneModels.push_back(modelA); } else { return false; } if (MD2Loader::LoadModel(".\\megaman.MD2", modelB, &Model::AddPolygon, &Model::AddVertex)) { _sceneModels.push_back(modelB); } else { return false; } if (MD2Loader::LoadModel(".\\w_railgun.MD2", modelC, &Model::AddPolygon, &Model::AddVertex)) { _sceneModels.push_back(modelC); } else { return false; } _lights.push_back(new AmbientLight(50, 50, 50)); _lights.push_back(new DirectionalLight(Vector3D(1, 0, 1), 50, 0, 0)); _lights.push_back(new PointLight(Vertex(0, 10, 0), 0, 1, 0, 100, 0, 0)); _cameras.push_back(Camera(0.0f, 0.0f, 0.0f, Vertex(0.0f, 0.0f, -100.0f))); return true; } void Rasteriser::SetCurrentCamera(int index) { if (index >= 0 && index < _cameras.size()) { _currentCamera = index; } } Camera& Rasteriser::GetCamera(int index) { return _cameras[index]; } Camera& Rasteriser::GetCurrentCamera() { return GetCamera(_currentCamera); } void Rasteriser::Update(const Bitmap& bitmap) { int currentRot = (_rotation % 360); Vertex startPos = Vertex(-50, 0, 0); int currentZOff = 0; int currentModelIndex = 0; for (Model ¤tModel : _sceneModels) { currentModel.EnqueueTransform(GetTranslateMatrix(startPos)); currentModel.EnqueueTransform(GetRotationMatrix(Axis::Y, (float) currentRot)); startPos.SetX(startPos.GetX() + 50); if ((currentModelIndex % 2) == 1) { currentZOff = 0; } else { currentZOff = 100; } startPos.SetZ((float)currentZOff); currentModelIndex++; } _currentAspectRatio = (float)(bitmap.GetWidth() / bitmap.GetHeight()); _currentPerspectiveMatrix = GetPerspectiveProjectionMatrix(1, _currentAspectRatio); _currentViewMatrix = GetViewMatrix(1, bitmap.GetWidth(), bitmap.GetHeight()); if (_rotation == 360) { _rotation = 0; } else { _rotation += 1; } } void Rasteriser::Render(const Bitmap& bitmap) { ClearViewport(bitmap); SelectObject(bitmap.GetDC(), GetStockObject(DC_BRUSH)); SelectObject(bitmap.GetDC(), GetStockObject(DC_PEN)); for (Model ¤tModel : _sceneModels) { currentModel.SetReflectionCoefficient(0.5f, 0.5f, 0.5f); Matrix workingMatrix = workingMatrix.IdentityMatrix(); for (Matrix currentTransform : currentModel.GetPendingTransforms()) { workingMatrix *= currentTransform; } currentModel.ApplyTransformToLocalVertices(workingMatrix); currentModel.CalculateBackfaces(GetCurrentCamera()); for (Polygon3D ¤tPolygon : currentModel.GetPolygons()) { if (!currentPolygon.GetCulled()) { COLORREF colorWorking = RGB(0, 0, 0); for (Light* currentLight : _lights) { colorWorking = currentLight->CalculateLight(currentModel, currentPolygon, colorWorking); } currentPolygon.SetColor(colorWorking); } } currentModel.ApplyTransformToTransformedVertices(GetCurrentCamera().GetCurrentCameraTransformMatrix()); currentModel.Sort(); currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix); currentModel.DehomogenizeAllVertices(); currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix); DrawSolidFlat(bitmap.GetDC(), currentModel); currentModel.ClearPendingTransforms(); } } void Rasteriser::ClearViewport(const Bitmap& bitmap) { bitmap.Clear(RGB(0, 0, 0)); } void Rasteriser::DrawSquare(HDC hDc, const vector verticies) { POINT pointArray[4]; for (int i = 0; i < 4; i++) { pointArray[i].x = (long) verticies[i].GetX(); pointArray[i].y = (long) verticies[i].GetY(); } SetDCBrushColor(hDc, RGB(255, 0, 255)); SetDCPenColor(hDc, RGB(0, 0, 255)); Polygon(hDc, pointArray, 4); } void Rasteriser::DrawShape(HDC hDc, const vector verticies) { vector pointArray; for (int i = 0; i < verticies.size(); i++) { POINT newPoint; newPoint.x = (long)verticies[i].GetX(); newPoint.y = (long)verticies[i].GetY(); pointArray.push_back(newPoint); } SetDCBrushColor(hDc, RGB(rand() % 256, rand() % 256, rand() % 256)); SetDCPenColor(hDc, RGB(rand() % 256, rand() % 256, rand() % 256)); Polygon(hDc, pointArray.data(), (int) verticies.size()); } void Rasteriser::DrawWireFrame(HDC hDc, Model& model) { vector pointArray; vector sizeArray; int unculledPolyCount = 0; int modelPolygonCount = (int) model.GetPolygonCount(); for (int i = 0; i < modelPolygonCount; i++) { if (!model.GetPolygon(i).GetCulled()) { int currentPolygonVertexCount = (int)model.GetPolygon(i).GetPolygonVertexCount(); for (int j = 0; j < currentPolygonVertexCount; j++) { POINT newPoint; newPoint.x = (long)model.GetVertex(i, j).GetX(); newPoint.y = (long)model.GetVertex(i, j).GetY(); pointArray.push_back(newPoint); } sizeArray.push_back(currentPolygonVertexCount); unculledPolyCount++; } } PolyPolygon(hDc, pointArray.data(), sizeArray.data(), unculledPolyCount); } void Rasteriser::DrawSolidFlat(HDC hDc, Model& model) { int modelPolygonCount = (int)model.GetPolygonCount(); for (int i = 0; i < modelPolygonCount; i++) { if (!model.GetPolygon(i).GetCulled()) { vector pointArray; int currentPolygonVertexCount = (int)model.GetPolygon(i).GetPolygonVertexCount(); for (int j = 0; j < currentPolygonVertexCount; j++) { POINT newPoint; newPoint.x = (long)model.GetVertex(i, j).GetX(); newPoint.y = (long)model.GetVertex(i, j).GetY(); pointArray.push_back(newPoint); } SetDCBrushColor(hDc, model.GetPolygon(i).GetColor()); SetDCPenColor(hDc, model.GetPolygon(i).GetColor()); Polygon(hDc, pointArray.data(), currentPolygonVertexCount); } } }