From ac331d071b8633a1c3acc04fc6c729e9bf9717c8 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 28 Aug 2019 23:44:46 +0100 Subject: [PATCH] Explicit threadpooling and framebuffers --- CMakeLists.txt | 10 ++-- CMakeSettings.json | 28 +++++++++ src/acceleration/accel.cpp | 12 ++-- src/common.hpp | 20 ++++--- src/core/renderer.cpp | 10 ++-- src/core/renderer.hpp | 8 +-- src/definitions/primatives/mesh.hpp | 2 +- src/display/display.cpp | 70 ++-------------------- src/display/display.hpp | 10 ---- src/display/displayinterface.hpp | 14 +---- src/display/framebuffer.cpp | 54 +++++++++++++++++ src/display/framebuffer.hpp | 30 ++++++++++ src/engine/progressiverenderer.cpp | 75 +++++------------------ src/engine/progressiverenderer.hpp | 13 ++-- src/engine/renderengine.cpp | 9 ++- src/engine/renderengine.hpp | 8 ++- src/inferno.hpp | 2 +- src/util/threadpool.cpp | 92 +++++++++++++++++++++++++++++ src/util/threadpool.hpp | 37 ++++++++++++ test/main.cpp | 2 +- 20 files changed, 320 insertions(+), 186 deletions(-) create mode 100644 CMakeSettings.json create mode 100644 src/display/framebuffer.cpp create mode 100644 src/display/framebuffer.hpp create mode 100644 src/util/threadpool.cpp create mode 100644 src/util/threadpool.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 56c6e50..6769b8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,8 @@ project(Inferno) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} CMakeModules/) cmake_policy(SET CMP0037 OLD) -set(CMAKE_BUILD_TYPE Debug) -SET(CMAKE_CXX_FLAGS "-g") +#set(CMAKE_BUILD_TYPE Debug) +#set(CMAKE_CXX_FLAGS "-g") set(executable output) set(SrcDIR ./src) @@ -21,9 +21,9 @@ if (UNIX) endif(UNIX) if (WIN32) - SET(CMAKE_CXX_FLAGS "-IC:/dev/SDL2/include/ -LC:/dev/SDL2/lib/x64/") - #SET(CMAKE_CXX_FLAGS "-IC:/dev/SDL2_image/include/ -LC:/dev/SDL2_image/lib/x64/") - SET(CMAKE_CXX_FLAGS "-IC:/dev/glm") + set(CMAKE_CXX_FLAGS "-IC:/dev/SDL2/include/ -LC:/dev/SDL2/lib/x64/") + #set(CMAKE_CXX_FLAGS "-IC:/dev/SDL2_image/include/ -LC:/dev/SDL2_image/lib/x64/") + set(CMAKE_CXX_FLAGS "-IC:/dev/glm") include_directories(${executable} "C:/dev/glm" diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 0000000..cdc79fe --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,28 @@ +{ + "configurations": [ + { + "name": "x64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "-v", + "ctestCommandArgs": "", + "variables": [] + }, + { + "name": "x64-Release", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "-v", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64_x64" ], + "variables": [] + } + ] +} \ No newline at end of file diff --git a/src/acceleration/accel.cpp b/src/acceleration/accel.cpp index da34a52..64da596 100644 --- a/src/acceleration/accel.cpp +++ b/src/acceleration/accel.cpp @@ -21,11 +21,11 @@ Acceleration::Acceleration(AccelerationMode mode) { void Acceleration::Construct(std::vector triangles) { switch (m_mode) { case MODE_ACCELERATION_DEFAULT: - case MODE_NONE: + case MODE_ACCELERATION_NONE: Constructed = false; break; - case MODE_KD: + case MODE_ACCELERATION_KD: m_bbox = new BBox; m_bbox->MakeEmpty(); @@ -41,7 +41,7 @@ void Acceleration::Construct(std::vector triangles) { Constructed = true; break; - case MODE_KD_SLOW: + case MODE_ACCELERATION_KD_SLOW: BuildKDTreeSlow(m_kdtreeslow, triangles); Constructed = true; break; @@ -56,14 +56,14 @@ bool Acceleration::Intersect(Ray ray, Triangle*& triMin, float& tMin) { if (!Constructed) return false; switch (m_mode) { case MODE_ACCELERATION_DEFAULT: - case MODE_NONE: + case MODE_ACCELERATION_NONE: break; - case MODE_KD: + case MODE_ACCELERATION_KD: return KDIntersect(m_kdtree, *m_bbox, ray, triMin, tMin); break; - case MODE_KD_SLOW: + case MODE_ACCELERATION_KD_SLOW: return KDIntersectSlow(m_kdtreeslow, &ray, triMin, tMin); break; diff --git a/src/common.hpp b/src/common.hpp index 5d974a4..4d3c902 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -15,17 +15,23 @@ enum OperationMode { MODE_OPERATION_DEFAULT, - MODE_PROGRESSIVE_GUI, - MODE_PROGRESSIVE_IMG, - MODE_SAMPLES_IMG + MODE_OPERATION_PROGRESSIVE_GUI, + MODE_OPERATION_PROGRESSIVE_IMG, + MODE_OPERATION_SAMPLES_IMG +}; + +enum RenderMode { + MODE_RENDER_DEFAULT, + MODE_RENDER_PATHTRACE, + MODE_RENDER_NORMALS }; enum AccelerationMode { MODE_ACCELERATION_DEFAULT, - MODE_NONE, - MODE_KD, - MODE_KD_SLOW, - MODE_BVH + MODE_ACCELERATION_NONE, + MODE_ACCELERATION_KD, + MODE_ACCELERATION_KD_SLOW, + MODE_ACCELERATION_BVH }; #endif diff --git a/src/core/renderer.cpp b/src/core/renderer.cpp index 4612cae..50dc772 100644 --- a/src/core/renderer.cpp +++ b/src/core/renderer.cpp @@ -33,21 +33,21 @@ void Renderer::InitRender(Scene* scene) { void Renderer::Render() { if (!RendererInitialized) return; - if (m_mode == MODE_PROGRESSIVE_GUI || m_mode == MODE_PROGRESSIVE_IMG) { + if (m_mode == MODE_OPERATION_PROGRESSIVE_GUI || m_mode == MODE_OPERATION_PROGRESSIVE_IMG) { RenderProgressive(); - } else if (m_mode == MODE_SAMPLES_IMG) { + } else if (m_mode == MODE_OPERATION_SAMPLES_IMG) { RenderSamples(); } else { // Add an error & return } } -void Renderer::Render(uint32_t* framebuffer) { +void Renderer::Render(FrameBuffer* framebuffer) { if (!RendererInitialized) return; m_framebuffer = framebuffer; - if (m_mode == MODE_PROGRESSIVE_GUI || m_mode == MODE_PROGRESSIVE_IMG) { + if (m_mode == MODE_OPERATION_PROGRESSIVE_GUI || m_mode == MODE_OPERATION_PROGRESSIVE_IMG) { RenderProgressive(); - } else if (m_mode == MODE_SAMPLES_IMG) { + } else if (m_mode == MODE_OPERATION_SAMPLES_IMG) { RenderSamples(); } else { // Add an error & return diff --git a/src/core/renderer.hpp b/src/core/renderer.hpp index caa9197..99a3d0a 100644 --- a/src/core/renderer.hpp +++ b/src/core/renderer.hpp @@ -3,9 +3,9 @@ #include "../common.hpp" -class DisplayInterface; - class ProgressiveRenderer; +class DisplayInterface; +class FrameBuffer; class Scene; @@ -24,14 +24,14 @@ public: bool RendererInitialized = false; void Render(); - void Render(uint32_t* framebuffer); + void Render(FrameBuffer* framebuffer); private: int m_samples = -1; OperationMode m_mode = MODE_OPERATION_DEFAULT; DisplayInterface* m_interface = nullptr; - uint32_t* m_framebuffer = nullptr; + FrameBuffer* m_framebuffer = nullptr; Scene* m_scene = nullptr; diff --git a/src/definitions/primatives/mesh.hpp b/src/definitions/primatives/mesh.hpp index 6b30888..e79369a 100644 --- a/src/definitions/primatives/mesh.hpp +++ b/src/definitions/primatives/mesh.hpp @@ -15,7 +15,7 @@ class Mesh { public: Mesh(std::vector triangles); - void Optimise(AccelerationMode mode = MODE_KD_SLOW); + void Optimise(AccelerationMode mode = MODE_ACCELERATION_KD_SLOW); bool Intersect(Ray ray, Triangle*& intersect, float& t); bool Optimised = false; diff --git a/src/display/display.cpp b/src/display/display.cpp index ce286de..6afb578 100644 --- a/src/display/display.cpp +++ b/src/display/display.cpp @@ -2,6 +2,7 @@ #include +#include "../display/framebuffer.hpp" #include "../common.hpp" #include "../pixel.hpp" @@ -20,7 +21,7 @@ bool Display::InitVideoDisplay(std::string title, int x, int y) { m_window = SDL_CreateWindow( title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - this->XRes * this->Scale, this->YRes * this->Scale, + this->XRes, this->YRes, SDL_WINDOW_ALLOW_HIGHDPI ); @@ -53,9 +54,8 @@ bool Display::InitVideoDisplay(std::string title, int x, int y) { return false; } - Framebuffer = (uint32_t*)malloc(this->XRes * this->YRes * sizeof(uint32_t)); - memset((void*)Framebuffer, 0, this->XRes * this->YRes * sizeof(uint32_t)); - if (!Framebuffer) { + Framebuffer = new FrameBuffer(this->XRes, this->YRes); + if (!Framebuffer) { // Add error std::cout << "ERROR: COULD NOT ALLOCATE FRAMEBUFFER" << std::endl; return false; @@ -75,63 +75,6 @@ bool Display::InitImGui() { return true; } -void Display::SetPixel(int x, int y, Pixel p) { - m_framebufferMutex.lock(); - Framebuffer[y * this->XRes + x] = p.rgb(); - m_framebufferMutex.unlock(); -} - -void Display::SetPixel(int x, int y, uint32_t p) { - m_framebufferMutex.lock(); - Framebuffer[y * this->XRes + x] = p; - m_framebufferMutex.unlock(); -} - -void Display::SetPixel(int x, int y, glm::vec3 p) { - Pixel pixel{ (uint8_t)p.r, (uint8_t)p.g, (uint8_t)p.b }; - m_framebufferMutex.lock(); - Framebuffer[y * this->XRes + x] = pixel.rgb(); - m_framebufferMutex.unlock(); -} - -void Display::SetPixelSafe(int x, int y, Pixel p) { - if (x >= 0 && x < this->XRes && y >= 0 && this->YRes) { - m_framebufferMutex.lock(); - Framebuffer[y * this->XRes + x] = p.rgb(); - m_framebufferMutex.unlock(); - } -} - -void Display::SetPixelSafe(int x, int y, uint32_t p) { - if (x >= 0 && x < this->XRes && y >= 0 && this->YRes) { - m_framebufferMutex.lock(); - Framebuffer[y * this->XRes + x] = p; - m_framebufferMutex.unlock(); - } -} - -void Display::SetPixelSafe(int x, int y, glm::vec3 p) { - if (x >= 0 && x < this->XRes && y >= 0 && this->YRes) { - Pixel pixel{ (uint8_t)p.r, (uint8_t)p.g, (uint8_t)p.b }; - m_framebufferMutex.lock(); - Framebuffer[y * this->XRes + x] = pixel.rgb(); - m_framebufferMutex.unlock(); - } -} - -void Display::SetFramebuffer(uint32_t* fb) { - m_framebufferMutex.lock(); - Framebuffer = nullptr; - Framebuffer = fb; - m_framebufferMutex.unlock(); -} - -void Display::ClearFramebuffer() { - m_framebufferMutex.lock(); - memset((void*)Framebuffer, 0, (XRes * YRes) * sizeof(uint32_t)); - m_framebufferMutex.unlock(); -} - void Display::Update() { ImGuiIO& io = ImGui::GetIO(); int mouseX, mouseY, wheel = 0; @@ -142,7 +85,7 @@ void Display::Update() { io.MouseDown[1] = buttons & SDL_BUTTON(SDL_BUTTON_RIGHT); io.MouseWheel = static_cast(wheel); - SDL_UpdateTexture(m_texture, NULL, Framebuffer, this->XRes * sizeof(uint32_t)); + SDL_UpdateTexture(m_texture, NULL, Framebuffer->Data, this->XRes * sizeof(uint32_t)); SDL_RenderCopy(m_renderer, m_texture, NULL, NULL); ImGui::Render(); @@ -152,7 +95,7 @@ void Display::Update() { } void Display::UpdatePartial() { - SDL_UpdateTexture(m_texture, NULL, Framebuffer, this->XRes * sizeof(uint32_t)); + SDL_UpdateTexture(m_texture, NULL, Framebuffer->Data, this->XRes * sizeof(uint32_t)); SDL_RenderCopy(m_renderer, m_texture, NULL, NULL); SDL_RenderPresent(m_renderer); } @@ -173,7 +116,6 @@ void Display::Close() { SDL_DestroyRenderer(m_renderer); SDL_DestroyWindow(m_window); SDL_Quit(); - free(Framebuffer); } Display::~Display() { diff --git a/src/display/display.hpp b/src/display/display.hpp index 28368c5..d811099 100644 --- a/src/display/display.hpp +++ b/src/display/display.hpp @@ -18,16 +18,6 @@ public: bool InitVideoDisplay(std::string title, int x, int y); bool InitImGui(); - void SetPixel(int x, int y, Pixel p) override; - void SetPixel(int x, int y, uint32_t p) override; - void SetPixel(int x, int y, glm::vec3 p) override; - void SetPixelSafe(int x, int y, Pixel p) override; - void SetPixelSafe(int x, int y, glm::vec3 p) override; - void SetPixelSafe(int x, int y, uint32_t p) override; - - void SetFramebuffer(uint32_t* fb) override; - void ClearFramebuffer() override; - void Update() override; void UpdatePartial() override; void UpdateTitle(std::string title) override; diff --git a/src/display/displayinterface.hpp b/src/display/displayinterface.hpp index 9246e44..9fc6e00 100644 --- a/src/display/displayinterface.hpp +++ b/src/display/displayinterface.hpp @@ -4,6 +4,7 @@ #include "../common.hpp" #include "../maths.hpp" +class FrameBuffer; class Pixel; class DisplayInterface { @@ -14,21 +15,10 @@ public: bool ImGui = false; int XRes, YRes; std::string Title; - unsigned int Scale = 1; + FrameBuffer* Framebuffer; - uint32_t* Framebuffer; - virtual bool Init() = 0; - virtual void SetPixel(int x, int y, Pixel p) = 0; - virtual void SetPixel(int x, int y, uint32_t p) = 0; - virtual void SetPixel(int x, int y, glm::vec3 p) = 0; - virtual void SetPixelSafe(int x, int y, Pixel p) = 0; - virtual void SetPixelSafe(int x, int y, uint32_t p) = 0; - virtual void SetPixelSafe(int x, int y, glm::vec3 p) = 0; - - virtual void SetFramebuffer(uint32_t* fb) = 0; - virtual void ClearFramebuffer() = 0; virtual void UpdateTitle(std::string title) = 0; virtual void UpdateTitle() = 0; diff --git a/src/display/framebuffer.cpp b/src/display/framebuffer.cpp new file mode 100644 index 0000000..d2f67bd --- /dev/null +++ b/src/display/framebuffer.cpp @@ -0,0 +1,54 @@ +#include "framebuffer.hpp" + +#include "../pixel.hpp" + +FrameBuffer::FrameBuffer(int xres, int yres) { + XRes = xres; YRes = yres; + Data = (uint32_t*)malloc((xres * yres) * sizeof(uint32_t)); + memset((void*)Data, 0, (xres * yres) * sizeof(uint32_t)); +} + +void FrameBuffer::SetPixel(int x, int y, Pixel p) { + Data[y * this->XRes + x] = p.rgb(); +} + +void FrameBuffer::SetPixel(int x, int y, uint32_t p) { + Data[y * this->XRes + x] = p; +} + +void FrameBuffer::SetPixel(int x, int y, glm::vec3 p) { + Pixel pixel{ (uint8_t)p.r, (uint8_t)p.g, (uint8_t)p.b }; + Data[y * this->XRes + x] = pixel.rgb(); +} + +void FrameBuffer::SetPixelSafe(int x, int y, Pixel p) { + if (x >= 0 && x < this->XRes && y >= 0 && this->YRes) { + Data[y * this->XRes + x] = p.rgb(); + } +} + +void FrameBuffer::SetPixelSafe(int x, int y, uint32_t p) { + if (x >= 0 && x < this->XRes && y >= 0 && this->YRes) { + Data[y * this->XRes + x] = p; + } +} + +void FrameBuffer::SetPixelSafe(int x, int y, glm::vec3 p) { + if (x >= 0 && x < this->XRes && y >= 0 && this->YRes) { + Pixel pixel{ (uint8_t)p.r, (uint8_t)p.g, (uint8_t)p.b }; + Data[y * this->XRes + x] = pixel.rgb(); + } +} + +void FrameBuffer::SetFramebuffer(uint32_t* fb) { + free(Data); + Data = fb; +} + +void FrameBuffer::ClearFramebuffer() { + memset((void*)Data, 0, (XRes * YRes) * sizeof(uint32_t)); +} + +FrameBuffer::~FrameBuffer() { + free(Data); +} diff --git a/src/display/framebuffer.hpp b/src/display/framebuffer.hpp new file mode 100644 index 0000000..dd28ec7 --- /dev/null +++ b/src/display/framebuffer.hpp @@ -0,0 +1,30 @@ +#ifndef INFERNO_DISPLAY_FRAMEBUFFER_H_ +#define INFERNO_DISPLAY_FRAMEBUFFER_H_ + +#include "../common.hpp" +#include "../maths.hpp" + +#include + +class Pixel; + +class FrameBuffer { +public: + FrameBuffer(int xres, int yres); + + void SetPixel(int x, int y, Pixel p); + void SetPixel(int x, int y, uint32_t p); + void SetPixel(int x, int y, glm::vec3 p); + void SetPixelSafe(int x, int y, Pixel p); + void SetPixelSafe(int x, int y, glm::vec3); + void SetPixelSafe(int x, int y, uint32_t p); + + void SetFramebuffer(uint32_t* fb); + void ClearFramebuffer(); + uint32_t* Data; + int XRes, YRes; + + ~FrameBuffer(); +}; + +#endif diff --git a/src/engine/progressiverenderer.cpp b/src/engine/progressiverenderer.cpp index 8da979a..fa06006 100644 --- a/src/engine/progressiverenderer.cpp +++ b/src/engine/progressiverenderer.cpp @@ -7,6 +7,7 @@ #include "../display/displayinterface.hpp" #include "../util/assetloader.hpp" +#include "../util/threadpool.hpp" #include "../definitions/primatives/primative.hpp" #include "../definitions/camera.hpp" @@ -18,7 +19,9 @@ ProgressiveRenderer::ProgressiveRenderer() { } void ProgressiveRenderer::Init(DisplayInterface* interface, Scene* scene) { + m_threadPool = new RenderThreadPool(); m_engine = new RenderEngine(); + m_engine->Mode = MODE_RENDER_PATHTRACE; m_engine->SetScene(scene); m_interface = interface; m_scene = scene; @@ -33,76 +36,30 @@ void ProgressiveRenderer::Input() { ImGui::NewFrame(); ImGui::Begin("Debug"); + ImGui::Checkbox("Render Normals", &m_normals); + if (m_normals) { + m_engine->Mode = MODE_RENDER_NORMALS; + } else { + m_engine->Mode = MODE_RENDER_PATHTRACE; + } ImGui::End(); } -void workerThread(ProgressiveRenderer* renderer, int idd, int yStart, int yRange) { - while (!renderer->Ready) { - std::chrono::milliseconds dura(10); - std::this_thread::sleep_for(dura); - } - - while (renderer->Ready) { - for (int y = yStart; y < yStart + yRange; y++) - for (int x = 0; x < renderer->m_scene->w; x++) { - Ray ray = renderer->m_scene->camera->CastRay(x, y); - glm::vec3 col = renderer->m_engine->GetColour(ray, 0); - renderer->m_interface->SetPixelSafe(x, y, col); - } - } -} - void ProgressiveRenderer::Render() { + m_threadPool->SetJobs(this, m_scene->w, m_scene->h); - /* - New design is needed - as follows is pretty - good - - class threadpool { - vector thread* threads - vector bool status - vector uint32 buffers - void merge() - } - - maybe - - class thread { - framebuffer - } - */ - - // Allocates threads with ranges to render - for (int i = 0; i < m_workerMax; i++) { - if (i == m_workerMax - 1) { - m_workers.push_back(new std::thread(workerThread, this, i, - (m_scene->h / m_workerMax) * i, - -((m_scene->h / m_workerMax) * i - m_scene->h) - )); - } else { - m_workers.push_back(new std::thread(workerThread, this, i, - (m_scene->h / m_workerMax) * i, - (m_scene->h / m_workerMax) * (i + 1) - (m_scene->h / m_workerMax) * i - )); - } - } - - int lastTime = SDL_GetTicks(); // Starts render loop - while (m_interface->Active) { - Ready = true; - - // TODO: Queue frame jobs properly - + Ready = true; + m_threadPool->Ready = true; + while (m_interface->Active) { + if (m_threadPool->CheckAllJobs()) m_threadPool->RunJobsAgain(); + Input(); m_interface->Update(); } Ready = false; - for (auto& thread : m_workers) { - thread->join(); - } + m_threadPool->Destroy(); } void ProgressiveRenderer::RenderProgressive() { diff --git a/src/engine/progressiverenderer.hpp b/src/engine/progressiverenderer.hpp index 91195ec..d9c516a 100644 --- a/src/engine/progressiverenderer.hpp +++ b/src/engine/progressiverenderer.hpp @@ -1,6 +1,7 @@ #ifndef INFERNO_ENGINE_PROGRESSIVERENDERER_H_ #define INFERNO_ENGINE_PROGRESSIVERENDERER_H_ +#include "../common.hpp" #include "../maths.hpp" #include @@ -9,6 +10,7 @@ #include #include +class RenderThreadPool; class DisplayInterface; class RenderEngine; class Scene; @@ -26,21 +28,16 @@ public: bool Ready = false; - bool MXAA = true; public: - Scene* m_scene = nullptr; + RenderThreadPool* m_threadPool = nullptr; DisplayInterface* m_interface = nullptr; RenderEngine* m_engine = nullptr; + Scene* m_scene = nullptr; - int m_workerMax = 6; - std::vector m_workers; - std::vector m_workerStatus; private: std::mutex m_mutex; - char* buf = ""; float f = 0.0f; + bool m_normals = true; }; -void workerThread(ProgressiveRenderer* renderer, int idd, int yStart, int yRange); - #endif diff --git a/src/engine/renderengine.cpp b/src/engine/renderengine.cpp index d81ef34..b1289d6 100644 --- a/src/engine/renderengine.cpp +++ b/src/engine/renderengine.cpp @@ -15,7 +15,7 @@ void RenderEngine::SetScene(Scene* scene) { } glm::vec3 RenderEngine::GetColour(Ray ray, int depth) { - + float t; Primative* hit = nullptr; bool didhit = TraceRayScene(ray, m_scene, t, hit); if (!didhit) { @@ -24,7 +24,12 @@ glm::vec3 RenderEngine::GetColour(Ray ray, int depth) { glm::vec3 hitPoint = ray.origin + ray.direction * t; - glm::vec3 normal = hit->SurfaceNormal(hitPoint); + if (Mode == MODE_RENDER_NORMALS) { return GetNormalColour(hit, hitPoint); } else { } + return { 1.0f, 1.0f, 1.0f }; +} + +glm::vec3 RenderEngine::GetNormalColour(Primative* hit, glm::vec3 hitPoint) { + glm::vec3 normal = hit->SurfaceNormal(hitPoint); return { (normal.x + 1.0f) * 127.5f, (normal.y + 1.0f) * 127.5f, (normal.z + 1.0f) * 127.5f }; } diff --git a/src/engine/renderengine.hpp b/src/engine/renderengine.hpp index 66ab370..73c4b7f 100644 --- a/src/engine/renderengine.hpp +++ b/src/engine/renderengine.hpp @@ -1,8 +1,10 @@ #ifndef INFERNO_ENGINE_RENDERENGINE_H_ #define INFERNO_ENGINE_RENDERENGINE_H_ +#include "../common.hpp" #include "../maths.hpp" +class Primative; class Scene; class Ray; @@ -11,9 +13,13 @@ public: RenderEngine(); void SetScene(Scene* scene); - glm::vec3 GetColour(Ray ray, int depth); + + RenderMode Mode = MODE_RENDER_NORMALS; + private: + glm::vec3 GetNormalColour(Primative* hit, glm::vec3 hitPoint); + Scene* m_scene = nullptr; }; diff --git a/src/inferno.hpp b/src/inferno.hpp index b04dc78..f772dc9 100644 --- a/src/inferno.hpp +++ b/src/inferno.hpp @@ -53,7 +53,7 @@ public: virtual ~InfernoEngine(); private: - OperationMode m_mode = MODE_PROGRESSIVE_GUI; + OperationMode m_mode = MODE_OPERATION_PROGRESSIVE_GUI; // Initialized flag - core engine features can't // be changed while this flag is set to true diff --git a/src/util/threadpool.cpp b/src/util/threadpool.cpp new file mode 100644 index 0000000..2026af6 --- /dev/null +++ b/src/util/threadpool.cpp @@ -0,0 +1,92 @@ +#include "threadpool.hpp" + +#include "../definitions/ray.hpp" +#include "../definitions/scene.hpp" +#include "../definitions/camera.hpp" + +#include "../display/displayinterface.hpp" +#include "../display/framebuffer.hpp" + +#include "../engine/renderengine.hpp" +#include "../engine/progressiverenderer.hpp" + +RenderThreadPool::RenderThreadPool() { + for (int i = 0; i < ThreadCount; i++) { + ThreadStatus.push_back(false); + } +}; + +void RenderThreadPool::SetJobs(ProgressiveRenderer* renderer, int x, int y) { + for (int i = 0; i < ThreadCount; i++) { + if (i == ThreadCount - 1) { + Pool.push_back(new std::thread(workerThread, this, renderer, i, + (x / ThreadCount) * i, + -((x / ThreadCount) * i - x) + )); + } + else { + Pool.push_back(new std::thread(workerThread, this, renderer, i, + (y / ThreadCount) * i, + (y / ThreadCount) * (i + 1) - (y / ThreadCount) * i + )); + } + } +} + +void RenderThreadPool::BeginJobs() { + Ready = true; +} + +bool RenderThreadPool::CheckAllJobs() { + bool ret = false; + + bool last = ThreadStatus[0]; + for (int i = 1; i < ThreadCount; i++) { + if (ThreadStatus[i] != last) return false; + ThreadStatus[i] = last; + } + + return last; +} + +void RenderThreadPool::RunJobsAgain() { + ThreadLock.lock(); + for (int i = 0; i < ThreadCount; i++) { + ThreadStatus[i] = false; + } + ThreadLock.unlock(); +} + +void RenderThreadPool::MergeBuffers(uint32_t* Framebuffer) { + +} + +void RenderThreadPool::Destroy() { + +} + +void workerThread(RenderThreadPool* threadpool, ProgressiveRenderer* renderer, int idd, int yStart, int yRange) { + while (!renderer->Ready && !threadpool->Ready) { + std::chrono::milliseconds dura(10); + std::this_thread::sleep_for(dura); + } + + while (renderer->Ready && threadpool->Ready) { + + for (int y = yStart; y < yStart + yRange; y++) + for (int x = 0; x < renderer->m_scene->w; x++) { + Ray ray = renderer->m_scene->camera->CastRay(x, y); + glm::vec3 col = renderer->m_engine->GetColour(ray, 0); + renderer->m_interface->Framebuffer->SetPixelSafe(x, y, col); + } + + threadpool->ThreadLock.lock(); + threadpool->ThreadStatus[idd] = true; + threadpool->ThreadLock.unlock(); + + while (threadpool->ThreadStatus[idd]) { + std::chrono::milliseconds dura(1); + std::this_thread::sleep_for(dura); + } + } +} diff --git a/src/util/threadpool.hpp b/src/util/threadpool.hpp new file mode 100644 index 0000000..adfd05d --- /dev/null +++ b/src/util/threadpool.hpp @@ -0,0 +1,37 @@ +#ifndef INFERNO_UTIL_THREADPOOL_H_ +#define INFERNO_UTIL_THREADPOOL_H_ + +#include +#include +#include + +class ProgressiveRenderer; +class FrameBuffer; + +class ThreadPool { +public: + bool Ready = false; + std::vector Pool; + std::vector ThreadStatus; // false = not done, true = done + std::mutex ThreadLock; + int ThreadCount = 6; +}; + +class RenderThreadPool : public ThreadPool { +public: + RenderThreadPool(); + + void SetJobs(ProgressiveRenderer* renderer, int x, int y); + void BeginJobs(); + bool CheckAllJobs(); // false = not ready, true = ready + void RunJobsAgain(); + void Destroy(); + + void MergeBuffers(uint32_t* Framebuffer); + + std::vector ThreadFrameBuffers; +}; + +void workerThread(RenderThreadPool* threadpool, ProgressiveRenderer* renderer, int idd, int yStart, int yRange); + +#endif diff --git a/test/main.cpp b/test/main.cpp index dfd3e85..8cc7da2 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -7,7 +7,7 @@ static const int height = 600; int main(int argc, char** argv) { InfernoEngine inferno; - inferno.SetMode(MODE_PROGRESSIVE_GUI); + inferno.SetMode(MODE_OPERATION_PROGRESSIVE_GUI); bool status = inferno.InitWindow(width, height); if (!status) {