diff --git a/TSE_Core/src/BehaviourScripts/Camera.cpp b/TSE_Core/src/BehaviourScripts/Camera.cpp index 20d0094..60c7b59 100644 --- a/TSE_Core/src/BehaviourScripts/Camera.cpp +++ b/TSE_Core/src/BehaviourScripts/Camera.cpp @@ -101,7 +101,11 @@ void TSE::Camera::SetRenderTarget(IRenderTarget *target) if(target != nullptr) target->AddResizeNotifiable(this); rt = target; - RecalculateProjMatrix(); + if(lastRtSize != rt->GetRawIResizableSize()) + { + lastRtSize = rt->GetRawIResizableSize(); + RecalculateProjMatrix(); + } } TSE::IRenderTarget *TSE::Camera::GetRenderTarget() diff --git a/TSE_Core/src/elements/RenderPipeline.cpp b/TSE_Core/src/elements/RenderPipeline.cpp new file mode 100644 index 0000000..b968950 --- /dev/null +++ b/TSE_Core/src/elements/RenderPipeline.cpp @@ -0,0 +1,40 @@ +#include "RenderPipeline.hpp" + +void TSE::RenderPipeline::AddRenderStep(const RenderStep &step) +{ + steps.push_back(step); +} + +void TSE::RenderPipeline::AddRenderStepAt(const RenderStep &step, int n) +{ + steps.insert(steps.begin() + n, step); +} + +void TSE::RenderPipeline::SetRenderStepAt(const RenderStep &step, int n) +{ + steps[n] = step; +} + +void TSE::RenderPipeline::RemoveRenderStepAt(int n) +{ + auto i = steps.begin() += n; + steps.erase(i); +} + +int TSE::RenderPipeline::GetRenderStepCount() +{ + return steps.size(); +} + +const TSE::RenderStep &TSE::RenderPipeline::GetRenderStepAt(int n) +{ + return steps[n]; +} + +TSE::RenderPipeline* TSE::RenderPipeline::CreateEmpty() +{ + RenderPipeline* res = new RenderPipeline(); + RenderStep step; + res->AddRenderStep(step); + return res; +} diff --git a/TSE_Core/src/elements/RenderPipeline.hpp b/TSE_Core/src/elements/RenderPipeline.hpp new file mode 100644 index 0000000..7a7d323 --- /dev/null +++ b/TSE_Core/src/elements/RenderPipeline.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include "RenderStep.hpp" + +namespace TSE +{ + class RenderPipeline + { + private: + std::vector steps; + + public: + void AddRenderStep(const RenderStep& step); + void AddRenderStepAt(const RenderStep& step, int n); + void SetRenderStepAt(const RenderStep& step, int n); + void RemoveRenderStepAt(int n); + + int GetRenderStepCount(); + const RenderStep& GetRenderStepAt(int n); + + static RenderPipeline* CreateEmpty(); + }; +} // namespace TSE diff --git a/TSE_Core/src/elements/RenderStep.hpp b/TSE_Core/src/elements/RenderStep.hpp new file mode 100644 index 0000000..27adc77 --- /dev/null +++ b/TSE_Core/src/elements/RenderStep.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "Layer.hpp" +#include +#include "interfaces/IRenderTarget.hpp" +#include "Types.hpp" + +namespace TSE +{ + struct RenderStep + { + public: + std::vector layersToRender; + IRenderTarget* target; + bool EditorCamera = true; + }; + +} // namespace TSE diff --git a/TSE_Core/src/elements/Scene.cpp b/TSE_Core/src/elements/Scene.cpp index 1a0afee..32019b2 100644 --- a/TSE_Core/src/elements/Scene.cpp +++ b/TSE_Core/src/elements/Scene.cpp @@ -2,38 +2,88 @@ #include "BehaviourScripts/Camera.hpp" #include #include "Debug.hpp" +#include "RenderPipeline.hpp" void TSE::Scene::Render(IRenderer &rnd, const IWindow &wnd) { + RenderPipeline* pipeline = IRenderer::pipeline; auto camerasBackup = std::vector(IRenderer::camerasToRenderWith); - int counter = 1; - for(auto l : layers) + + if(pipeline != nullptr) { - IRenderer::camerasToRenderWith.clear(); - if(!l.second->IsVisual()) continue; - for(auto camera : camerasBackup) + for(int i = 0; i < pipeline->GetRenderStepCount(); i++) { - auto it = std::find(camera->layersNotToRender.begin(), camera->layersNotToRender.end(), l.second->GetID()); - if(it == camera->layersNotToRender.end()) + IRenderer::camerasToRenderWith = std::vector(camerasBackup); + const RenderStep& step = pipeline->GetRenderStepAt(i); + if(!step.EditorCamera) { - IRenderer::camerasToRenderWith.push_back(camera); + + for(int i = 0; i < IRenderer::camerasToRenderWith.size(); i++) + { + if(IRenderer::camerasToRenderWith[i]->baseObject->name == ".EditorCamera") + IRenderer::camerasToRenderWith.erase(IRenderer::camerasToRenderWith.begin() + i); + } + } + for(int i = 0; i < IRenderer::camerasToRenderWith.size(); i++) + { + if(IRenderer::camerasToRenderWith[i]->baseObject->name != ".EditorCamera") + IRenderer::camerasToRenderWith[i]->SetRenderTarget(step.target); + } + + int counter = 1; + + for(auto l : step.layersToRender) + { + if(!l->IsVisual()) continue; + l->Render(rnd); + if(counter++ != layers.size()) + { + rnd.End(); //OPTIMIZE: + //takes up 13,97% of function, but only needed, if there is more then one layer + //possible optimizations: + // -remove layers + // -make layer calculations, in shader + // -make an offset, that is calculated on cpu, and then commit everything at once + + // now it is better because it is only done once per frame if only one shader is used, or textures are full, or more then one layers are used + rnd.Flush(); + rnd.Begin(); + wnd.ClearDepthBuffer(); + } } } - - l.second->Render(rnd); - if(counter++ != layers.size()) + } + else + { + int counter = 1; + for(auto l : layers) { - rnd.End(); //OPTIMIZE: - //takes up 13,97% of function, but only needed, if there is more then one layer - //possible optimizations: - // -remove layers - // -make layer calculations, in shader - // -make an offset, that is calculated on cpu, and then commit everything at once + IRenderer::camerasToRenderWith.clear(); + if(!l.second->IsVisual()) continue; + for(auto camera : camerasBackup) + { + auto it = std::find(camera->layersNotToRender.begin(), camera->layersNotToRender.end(), l.second->GetID()); + if(it == camera->layersNotToRender.end()) + { + IRenderer::camerasToRenderWith.push_back(camera); + } + } - // now it is better because it is only done once per frame if only one shader is used, or textures are full, or more then one layers are used - rnd.Flush(); - rnd.Begin(); - wnd.ClearDepthBuffer(); + l.second->Render(rnd); + if(counter++ != layers.size()) + { + rnd.End(); //OPTIMIZE: + //takes up 13,97% of function, but only needed, if there is more then one layer + //possible optimizations: + // -remove layers + // -make layer calculations, in shader + // -make an offset, that is calculated on cpu, and then commit everything at once + + // now it is better because it is only done once per frame if only one shader is used, or textures are full, or more then one layers are used + rnd.Flush(); + rnd.Begin(); + wnd.ClearDepthBuffer(); + } } } } diff --git a/TSE_Core/src/interfaces/IRenderer.hpp b/TSE_Core/src/interfaces/IRenderer.hpp index 29e4f63..12d06b0 100644 --- a/TSE_Core/src/interfaces/IRenderer.hpp +++ b/TSE_Core/src/interfaces/IRenderer.hpp @@ -7,11 +7,13 @@ namespace TSE { class Camera; + class RenderPipeline; class IRenderer { public: + inline static TSE::RenderPipeline* pipeline = nullptr; static std::vector camerasToRenderWith; virtual void End() = 0; diff --git a/TSE_Core/src/interfaces/IResizable.hpp b/TSE_Core/src/interfaces/IResizable.hpp index 31e930c..9bb8878 100644 --- a/TSE_Core/src/interfaces/IResizable.hpp +++ b/TSE_Core/src/interfaces/IResizable.hpp @@ -2,6 +2,7 @@ #include #include "IResizeNotifiable.hpp" +#include "Vector2.hpp" namespace TSE { @@ -15,5 +16,9 @@ namespace TSE public: void AddResizeNotifiable(IResizeNotifiable* obj); void RemoveResizeNotifiable(IResizeNotifiable* obj); + inline Vector2 GetRawIResizableSize() + { + return Vector2(width, height); + }; }; } // namespace TSE