diff --git a/src/definitions/scene.cpp b/src/definitions/scene.cpp index 604307b..48a53b9 100644 --- a/src/definitions/scene.cpp +++ b/src/definitions/scene.cpp @@ -1,6 +1,12 @@ #include "scene.hpp" +#include "ray.hpp" + Scene::Scene(int width, int height) { w = width; h = height; } + +glm::vec3 Scene::SampleSky(Ray ray) { + return { 0.617f, 0.980f, 1.000f }; +} diff --git a/src/definitions/scene.hpp b/src/definitions/scene.hpp index f52b697..7f4e8fb 100644 --- a/src/definitions/scene.hpp +++ b/src/definitions/scene.hpp @@ -1,19 +1,25 @@ #ifndef INFERNO_DEFINITIONS_SCENE_H_ #define INFERNO_DEFINITIONS_SCENE_H_ +#include "../maths.hpp" + #include -class Camera; class Primative; +class Camera; class Mesh; +class Ray; class Scene { public: Scene(int width, int height); int w, h; Camera* camera; + float gamma; std::vector objects; std::vector meshs; + + glm::vec3 SampleSky(Ray ray); }; #endif diff --git a/src/display/display.cpp b/src/display/display.cpp index 22f166b..f0bcfc1 100644 --- a/src/display/display.cpp +++ b/src/display/display.cpp @@ -87,6 +87,13 @@ void Display::SetPixel(int x, int y, uint32_t p) { m_framebufferMutex.unlock(); } +void Display::SetPixel(int x, int y, glm::vec3 p) { + Pixel pixel{ (uint8_t)p.x, (uint8_t)p.y, (uint8_t)p.z }; + 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(); @@ -103,6 +110,15 @@ void Display::SetPixelSafe(int x, int y, uint32_t p) { } } +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.x, (uint8_t)p.y, (uint8_t)p.z }; + m_framebufferMutex.lock(); + Framebuffer[y * this->XRes + x] = pixel.rgb(); + m_framebufferMutex.unlock(); + } +} + void Display::SetFramebuffer(uint32_t* fb) { m_framebufferMutex.lock(); Framebuffer = nullptr; @@ -151,13 +167,13 @@ void Display::UpdateTitle() { } void Display::Close() { - free(Framebuffer); + Active = false; SDL_DestroyTexture(m_texture); SDL_DestroyTexture(m_imguiTexture); SDL_DestroyRenderer(m_renderer); SDL_DestroyWindow(m_window); SDL_Quit(); - Active = false; + free(Framebuffer); } Display::~Display() { diff --git a/src/display/display.hpp b/src/display/display.hpp index 681f57c..28368c5 100644 --- a/src/display/display.hpp +++ b/src/display/display.hpp @@ -3,9 +3,11 @@ #include -#include "../common.hpp" #include "displayinterface.hpp" +#include "../common.hpp" +#include "../maths.hpp" + class Pixel; class Display : public DisplayInterface { @@ -18,8 +20,10 @@ public: 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, uint32_t 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; diff --git a/src/display/displayinterface.hpp b/src/display/displayinterface.hpp index 8849de5..9246e44 100644 --- a/src/display/displayinterface.hpp +++ b/src/display/displayinterface.hpp @@ -2,6 +2,7 @@ #define INFERNO_DISPLAY_DISPLAYINTERFACE_H_ #include "../common.hpp" +#include "../maths.hpp" class Pixel; @@ -21,8 +22,10 @@ public: 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; diff --git a/src/engine/progressiverenderer.cpp b/src/engine/progressiverenderer.cpp index 8313980..a077d64 100644 --- a/src/engine/progressiverenderer.cpp +++ b/src/engine/progressiverenderer.cpp @@ -1,5 +1,7 @@ #include "progressiverenderer.hpp" +#include "renderengine.hpp" + #include "../common.hpp" #include "../pixel.hpp" #include "../display/displayinterface.hpp" @@ -16,8 +18,10 @@ ProgressiveRenderer::ProgressiveRenderer() { } void ProgressiveRenderer::Init(DisplayInterface* interface, Scene* scene) { + m_engine = new RenderEngine(); + m_engine->SetScene(scene); m_interface = interface; - m_scene = scene; + m_scene = scene; } void ProgressiveRenderer::Input() { @@ -31,69 +35,79 @@ void ProgressiveRenderer::Input() { ImGui::Begin("Debug"); ImGui::Text("Hello, world %d", 123); if (ImGui::Button("Save")) {} - char* buf = ""; float f; ImGui::InputText("string", buf, IM_ARRAYSIZE(buf)); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::End(); } +void workerThread(ProgressiveRenderer* renderer, int idd, int xStart, int xRange) { + while (!renderer->Ready) { + std::chrono::milliseconds dura(10); + std::this_thread::sleep_for(dura); + } + + while (renderer->Ready) { + for (int x = xStart; x < xStart + xRange; x++) + for (int y = 0; y < renderer->m_scene->h; y++) { + 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() { int frames = 0; auto startTime = std::chrono::high_resolution_clock::now(); + // 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->w / m_workerMax) * i, + -((m_scene->w / m_workerMax) * i - m_scene->w) + )); + } else { + m_workers.push_back(new std::thread(workerThread, this, i, + (m_scene->w / m_workerMax) * i, + (m_scene->w / m_workerMax) * (i + 1) - (m_scene->w / m_workerMax) * i + )); + } + } + int lastTime = SDL_GetTicks(); + // Starts render loop while (m_interface->Active) { - - - + Ready = true; + + // TODO: Queue frame jobs properly + Input(); - m_interface->Update(); } + Ready = false; + for (auto& thread : m_workers) { + thread->join(); + } - while (m_interface->Active) { - auto frameStartTime = std::chrono::high_resolution_clock::now(); + // auto frameStartTime = std::chrono::high_resolution_clock::now(); - #pragma omp parallel for schedule(dynamic) - for (int x = 0; x < m_scene->w; x++) - for (int y = 0; y < m_scene->h; y++) { + // auto endTime = std::chrono::high_resolution_clock::now(); - Ray ray = m_scene->camera->CastRay(x, y); + // frames++; + // std::cout << "Frame: " << frames << std::endl; + // std::cout << "Frame Time: " << std::chrono::duration_cast(endTime - frameStartTime).count() + // << ":" << std::chrono::duration_cast(endTime - frameStartTime).count() << "s" << std::endl; + // std::cout << "Avg Frame Time: " << std::chrono::duration_cast(endTime - startTime).count() / frames + // << ":" << std::chrono::duration_cast(endTime - startTime).count() / frames << "s" + // << std::endl << std::endl; - float t; - Primative* hit = nullptr; - bool didhit = TraceRayScene(ray, m_scene, t, hit); - if (!didhit) { - m_interface->SetPixelSafe(x, y, 0x000000); - continue; - } - - glm::vec3 hitPoint = ray.origin + ray.direction * t; - - glm::vec3 normal = hit->SurfaceNormal(hitPoint); - Pixel col((normal.x + 1.0f) * 127.5f, (normal.y + 1.0f) * 127.5f, (normal.z + 1.0f) * 127.5f); - m_interface->SetPixelSafe(x, y, col.rgb()); - } - - - auto endTime = std::chrono::high_resolution_clock::now(); - - frames++; - std::cout << "Frame: " << frames << std::endl; - std::cout << "Frame Time: " << std::chrono::duration_cast(endTime - frameStartTime).count() - << ":" << std::chrono::duration_cast(endTime - frameStartTime).count() << "s" << std::endl; - std::cout << "Avg Frame Time: " << std::chrono::duration_cast(endTime - startTime).count() / frames - << ":" << std::chrono::duration_cast(endTime - startTime).count() / frames << "s" - << std::endl << std::endl; - - // Swap framebuffers - m_interface->Update(); - m_interface->ClearFramebuffer(); - } + // Swap framebuffers + // m_interface->Update(); + // m_interface->ClearFramebuffer(); } void ProgressiveRenderer::RenderProgressive() { } - diff --git a/src/engine/progressiverenderer.hpp b/src/engine/progressiverenderer.hpp index 246f6ff..73cb8cd 100644 --- a/src/engine/progressiverenderer.hpp +++ b/src/engine/progressiverenderer.hpp @@ -1,13 +1,18 @@ #ifndef INFERNO_ENGINE_PROGRESSIVERENDERER_H_ #define INFERNO_ENGINE_PROGRESSIVERENDERER_H_ +#include "../maths.hpp" + +#include #include #include #include #include class DisplayInterface; +class RenderEngine; class Scene; +class Ray; class ProgressiveRenderer { public: @@ -19,15 +24,23 @@ public: void Render(); void RenderProgressive(); -private: - DisplayInterface* m_interface = nullptr; + bool Ready = false; + bool MXAA = true; +public: Scene* m_scene = nullptr; + DisplayInterface* m_interface = nullptr; + RenderEngine* m_engine = nullptr; - int m_workerMax = 16; + int m_workerMax = 6; std::vector m_workers; + std::vector m_workerStatus; +private: + std::mutex m_mutex; - bool m_mxaa = true; + char* buf = ""; float f = 0.0f; }; +void workerThread(ProgressiveRenderer* renderer, int idd, int xStart, int xRange); + #endif diff --git a/src/engine/renderengine.cpp b/src/engine/renderengine.cpp new file mode 100644 index 0000000..d81ef34 --- /dev/null +++ b/src/engine/renderengine.cpp @@ -0,0 +1,30 @@ +#include "renderengine.hpp" + +#include "../pixel.hpp" + +#include "../definitions/primatives/primative.hpp" +#include "../definitions/scene.hpp" +#include "../definitions/ray.hpp" + +RenderEngine::RenderEngine() { + +} + +void RenderEngine::SetScene(Scene* scene) { + m_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) { + return m_scene->SampleSky(ray); + } + + glm::vec3 hitPoint = ray.origin + ray.direction * t; + + 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 new file mode 100644 index 0000000..66ab370 --- /dev/null +++ b/src/engine/renderengine.hpp @@ -0,0 +1,20 @@ +#ifndef INFERNO_ENGINE_RENDERENGINE_H_ +#define INFERNO_ENGINE_RENDERENGINE_H_ + +#include "../maths.hpp" + +class Scene; +class Ray; + +class RenderEngine { +public: + RenderEngine(); + + void SetScene(Scene* scene); + + glm::vec3 GetColour(Ray ray, int depth); +private: + Scene* m_scene = nullptr; +}; + +#endif diff --git a/src/engine/tonemap.cpp b/src/engine/tonemap.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/engine/tonemap.hpp b/src/engine/tonemap.hpp new file mode 100644 index 0000000..e69de29