-
Mathias Paulin authoredMathias Paulin authored
NodeBasedRenderer.hpp 6.65 KiB
#pragma once
#include <RadiumNBR/NodeBasedRendererMacro.hpp>
#include <RadiumNBR/RenderPass.hpp>
#include <Core/Resources/Resources.hpp>
#include <Engine/Rendering/Renderer.hpp>
namespace globjects {
class Framebuffer;
}
namespace RadiumNBR {
/// Todo, put this somewhere else. This is needed to locate resources by client applications
extern int NodeBasedRendererMagic;
class UIPass;
class DebugPass;
/** Node based for the Radium Engine
* This Renderer is fully configurable, either dynamically or programmatically.
* It implements the Ra::Engine::Rendering/Renderer interface.
*
* A NodeBasedRenderer is configured by using the RenderControlFunctor given at construction.
* A RenderControlFunctor offers the following services :
* - configure() : add to the renderer as many RadiumNBR::RenderPass as needed. This method is
* called once when initializing the renderer. This method could also initialize internal
* resources into the controller that could be used to control the rendering.
* - resize() : called each time the renderer output is resized. This will allow modify controller
* resources that depends on the size of the output (e.g. internal textures ...)
* - update() : Called once before each frame to update the internal state of the renderer.
*
* A NodeBasedRenderer defines two textures that might be shared between passes :
* - a depth buffer attachable texture, stored with the key "Depth (RadiumNBR)" into the shared
* textures collection
* - a Linear space RGBA color texture, stored with the key "Linear RGB (RadiumNBR)" into the
* shared textures collection
*
* If requested on the base Ra::Engine::Rendering::Renderer, a NodeBasedRenderer apply a
* post-process step on the "Linear RGB (RadiumNBR)" that convert colors from linearRGB to sRGB
* color space before displaying the image.
*
*
* @see rendering.md for description of the renderer
*/
class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rendering::Renderer
{
public:
/**
* Rendering functor prototype
* @todo make this a concept
*/
struct RenderControlFunctor {
RenderControlFunctor() = default;
virtual ~RenderControlFunctor() = default;
RenderControlFunctor( const RenderControlFunctor& ) = delete;
RenderControlFunctor( const RenderControlFunctor&& ) = delete;
RenderControlFunctor& operator=( RenderControlFunctor&& ) = delete;
RenderControlFunctor& operator=( const RenderControlFunctor& ) = delete;
/// Configuration function.
/// Called once at the configuration of the renderer
virtual void configure( NodeBasedRenderer* renderer, int w, int h ){};
/// Resize function
/// Called each time the renderer is resized
virtual void resize( int w, int h ){};
/// Update function
/// Called once before each frame to update the internal state of the renderer
virtual void update( const Ra::Engine::Data::ViewingParameters& renderData ){};
};
/// Construct a renderer that has to be configured explicitely
NodeBasedRenderer();
/// Construct a renderer configured and managed through the controller
explicit NodeBasedRenderer( RenderControlFunctor& controller );
/// The destructor is defaulted
~NodeBasedRenderer() override;
[[nodiscard]] std::string getRendererName() const override { return "Configurable Renderer"; }
bool buildRenderTechnique( Ra::Engine::Rendering::RenderObject* ro ) const override;
/** add a pass to be executed at the given rank, and, optionally, is the default pass for the
* renderer.
*
* Passes are executed by increasing rank.
* [not yet available : If two passes have the same rank, they will be
* executed in arbitrary order].
*
* The default pass (rank 0) might be used for specific render operations.
*
* If a pass with the same rank already exists in the Renderer, the given pass is not added nor
* is changed the default)
* @return true if the pass is insserted, false if not
*/
bool addPass( std::shared_ptr<RadiumNBR::RenderPass> pass, int rank, bool defaultPass = false );
/// Hide or show the UI
void showUI( bool b );
/// Hide or show the Debug objects
void showDebug( bool b );
/// Access the default light manager
Ra::Engine::Scene::LightManager* getLightManager() { return m_lightmanagers[0]; }
/// Access the controler
RenderControlFunctor& getController() { return m_controller; }
protected:
void initializeInternal() override;
void resizeInternal() override;
void updateStepInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override;
void renderInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override;
void postProcessInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override;
void debugInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override;
void uiInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override;
/** Initialize internal resources for the renderer.
* The base function creates the depth and final color texture to be shared by the rendering
* passes that need them.
*/
virtual void initResources();
public:
inline std::map<std::string, std::shared_ptr<Ra::Engine::Data::Texture>>& sharedTextures() {
return m_sharedTextures;
}
inline globjects::Framebuffer* postprocessFbo() { return m_postprocessFbo.get(); }
inline std::map<int, std::shared_ptr<RenderPass>>& renderPasses() { return m_renderPasses; }
inline const std::map<int, std::shared_ptr<RenderPass>>& renderPasses() const {
return m_renderPasses;
}
inline std::vector<RenderObjectPtr>* allRenderObjects() { return &m_fancyRenderObjects; }
inline int defaultPass() const { return m_defaultPass; }
private:
/// textures own by the Renderer but shared across passes
std::map<std::string, std::shared_ptr<Ra::Engine::Data::Texture>> m_sharedTextures;
/// internal FBO used for post-processing
std::unique_ptr<globjects::Framebuffer> m_postprocessFbo;
/// collection of render passes, sorted by precedence (first pass is at key 0)
std::map<int, std::shared_ptr<RenderPass>> m_renderPasses;
/// The default pass
int m_defaultPass{-1};
/// The configurator functor to use
RenderControlFunctor& m_controller;
/// The pass to draw UI object
std::unique_ptr<UIPass> m_uiPass;
bool m_showUi{false};
/// The pass to draw Debug object
std::unique_ptr<DebugPass> m_debugPass;
bool m_showDebug{false};
};
} // namespace RadiumNBR