diff --git a/src/DemoApp/main.cpp b/src/DemoApp/main.cpp index defd1fbede4555983da2de622e02a4599bae571a..3326b898e6af326aedbbb26af56edd0b65d55e2d 100644 --- a/src/DemoApp/main.cpp +++ b/src/DemoApp/main.cpp @@ -13,9 +13,10 @@ * This class parameterize the renderer just after the OpenGL system was initialized. * In the functor, The OpenGL context of the drawing window is activated. */ -class RendererBuilder { +class RendererController : public RadiumNBR::RenderControlFunctor { public: - void operator ()(RadiumNBR::NodeBasedRenderer *renderer, int w, int h) { + + void configure(RadiumNBR::NodeBasedRenderer *renderer, int w, int h) override { LOG( Ra::Core::Utils::logINFO ) << "Customizing the renderer " << renderer->getRendererName(); //! [Caching some helpers and data from the Engine and the renderer] @@ -101,6 +102,7 @@ class DemoWindowFactory : public Ra::Gui::BaseApplication::WindowFactory std::shared_ptr<RadiumNBR::NodeBasedRenderer> renderer; }; + int main( int argc, char* argv[] ) { if ( argc < 2 ) { @@ -108,7 +110,8 @@ int main( int argc, char* argv[] ) { return 1; } //! [Instatiating the renderer giving a customization functor] - auto renderer = std::make_shared<RadiumNBR::NodeBasedRenderer>(RendererBuilder{} ); + RendererController renderControl; + auto renderer = std::make_shared<RadiumNBR::NodeBasedRenderer>( renderControl ); //! [Instatiating the renderer giving a customization functor] //! [Instatiating the application] diff --git a/src/libRender/RadiumNBR/FullFeatureRenderer.cpp b/src/libRender/RadiumNBR/FullFeatureRenderer.cpp index f455a4e85352fefb03b1c6a88667ba32b0749fe4..faae3040c1b511f847cec88a8fc9b5af384df7fb 100644 --- a/src/libRender/RadiumNBR/FullFeatureRenderer.cpp +++ b/src/libRender/RadiumNBR/FullFeatureRenderer.cpp @@ -244,49 +244,36 @@ void FullFeatureRenderer::updateStepInternal( const ViewingParameters& renderDat // Split objects into opaque and transparent m_transparentRenderObjects.clear(); m_volumetricRenderObjects.clear(); - allRenderObjects()->clear(); - for ( auto it = m_fancyRenderObjects.begin(); it != m_fancyRenderObjects.end(); ) - { - allRenderObjects()->push_back( *it ); + + auto objectsToRender = allRenderObjects(); + for( auto it = objectsToRender->begin(); it != objectsToRender->end(); ) { if ( ( *it )->isTransparent() ) { m_transparentRenderObjects.push_back( *it ); - it = m_fancyRenderObjects.erase( it ); + it = objectsToRender->erase( it ); + //++it; } else { auto material = ( *it )->getMaterial(); if ( material && - material->getMaterialAspect() == Material::MaterialAspect::MAT_DENSITY ) + material->getMaterialAspect() == Material::MaterialAspect::MAT_DENSITY ) { m_volumetricRenderObjects.push_back( *it ); - it = m_fancyRenderObjects.erase( it ); + it = objectsToRender->erase( it ); } else { ++it; } } } - - // Update passes - // Note that this could be expensive. Find a way to add attributes to renderObjects so - // that one ca factorizes some evaluations. - for ( auto& rp : renderPasses() ) - { - if ( rp.second->isActive() ) { rp.second->update(); } - } -} - -void FullFeatureRenderer::renderInternal( const ViewingParameters& renderData ) { m_clearPass->setBackground( getBackgroundColor() ); if ( m_hasEnvMap ) { // for ( auto &lm : m_lightmanagers ) { lm->removeSystemLights(); } } - NodeBasedRenderer::renderInternal( renderData ); + NodeBasedRenderer::updateStepInternal( renderData ); } - - void FullFeatureRenderer::setEnvMap( const std::string& files ) { if ( files.empty() ) { diff --git a/src/libRender/RadiumNBR/FullFeatureRenderer.hpp b/src/libRender/RadiumNBR/FullFeatureRenderer.hpp index 44dba4f8cc0b3ab391cec03bba25086217c589d5..852011bd45e690243344c054e10893032357813c 100644 --- a/src/libRender/RadiumNBR/FullFeatureRenderer.hpp +++ b/src/libRender/RadiumNBR/FullFeatureRenderer.hpp @@ -55,7 +55,6 @@ class NodeBasedRenderer_LIBRARY_API FullFeatureRenderer final : public NodeBased protected: void initializeInternal() override; void updateStepInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override; - void renderInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override; private: void initPasses(); diff --git a/src/libRender/RadiumNBR/NodeBasedRenderer.cpp b/src/libRender/RadiumNBR/NodeBasedRenderer.cpp index 19602c3f2a1dcbaa051176221dacbc0865403526..46106db91393abef25fd84d14ba16972047cbf34 100644 --- a/src/libRender/RadiumNBR/NodeBasedRenderer.cpp +++ b/src/libRender/RadiumNBR/NodeBasedRenderer.cpp @@ -26,11 +26,13 @@ int NodeBasedRendererMagic = 0xFF0F00F0; static const GLenum buffers[] = { GL_COLOR_ATTACHMENT0 }; -NodeBasedRenderer::NodeBasedRenderer() : Renderer() {} +static RenderControlFunctor noOpController; -NodeBasedRenderer::NodeBasedRenderer( std::function<void(NodeBasedRenderer *, int, int)> configurator ) : +NodeBasedRenderer::NodeBasedRenderer() : Renderer(), m_controller{noOpController} {} + +NodeBasedRenderer::NodeBasedRenderer( RenderControlFunctor & controller ) : Renderer(), - m_configurator{std::move(configurator)} {} + m_controller{controller} {} NodeBasedRenderer::~NodeBasedRenderer() = default; @@ -45,7 +47,7 @@ bool NodeBasedRenderer::buildRenderTechnique( RenderObject* ro ) const { return true; } -void NodeBasedRenderer::initShaders() { +void NodeBasedRenderer::initResources() { // uses several resources from the Radium engine auto resourcesRootDir{ RadiumEngine::getInstance()->getResourcesDir() + "Shaders/" }; @@ -54,15 +56,11 @@ void NodeBasedRenderer::initShaders() { resourcesRootDir + "2DShaders/Basic2D.vert.glsl", resourcesRootDir + "2DShaders/Hdr2Ldr.frag.glsl" } ); -} - -void NodeBasedRenderer::initBuffers() { m_postprocessFbo = std::make_unique<globjects::Framebuffer>(); // NodeBased renderer : only initializes textures that are shared between all the passes or // that are used internally on the renderer. // Each pass will manage its own textures and export them if they can be shared. - TextureParameters texparams; texparams.width = m_width; texparams.height = m_height; @@ -106,12 +104,11 @@ void NodeBasedRenderer::initializeInternal() { m_lightmanagers.push_back( lmngr ); // Initialize renderer resources - initShaders(); - initBuffers(); + initResources(); for ( const auto& t : m_sharedTextures ) { m_secondaryTextures.insert( { t.first, t.second.get() } ); } - if ( m_configurator ) { m_configurator( this, m_width, m_height ); } + m_controller.configure( this, m_width, m_height ); } void NodeBasedRenderer::resizeInternal() { @@ -269,13 +266,9 @@ void NodeBasedRenderer::postProcessInternal( const ViewingParameters& /* renderD m_postprocessFbo->unbind(); } -// Todo : verify if the ro partition is the good one and that the passes use the right part. void NodeBasedRenderer::updateStepInternal( const ViewingParameters& renderData ) { - m_allRenderObjects.clear(); - for ( auto it = m_fancyRenderObjects.begin(); it != m_fancyRenderObjects.end(); ++it) - { - m_allRenderObjects.push_back( *it ); - } + + m_controller.update( renderData ); // Update passes // Note that this could be expensive. Find a way to add attributes to renderObjects so diff --git a/src/libRender/RadiumNBR/NodeBasedRenderer.hpp b/src/libRender/RadiumNBR/NodeBasedRenderer.hpp index 6514175e23160e7087e342bde1cd8e30ea7c9dc1..20a69dd828b25c1b0e004d05492a8256f24e43a2 100644 --- a/src/libRender/RadiumNBR/NodeBasedRenderer.hpp +++ b/src/libRender/RadiumNBR/NodeBasedRenderer.hpp @@ -14,6 +14,29 @@ namespace RadiumNBR { /// Todo, put this somewhere else. This is needed to locate resources by cclient applications extern int NodeBasedRendererMagic; +class NodeBasedRenderer; + +/** + * Rendering functor prototype + * @todo make this a concept + */ +struct RenderControlFunctor { + + virtual ~RenderControlFunctor() = default; + /// 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) {}; +}; + + /** Node based for the Radium Engine * This Renderer is fully configurable, either dynammically or programatically. * It implements the Ra::Engine::Rendering/Renderer interface and can be configured by adding @@ -32,8 +55,12 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende { public: + + // NodeBasedRenderer(); - NodeBasedRenderer( std::function<void(NodeBasedRenderer *, int, int)> configurator ); + // TODO : instead of an std::function, restrict to a ref to a functor (class with () operator + // Such a functor could then be used also during the update step. + explicit NodeBasedRenderer( RenderControlFunctor& controller ); ~NodeBasedRenderer() override; @@ -64,8 +91,13 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende void debugInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override; void uiInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override; - virtual void initShaders(); - virtual void initBuffers(); + // TODO : merge these two function into initResources ? + + /** 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() { @@ -85,7 +117,8 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende } inline std::vector<RenderObjectPtr> *allRenderObjects() { - return &m_allRenderObjects; + //return &m_allRenderObjects; + return &m_fancyRenderObjects; } inline int defaultPass() const { @@ -103,13 +136,13 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende std::map< int, std::shared_ptr<RenderPass> > m_renderPasses; /// Backup of all objects so that global passses can execute - std::vector<RenderObjectPtr> m_allRenderObjects; + //std::vector<RenderObjectPtr> m_allRenderObjects; /// The default pass int m_defaultPass{-1}; /// The configurator functor to use - std::function<void(NodeBasedRenderer *, int, int)> m_configurator; + RenderControlFunctor& m_controller; }; } diff --git a/src/libRender/RadiumNBR/Shaders/AccessibilityPass/ssao.frag.glsl b/src/libRender/RadiumNBR/Shaders/AccessibilityPass/ssao.frag.glsl index 9ba9206dc2cb1cf719a2c9324c1f79fcab03d6d9..752bed9abddda15f650476c047dfdb55fb6651b0 100644 --- a/src/libRender/RadiumNBR/Shaders/AccessibilityPass/ssao.frag.glsl +++ b/src/libRender/RadiumNBR/Shaders/AccessibilityPass/ssao.frag.glsl @@ -50,7 +50,7 @@ void main() { } } ssdo = 1 - ssdo/nbSamples; - ssdo *= ssdo; + //ssdo *= ssdo; ssdo = smoothstep(0, 1, ssdo); } out_ssao = vec4(vec3(ssdo), 1);