Added multithreading and Scene Toggling
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@
|
|||||||
//Project includes
|
//Project includes
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
|
|
||||||
|
#include <execution>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "Maths.h"
|
#include "Maths.h"
|
||||||
@@ -24,7 +25,11 @@ Renderer::Renderer(SDL_Window * pWindow) :
|
|||||||
m_AspectRatio = (m_Width / float(m_Height)) ;
|
m_AspectRatio = (m_Width / float(m_Height)) ;
|
||||||
m_pBufferPixels = static_cast<uint32_t*>(m_pBuffer->pixels);
|
m_pBufferPixels = static_cast<uint32_t*>(m_pBuffer->pixels);
|
||||||
|
|
||||||
|
m_HorizontalIterator.resize(m_Width);
|
||||||
|
m_VerticalIterator.resize(m_Height);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < m_Width; i++) m_HorizontalIterator[i] = i;
|
||||||
|
for (uint32_t i = 0; i < m_Height; i++) m_VerticalIterator[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Render(Scene* pScene) const
|
void Renderer::Render(Scene* pScene) const
|
||||||
@@ -35,16 +40,18 @@ void Renderer::Render(Scene* pScene) const
|
|||||||
|
|
||||||
const Matrix cameraToWorld = camera.CalculateCameraToWorld();
|
const Matrix cameraToWorld = camera.CalculateCameraToWorld();
|
||||||
|
|
||||||
for (int px{}; px < m_Width; ++px)
|
|
||||||
{
|
|
||||||
for (int py{}; py < m_Height; ++py)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
if (m_IsMultiThreadingEnabled)
|
||||||
|
{
|
||||||
|
std::for_each(std::execution::par ,m_HorizontalIterator.begin(), m_HorizontalIterator.end(), [this, camera, cameraToWorld, materials, lights, pScene](uint32_t px)
|
||||||
|
{
|
||||||
|
std::for_each(std::execution::par,m_VerticalIterator.begin(), m_VerticalIterator.end(), [this, px, camera, cameraToWorld, materials, lights, pScene](uint32_t py)
|
||||||
|
{
|
||||||
//Sets screen to black
|
//Sets screen to black
|
||||||
ColorRGB finalColor{ };
|
ColorRGB finalColor{ };
|
||||||
|
|
||||||
//creates a vector that holds a coordinate in 3D space dependent on which pixel the loop is on
|
//creates a vector that holds a coordinate in 3D space dependent on which pixel the loop is on
|
||||||
Vector3 rayDirection{ float((2 * ((px + 0.5) / m_Width) - 1) * m_AspectRatio * camera.FOV),float((1 - 2 * ((py + 0.5) / m_Height)) * camera.FOV),1};
|
Vector3 rayDirection{ float((2 * ((px + 0.5) / m_Width) - 1) * m_AspectRatio * camera.FOV),float((1 - 2 * ((py + 0.5) / m_Height)) * camera.FOV),1 };
|
||||||
rayDirection.Normalize();
|
rayDirection.Normalize();
|
||||||
rayDirection = cameraToWorld.TransformVector(rayDirection);
|
rayDirection = cameraToWorld.TransformVector(rayDirection);
|
||||||
|
|
||||||
@@ -87,7 +94,7 @@ void Renderer::Render(Scene* pScene) const
|
|||||||
|
|
||||||
if (m_CurrentLightingMode == LightingMode::Combined)
|
if (m_CurrentLightingMode == LightingMode::Combined)
|
||||||
{
|
{
|
||||||
ColorRGB ObservedArea = ColorRGB{ observedArea, observedArea,observedArea};
|
ColorRGB ObservedArea = ColorRGB{ observedArea, observedArea,observedArea };
|
||||||
|
|
||||||
ColorRGB Radiance = LightUtils::GetRadiance(lights[idx], closestHit.origin);
|
ColorRGB Radiance = LightUtils::GetRadiance(lights[idx], closestHit.origin);
|
||||||
|
|
||||||
@@ -115,6 +122,90 @@ void Renderer::Render(Scene* pScene) const
|
|||||||
static_cast<uint8_t>(finalColor.r * 255),
|
static_cast<uint8_t>(finalColor.r * 255),
|
||||||
static_cast<uint8_t>(finalColor.g * 255),
|
static_cast<uint8_t>(finalColor.g * 255),
|
||||||
static_cast<uint8_t>(finalColor.b * 255));
|
static_cast<uint8_t>(finalColor.b * 255));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int px{}; px < m_Width; ++px)
|
||||||
|
{
|
||||||
|
for (int py{}; py < m_Height; ++py)
|
||||||
|
{
|
||||||
|
//Sets screen to black
|
||||||
|
ColorRGB finalColor{ };
|
||||||
|
|
||||||
|
//creates a vector that holds a coordinate in 3D space dependent on which pixel the loop is on
|
||||||
|
Vector3 rayDirection{ float((2 * ((px + 0.5) / m_Width) - 1) * m_AspectRatio * camera.FOV),float((1 - 2 * ((py + 0.5) / m_Height)) * camera.FOV),1 };
|
||||||
|
rayDirection.Normalize();
|
||||||
|
rayDirection = cameraToWorld.TransformVector(rayDirection);
|
||||||
|
|
||||||
|
//Creates a Ray from origin to the point where the current pixel in loop is
|
||||||
|
Ray viewRay{ camera.origin,rayDirection };
|
||||||
|
|
||||||
|
HitRecord closestHit{};
|
||||||
|
pScene->GetClosestHit(viewRay, closestHit);
|
||||||
|
|
||||||
|
if (closestHit.didHit)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int idx{ 0 }; idx < lights.size(); idx++)
|
||||||
|
{
|
||||||
|
Vector3 lightVec = LightUtils::GetDirectionToLight(lights[idx], closestHit.origin);
|
||||||
|
float maxRayLenght = lightVec.Normalize();
|
||||||
|
Ray shadowRay(closestHit.origin + closestHit.normal * 0.0001f, lightVec, 0.0001f, maxRayLenght);
|
||||||
|
bool shadowDoesHit = pScene->DoesHit(shadowRay);
|
||||||
|
float observedArea = Vector3::Dot(closestHit.normal, lightVec);
|
||||||
|
|
||||||
|
if (observedArea > 0.f)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!m_ShadowsEnabled or (m_ShadowsEnabled && !shadowDoesHit))
|
||||||
|
{
|
||||||
|
if (m_CurrentLightingMode == LightingMode::ObservedArea)
|
||||||
|
{
|
||||||
|
finalColor += ColorRGB{ observedArea,observedArea,observedArea };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_CurrentLightingMode == LightingMode::Radiance)
|
||||||
|
{
|
||||||
|
finalColor += LightUtils::GetRadiance(lights[idx], closestHit.origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_CurrentLightingMode == LightingMode::BRDF)
|
||||||
|
{
|
||||||
|
finalColor += materials[closestHit.materialIndex]->Shade(closestHit, lightVec, viewRay.direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_CurrentLightingMode == LightingMode::Combined)
|
||||||
|
{
|
||||||
|
ColorRGB ObservedArea = ColorRGB{ observedArea, observedArea,observedArea };
|
||||||
|
|
||||||
|
ColorRGB Radiance = LightUtils::GetRadiance(lights[idx], closestHit.origin);
|
||||||
|
|
||||||
|
ColorRGB BRDF = materials[closestHit.materialIndex]->Shade(closestHit, lightVec, viewRay.direction);
|
||||||
|
|
||||||
|
finalColor += Radiance * BRDF * ObservedArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//const float scaled_t = (closestHit.t - 50.f) / 40.f; //shades spheres based on proximity
|
||||||
|
//finalColor = { scaled_t,scaled_t,scaled_t };
|
||||||
|
|
||||||
|
//const float scaled_t = (closestHit.t) / 500.f; //shades planes based on proximity
|
||||||
|
//finalColor = { scaled_t,scaled_t,scaled_t };
|
||||||
|
}
|
||||||
|
//Update Color in Buffer
|
||||||
|
finalColor.MaxToOne();
|
||||||
|
|
||||||
|
m_pBufferPixels[px + (py * m_Width)] = SDL_MapRGB(m_pBuffer->format,
|
||||||
|
static_cast<uint8_t>(finalColor.r * 255),
|
||||||
|
static_cast<uint8_t>(finalColor.g * 255),
|
||||||
|
static_cast<uint8_t>(finalColor.b * 255));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
struct SDL_Window;
|
struct SDL_Window;
|
||||||
struct SDL_Surface;
|
struct SDL_Surface;
|
||||||
@@ -39,6 +40,8 @@ namespace dae
|
|||||||
|
|
||||||
};
|
};
|
||||||
void ToggleShadows() { m_ShadowsEnabled = !m_ShadowsEnabled; }
|
void ToggleShadows() { m_ShadowsEnabled = !m_ShadowsEnabled; }
|
||||||
|
void ToggleMultiThreading() { m_IsMultiThreadingEnabled = !m_IsMultiThreadingEnabled; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -52,6 +55,7 @@ namespace dae
|
|||||||
|
|
||||||
LightingMode m_CurrentLightingMode{LightingMode::Combined};
|
LightingMode m_CurrentLightingMode{LightingMode::Combined};
|
||||||
bool m_ShadowsEnabled{true};
|
bool m_ShadowsEnabled{true};
|
||||||
|
bool m_IsMultiThreadingEnabled{ true };
|
||||||
SDL_Window* m_pWindow{};
|
SDL_Window* m_pWindow{};
|
||||||
|
|
||||||
SDL_Surface* m_pBuffer{};
|
SDL_Surface* m_pBuffer{};
|
||||||
@@ -60,5 +64,7 @@ namespace dae
|
|||||||
int m_Width{};
|
int m_Width{};
|
||||||
int m_Height{};
|
int m_Height{};
|
||||||
float m_AspectRatio{};
|
float m_AspectRatio{};
|
||||||
|
|
||||||
|
std::vector<uint32_t> m_HorizontalIterator, m_VerticalIterator;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ namespace dae {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Scene_W4::Initialize()
|
void Scene_W4_Bunny::Initialize()
|
||||||
{
|
{
|
||||||
m_Camera.origin = { 0.f, 1.f, -5.f };
|
m_Camera.origin = { 0.f, 1.f, -5.f };
|
||||||
m_Camera.fovAngle = 45.f;
|
m_Camera.fovAngle = 45.f;
|
||||||
@@ -366,7 +366,7 @@ namespace dae {
|
|||||||
|
|
||||||
|
|
||||||
pMesh = AddTriangleMesh(TriangleCullMode::BackFaceCulling, matLambert_White);
|
pMesh = AddTriangleMesh(TriangleCullMode::BackFaceCulling, matLambert_White);
|
||||||
Utils::ParseOBJ("Resources/Warlock.obj",
|
Utils::ParseOBJ("Resources/lowpoly_bunny.obj",
|
||||||
pMesh->positions,
|
pMesh->positions,
|
||||||
pMesh->normals,
|
pMesh->normals,
|
||||||
pMesh->indices);
|
pMesh->indices);
|
||||||
@@ -382,18 +382,18 @@ namespace dae {
|
|||||||
|
|
||||||
//pMesh->CalculateNormals();
|
//pMesh->CalculateNormals();
|
||||||
//pMesh->Translate({ 0.f,1.5f,0.f });
|
//pMesh->Translate({ 0.f,1.5f,0.f });
|
||||||
pMesh->RotateY(90);
|
pMesh->RotateY(60);
|
||||||
pMesh->UpdateTransforms();
|
pMesh->UpdateTransforms();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Light
|
// Light
|
||||||
AddPointLight({ 0.f, 5.f, 5.f }, 50.f, ColorRGB{ 1.f, .61f, .45f }); // Backlight
|
AddPointLight({ 0.f, 5.f, 5.f }, 50.f, ColorRGB{ 1.f, .61f, .45f }); // Backlight
|
||||||
//AddPointLight({ -2.5f, 5.f, -5.f }, 70.f, ColorRGB{ 1.f, .8f, .45f }); // Front Light Left
|
AddPointLight({ -2.5f, 5.f, -5.f }, 70.f, ColorRGB{ 1.f, .8f, .45f }); // Front Light Left
|
||||||
//AddPointLight({ 2.5f, 5.f, -5.f }, 50.f, ColorRGB{ .34f, .47f, .68f }); // Front Light Right
|
AddPointLight({ 2.5f, 5.f, -5.f }, 50.f, ColorRGB{ .34f, .47f, .68f }); // Front Light Right
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene_W4::Update(dae::Timer* pTimer)
|
void Scene_W4_Bunny::Update(dae::Timer* pTimer)
|
||||||
{
|
{
|
||||||
Scene::Update(pTimer);
|
Scene::Update(pTimer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,17 +112,17 @@ namespace dae
|
|||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
//WEEK 4 Test Scene
|
//WEEK 4 Bunny Scene
|
||||||
class Scene_W4 final : public Scene
|
class Scene_W4_Bunny final : public Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Scene_W4() = default;
|
Scene_W4_Bunny() = default;
|
||||||
~Scene_W4() override = default;
|
~Scene_W4_Bunny() override = default;
|
||||||
|
|
||||||
Scene_W4(const Scene_W4&) = delete;
|
Scene_W4_Bunny(const Scene_W4_Bunny&) = delete;
|
||||||
Scene_W4(Scene_W4&&) noexcept = delete;
|
Scene_W4_Bunny(Scene_W4_Bunny&&) noexcept = delete;
|
||||||
Scene_W4& operator=(const Scene_W4&) = delete;
|
Scene_W4_Bunny& operator=(const Scene_W4_Bunny&) = delete;
|
||||||
Scene_W4& operator=(Scene_W4&&) noexcept = delete;
|
Scene_W4_Bunny& operator=(Scene_W4_Bunny&&) noexcept = delete;
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
void Update(dae::Timer* pTimer) override;
|
void Update(dae::Timer* pTimer) override;
|
||||||
@@ -132,7 +132,7 @@ namespace dae
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//WEEK 4 Test Scene
|
//WEEK 4 Reference Scene
|
||||||
class Scene_W4_ReferenceScene final : public Scene
|
class Scene_W4_ReferenceScene final : public Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ int main(int argc, char* args[])
|
|||||||
const auto pRenderer = new Renderer(pWindow);
|
const auto pRenderer = new Renderer(pWindow);
|
||||||
|
|
||||||
const auto pScene = new Scene_W4_ReferenceScene();
|
const auto pScene = new Scene_W4_ReferenceScene();
|
||||||
|
const auto pScene2 = new Scene_W4_Bunny();
|
||||||
pScene->Initialize();
|
pScene->Initialize();
|
||||||
|
pScene2->Initialize();
|
||||||
|
|
||||||
|
|
||||||
//Start loop
|
//Start loop
|
||||||
@@ -60,6 +62,7 @@ int main(int argc, char* args[])
|
|||||||
float printTimer = 0.f;
|
float printTimer = 0.f;
|
||||||
bool isLooping = true;
|
bool isLooping = true;
|
||||||
bool takeScreenshot = false;
|
bool takeScreenshot = false;
|
||||||
|
bool isBunnyScene = false;
|
||||||
while (isLooping)
|
while (isLooping)
|
||||||
{
|
{
|
||||||
//--------- Get input events ---------
|
//--------- Get input events ---------
|
||||||
@@ -82,6 +85,14 @@ int main(int argc, char* args[])
|
|||||||
{
|
{
|
||||||
pRenderer->CycleLightingMode();
|
pRenderer->CycleLightingMode();
|
||||||
}
|
}
|
||||||
|
if (e.key.keysym.scancode == SDL_SCANCODE_F4)
|
||||||
|
{
|
||||||
|
pRenderer->ToggleMultiThreading();
|
||||||
|
}
|
||||||
|
if (e.key.keysym.scancode == SDL_SCANCODE_F5)
|
||||||
|
{
|
||||||
|
isBunnyScene = !isBunnyScene;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,10 +102,26 @@ int main(int argc, char* args[])
|
|||||||
|
|
||||||
|
|
||||||
//--------- Update ---------
|
//--------- Update ---------
|
||||||
|
if (isBunnyScene)
|
||||||
|
{
|
||||||
|
pScene2->Update(pTimer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
pScene->Update(pTimer);
|
pScene->Update(pTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------- Render ---------
|
//--------- Render ---------
|
||||||
|
if (isBunnyScene)
|
||||||
|
{
|
||||||
|
pRenderer->Render(pScene2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
pRenderer->Render(pScene);
|
pRenderer->Render(pScene);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------- Timer ---------
|
//--------- Timer ---------
|
||||||
pTimer->Update();
|
pTimer->Update();
|
||||||
@@ -119,6 +146,7 @@ int main(int argc, char* args[])
|
|||||||
|
|
||||||
//Shutdown "framework"
|
//Shutdown "framework"
|
||||||
delete pScene;
|
delete pScene;
|
||||||
|
delete pScene2;
|
||||||
delete pRenderer;
|
delete pRenderer;
|
||||||
delete pTimer;
|
delete pTimer;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user