Batman (week 6)

This commit is contained in:
2024-11-10 16:24:57 +01:00
commit 2f55e5b8d6
148 changed files with 188094 additions and 0 deletions

157
project/src/Renderer.cpp Normal file
View File

@@ -0,0 +1,157 @@
//External includes
#include "SDL_surface.h"
//Project includes
#include "Renderer.h"
#include "Maths.h"
using namespace dae;
Renderer::Renderer(SDL_Window *pWindow) : m_pWindow(pWindow) {
//Initialize
SDL_GetWindowSize(pWindow, &m_Width, &m_Height);
//Create Buffers
m_pFrontBuffer = SDL_GetWindowSurface(pWindow);
m_pBackBuffer = SDL_CreateRGBSurface(0, m_Width, m_Height, 32, 0, 0, 0, 0);
m_pBackBufferPixels = (uint32_t *) m_pBackBuffer->pixels;
m_pDepthBufferPixels = new float[m_Width * m_Height];
//Initialize Camera
m_Camera.Initialize(60.f, {.0f, .0f, -10.f});
//Initialize Camera
m_Camera.Initialize(60.f, {.0f, .0f, -10.f});
m_aspectRatio = static_cast<float>(m_Width) / static_cast<float>(m_Height);
}
Renderer::~Renderer() {
delete[] m_pDepthBufferPixels;
}
void Renderer::Update(Timer *pTimer) {
m_Camera.Update(pTimer);
}
void Renderer::Render() {
//@START
//Lock BackBuffer
//Random color
SDL_FillRect(m_pBackBuffer, nullptr, m_ClearColor);
SDL_LockSurface(m_pBackBuffer);
std::fill_n(m_pDepthBufferPixels, m_Width * m_Height, std::numeric_limits<float>::max());
//Clear
SDL_FillRect(m_pBackBuffer, nullptr, m_ClearColor);
ColorRGB finalColor{};
constexpr int numVerticies = 3;
std::vector<Vertex> verticiesScreenSpace{};
VertexTransformationFunction(m_verticiesWorld, verticiesScreenSpace);
const int numTriangles{static_cast<int>(m_verticiesWorld.size()) / numVerticies};
for (int triangleIndex{}; triangleIndex < numTriangles; ++triangleIndex) {
const Vector3 &vertexPos0{verticiesScreenSpace[triangleIndex * numVerticies].position};
const Vector3 &vertexPos1{verticiesScreenSpace[triangleIndex * numVerticies + 1].position};
const Vector3 &vertexPos2{verticiesScreenSpace[triangleIndex * numVerticies + 2].position};
const float minX{std::min(vertexPos0.x, std::min(vertexPos1.x, vertexPos2.x))};
const float minY{std::min(vertexPos0.y, std::min(vertexPos1.y, vertexPos2.y))};
const float maxX{std::max(vertexPos0.x, std::max(vertexPos1.x, vertexPos2.x))};
const float maxY{std::max(vertexPos0.y, std::max(vertexPos1.y, vertexPos2.y))};
const int indexOffset{triangleIndex * numVerticies};
const Vector3 side1{
verticiesScreenSpace[indexOffset + 1].position - verticiesScreenSpace[indexOffset].position};
const Vector3 side2{
verticiesScreenSpace[indexOffset + 2].position - verticiesScreenSpace[indexOffset].position};
const float area{0.5f * Vector3::Cross(side1, side2).z};
const int startX = std::max(0, static_cast<int>(minX));
const int endX = std::min(m_Width - 1, static_cast<int>(maxX));
const int startY = std::max(0, static_cast<int>(minY));
const int endY = std::min(m_Height - 1, static_cast<int>(maxY));
for (int px{startX}; px < endX; ++px) {
for (int py{startY}; py < endY; ++py) {
Vector3 P{px + 0.5f, py + 0.5f, 1};
bool inTriangle{true};
float currDepth{0.0f};
ColorRGB pointColor{};
for (int vertexIndex{0}; vertexIndex < numVerticies; ++vertexIndex) {
const Vertex &nextVert{verticiesScreenSpace[(vertexIndex + 1) % numVerticies + indexOffset]};
const Vector3 &currentVecPos{verticiesScreenSpace[vertexIndex + indexOffset].position};
const Vector3 eVec{nextVert.position - currentVecPos};
const Vector3 pVec{P - currentVecPos};
const float crossResult{Vector3::Cross(eVec, pVec).z};
if (crossResult < 0) {
inTriangle = false;
break;
}
currDepth +=
verticiesScreenSpace[((vertexIndex + 2) % numVerticies + indexOffset)].position.z *
((crossResult * 0.5f) / area);
pointColor += verticiesScreenSpace[((vertexIndex + 2) % numVerticies + indexOffset)].color *
((crossResult * 0.5f) / area);
}
if (!inTriangle) {
continue;
}
const int depthBufferIndex{px + (py * m_Width)};
if (m_pDepthBufferPixels[depthBufferIndex] >= currDepth) {
m_pDepthBufferPixels[depthBufferIndex] = currDepth;
finalColor = pointColor;
finalColor.MaxToOne();
m_pBackBufferPixels[px + (py * m_Width)] = SDL_MapRGB(m_pBackBuffer->format,
static_cast<uint8_t>(finalColor.r * 255),
static_cast<uint8_t>(finalColor.g * 255),
static_cast<uint8_t>(finalColor.b * 255));
}
}
}
}
//RENDER LOGIC
SDL_UnlockSurface(m_pBackBuffer);
SDL_BlitSurface(m_pBackBuffer, nullptr, m_pFrontBuffer, nullptr);
SDL_UpdateWindowSurface(m_pWindow);
}
void Renderer::VertexTransformationFunction(const std::vector<Vertex> &vertices_in,
std::vector<Vertex> &vertices_out) const {
for (const Vertex &vert: vertices_in) {
Vector3 vertPos{m_Camera.invViewMatrix.TransformPoint(vert.position)};
vertPos.x = (vertPos.x / vertPos.z) / (m_aspectRatio * m_Camera.fov);
vertPos.y = (vertPos.y / vertPos.z) / m_Camera.fov;
vertPos.x = (vertPos.x + 1) / 2 * static_cast<float>(m_Width);
vertPos.y = (1 - vertPos.y) / 2 * static_cast<float>(m_Height);
vertices_out.push_back(Vertex{vertPos, vert.color});
}
}
bool Renderer::SaveBufferToImage() const {
return SDL_SaveBMP(m_pBackBuffer, "Rasterizer_ColorBuffer.bmp");
}