Explicit threadpooling and framebuffers
This commit is contained in:
@@ -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"
|
||||
|
||||
28
CMakeSettings.json
Normal file
28
CMakeSettings.json
Normal file
@@ -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": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,11 +21,11 @@ Acceleration::Acceleration(AccelerationMode mode) {
|
||||
void Acceleration::Construct(std::vector<Triangle*> 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<Triangle*> 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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class Mesh {
|
||||
public:
|
||||
Mesh(std::vector<Triangle*> 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;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#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<float>(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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
uint32_t* Framebuffer;
|
||||
FrameBuffer* 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;
|
||||
|
||||
|
||||
54
src/display/framebuffer.cpp
Normal file
54
src/display/framebuffer.cpp
Normal file
@@ -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);
|
||||
}
|
||||
30
src/display/framebuffer.hpp
Normal file
30
src/display/framebuffer.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef INFERNO_DISPLAY_FRAMEBUFFER_H_
|
||||
#define INFERNO_DISPLAY_FRAMEBUFFER_H_
|
||||
|
||||
#include "../common.hpp"
|
||||
#include "../maths.hpp"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
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
|
||||
@@ -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
|
||||
Ready = true;
|
||||
m_threadPool->Ready = true;
|
||||
while (m_interface->Active) {
|
||||
Ready = true;
|
||||
|
||||
// TODO: Queue frame jobs properly
|
||||
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() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef INFERNO_ENGINE_PROGRESSIVERENDERER_H_
|
||||
#define INFERNO_ENGINE_PROGRESSIVERENDERER_H_
|
||||
|
||||
#include "../common.hpp"
|
||||
#include "../maths.hpp"
|
||||
|
||||
#include <sstream>
|
||||
@@ -9,6 +10,7 @@
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
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<std::thread*> m_workers;
|
||||
std::vector<bool> 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
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
92
src/util/threadpool.cpp
Normal file
92
src/util/threadpool.cpp
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
src/util/threadpool.hpp
Normal file
37
src/util/threadpool.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef INFERNO_UTIL_THREADPOOL_H_
|
||||
#define INFERNO_UTIL_THREADPOOL_H_
|
||||
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
class ProgressiveRenderer;
|
||||
class FrameBuffer;
|
||||
|
||||
class ThreadPool {
|
||||
public:
|
||||
bool Ready = false;
|
||||
std::vector<std::thread*> Pool;
|
||||
std::vector<bool> 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<FrameBuffer*> ThreadFrameBuffers;
|
||||
};
|
||||
|
||||
void workerThread(RenderThreadPool* threadpool, ProgressiveRenderer* renderer, int idd, int yStart, int yRange);
|
||||
|
||||
#endif
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user