diff --git a/src/inferno.cpp b/src/inferno.cpp index 1ee8b03..da315b8 100644 --- a/src/inferno.cpp +++ b/src/inferno.cpp @@ -36,6 +36,7 @@ Inferno::Inferno() mWin->init("Inferno v" INFERNO_VERSION, 1280, 720); mRasterRenderer = new RasterizeRenderer(); + mRayRenderer = new RenderDispatcher(); mScene = new Scene(); } @@ -216,8 +217,27 @@ int Inferno::run() if (showRenderSettings && ImGui::Begin("Inferno HART")) { + // start/stop + bool isRenderRunning = mRayRenderer->progressionStatus(); + if (isRenderRunning) + { + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); + ImGui::Button("Start Render"); ImGui::SameLine(); + ImGui::PopItemFlag(); ImGui::PopStyleVar(); + if (ImGui::Button("Stop Render")) + mRayRenderer->stopProgression(); + } else { + if (ImGui::Button("Start Render")) + mRayRenderer->startProgression(); + ImGui::SameLine(); + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); + ImGui::Button("Stop Render"); + ImGui::PopItemFlag(); ImGui::PopStyleVar(); + } + if (ImGui::TreeNode("Render")) { + // modules HHM* hhm = mRayRenderer->getTopModule(); if (ImGui::TreeNode("Accelerator")) { diff --git a/src/renderer/dispatcher.cpp b/src/renderer/dispatcher.cpp index 04732b6..f499573 100644 --- a/src/renderer/dispatcher.cpp +++ b/src/renderer/dispatcher.cpp @@ -3,10 +3,14 @@ #include "hart_module.hpp" #include "renderer.hpp" +#include + +#include using namespace inferno; RenderDispatcher::RenderDispatcher() + : mRenderWorker{} { mHHM = new HHM(); mRenderer = new RayRenderer(mHHM); @@ -14,7 +18,9 @@ RenderDispatcher::RenderDispatcher() RenderDispatcher::~RenderDispatcher() { - + mDoWork = false; + mJoin = true; + mRenderWorker.join(); } RayRenderer* RenderDispatcher::getRenderer() @@ -27,17 +33,38 @@ HHM* RenderDispatcher::getTopModule() return mHHM; } +void renderWorker(RayRenderer* renderer, std::atomic* doWork, std::atomic* join) +{ + while (!*join) + { + if (!*doWork) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + continue; // stall + } + spdlog::debug("Sample complete"); + } +} + void RenderDispatcher::startProgression() { - + if (!mRenderWorker.joinable()) + { + mRenderWorker = std::thread{ &renderWorker, this->mRenderer, &mDoWork, &mJoin }; + } + mDoWork = true; } void RenderDispatcher::stopProgression() { + mDoWork = false; +} +bool RenderDispatcher::progressionStatus() +{ + return mDoWork; } GLuint RenderDispatcher::getLatestTexture() { - + return mRenderer->getRenderedTexture(); } diff --git a/src/renderer/dispatcher.hpp b/src/renderer/dispatcher.hpp index 0abe914..fd18921 100644 --- a/src/renderer/dispatcher.hpp +++ b/src/renderer/dispatcher.hpp @@ -2,6 +2,10 @@ #include +#include +#include +#include + namespace inferno { // Thread dispatcher keeps track of the thread that calls the @@ -22,11 +26,17 @@ public: void startProgression(); void stopProgression(); + bool progressionStatus(); GLuint getLatestTexture(); private: HHM* mHHM; RayRenderer* mRenderer; + +private: + std::thread mRenderWorker; + std::atomic mDoWork = false; + std::atomic mJoin = false; }; } diff --git a/src/renderer/renderer.hpp b/src/renderer/renderer.hpp index e1555dd..260a1a6 100644 --- a/src/renderer/renderer.hpp +++ b/src/renderer/renderer.hpp @@ -25,6 +25,7 @@ public: void draw(); private: + // TODO: a mutex for the renderTargetTexture as it gets accessed by the render thread and the main thread GLuint mRenderTargetTexture = 0; glm::fvec4* mTarget;