Skip to content
Snippets Groups Projects
Commit 94cb1c80 authored by Mathias Paulin's avatar Mathias Paulin :speech_balloon:
Browse files

Separate NodeBasedRenderer interface from FullFeaturedRenderer implementation.

parent 0a23c7fb
No related branches found
No related tags found
No related merge requests found
...@@ -14,8 +14,8 @@ using namespace Ra::Core::Utils; // for LOG( logLEVEL ) ...@@ -14,8 +14,8 @@ using namespace Ra::Core::Utils; // for LOG( logLEVEL )
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QFileDialog> #include <QFileDialog>
#include <RadiumNBR/Gui/NodeBasedRendererGui.hpp> #include <RadiumNBR/FullFeatureRenderer.hpp>
#include <RadiumNBR/NodeBasedRenderer.hpp> #include <RadiumNBR/Gui/FullFeaturedRendererGui.hpp>
#ifdef WITH_H3D_SUPPORT #ifdef WITH_H3D_SUPPORT
# include <RadiumH3D/h3DLoader.hpp> # include <RadiumH3D/h3DLoader.hpp>
...@@ -135,7 +135,7 @@ void RadiumPlayer::addRenderers() { ...@@ -135,7 +135,7 @@ void RadiumPlayer::addRenderers() {
} }
// add experimental renderer // add experimental renderer
{ {
auto myRenderer = std::make_shared<RadiumNBR::NodeBasedRenderer>(); auto myRenderer = std::make_shared<RadiumNBR::FullFeatureRenderer>();
std::string rendererName = myRenderer->getRendererName(); std::string rendererName = myRenderer->getRendererName();
auto controlPanel = auto controlPanel =
RadiumNBR::buildRadiumNBRGui( myRenderer.get(), [this]() { this->askForUpdate(); } ); RadiumNBR::buildRadiumNBRGui( myRenderer.get(), [this]() { this->askForUpdate(); } );
......
#include <NodeRendererPlugin.hpp> #include <NodeRendererPlugin.hpp>
#include <RadiumNBR/Gui/NodeBasedRendererGui.hpp> #include <RadiumNBR/Gui/FullFeaturedRendererGui.hpp>
namespace RadiumNBRPlugin { namespace RadiumNBRPlugin {
...@@ -15,7 +15,7 @@ bool NodeRendererPlugin::doAddWidget( QString& name ) { ...@@ -15,7 +15,7 @@ bool NodeRendererPlugin::doAddWidget( QString& name ) {
} }
QWidget* NodeRendererPlugin::getWidget() { QWidget* NodeRendererPlugin::getWidget() {
if ( !m_renderer ) { m_renderer = std::make_shared<RadiumNBR::NodeBasedRenderer>(); } if ( !m_renderer ) { m_renderer = std::make_shared<RadiumNBR::FullFeatureRenderer>(); }
auto sendSignal = [this]() { emit askForUpdate(); }; auto sendSignal = [this]() { emit askForUpdate(); };
return RadiumNBR::buildRadiumNBRGui( m_renderer.get(), sendSignal ); return RadiumNBR::buildRadiumNBRGui( m_renderer.get(), sendSignal );
} }
...@@ -44,7 +44,7 @@ bool NodeRendererPlugin::doAddRenderer() { ...@@ -44,7 +44,7 @@ bool NodeRendererPlugin::doAddRenderer() {
} }
void NodeRendererPlugin::addRenderers( void NodeRendererPlugin::addRenderers(
std::vector<std::shared_ptr<Ra::Engine::Rendering::Renderer>>* rds ) { std::vector<std::shared_ptr<Ra::Engine::Rendering::Renderer>>* rds ) {
if ( !m_renderer ) { m_renderer = std::make_shared<RadiumNBR::NodeBasedRenderer>(); } if ( !m_renderer ) { m_renderer = std::make_shared<RadiumNBR::FullFeatureRenderer>(); }
rds->push_back( m_renderer ); rds->push_back( m_renderer );
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <PluginBase/RadiumPluginInterface.hpp> #include <PluginBase/RadiumPluginInterface.hpp>
#include <RadiumNBR/NodeBasedRenderer.hpp> #include <RadiumNBR/FullFeatureRenderer.hpp>
namespace RadiumNBRPlugin { namespace RadiumNBRPlugin {
...@@ -45,7 +45,7 @@ class NodeRenderer_PLUGIN_API NodeRendererPlugin : public QObject, ...@@ -45,7 +45,7 @@ class NodeRenderer_PLUGIN_API NodeRendererPlugin : public QObject,
void askForUpdate(); void askForUpdate();
private: private:
std::shared_ptr<RadiumNBR::NodeBasedRenderer> m_renderer; std::shared_ptr<RadiumNBR::FullFeatureRenderer> m_renderer;
}; };
} // namespace RadiumNBRPlugin } // namespace RadiumNBRPlugin
...@@ -31,6 +31,7 @@ set(markdowns ...@@ -31,6 +31,7 @@ set(markdowns
set(sources set(sources
RadiumNBR/NodeBasedRenderer.cpp RadiumNBR/NodeBasedRenderer.cpp
RadiumNBR/EnvMap.cpp RadiumNBR/EnvMap.cpp
RadiumNBR/FullFeatureRenderer.cpp
RadiumNBR/SphereSampler.cpp RadiumNBR/SphereSampler.cpp
RadiumNBR/Passes/ClearPass.cpp RadiumNBR/Passes/ClearPass.cpp
RadiumNBR/Passes/GeomPrepass.cpp RadiumNBR/Passes/GeomPrepass.cpp
...@@ -46,6 +47,7 @@ set(public_headers ...@@ -46,6 +47,7 @@ set(public_headers
RadiumNBR/NodeBasedRendererMacro.hpp RadiumNBR/NodeBasedRendererMacro.hpp
RadiumNBR/NodeBasedRenderer.hpp RadiumNBR/NodeBasedRenderer.hpp
RadiumNBR/EnvMap.hpp RadiumNBR/EnvMap.hpp
RadiumNBR/FullFeatureRenderer.hpp
RadiumNBR/RenderPass.hpp RadiumNBR/RenderPass.hpp
RadiumNBR/SphereSampler.hpp RadiumNBR/SphereSampler.hpp
RadiumNBR/Passes/ClearPass.hpp RadiumNBR/Passes/ClearPass.hpp
...@@ -122,12 +124,12 @@ set(gui_markdowns ...@@ -122,12 +124,12 @@ set(gui_markdowns
) )
set(gui_sources set(gui_sources
RadiumNBR/Gui/NodeBasedRendererGui.cpp RadiumNBR/Gui/FullFeaturedRendererGui.cpp
RadiumNBR/Gui/RendererPanel.cpp RadiumNBR/Gui/RendererPanel.cpp
) )
set(gui_public_headers set(gui_public_headers
RadiumNBR/Gui/NodeBasedRendererGui.hpp RadiumNBR/Gui/FullFeaturedRendererGui.hpp
RadiumNBR/Gui/RendererPanel.hpp RadiumNBR/Gui/RendererPanel.hpp
) )
......
#include <RadiumNBR/FullFeatureRenderer.hpp>
#include <Core/Containers/MakeShared.hpp>
#include <Core/Resources/Resources.hpp>
#ifdef PASSES_LOG
# include <Core/Utils/Log.hpp>
using namespace Ra::Core::Utils; // log
#endif
#include <Engine/Data/Material.hpp>
#include <Engine/Data/ShaderProgramManager.hpp>
#include <Engine/Rendering/RenderObject.hpp>
#include <Engine/Scene/DefaultCameraManager.hpp>
#include <Engine/Scene/DefaultLightManager.hpp>
#include <RadiumNBR/Passes/AccessibilityBufferPass.hpp>
#include <RadiumNBR/Passes/ClearPass.hpp>
#include <RadiumNBR/Passes/EmissivityPass.hpp>
#include <RadiumNBR/Passes/EnvLightPass.hpp>
#include <RadiumNBR/Passes/GeomPrepass.hpp>
#include <RadiumNBR/Passes/LocalLightPass.hpp>
#include <RadiumNBR/Passes/TransparencyPass.hpp>
#include <RadiumNBR/Passes/VolumePass.hpp>
#include <RadiumNBR/Passes/WireframePass.hpp>
#include <globjects/Framebuffer.h>
using namespace Ra::Engine;
using namespace Ra::Engine::Scene;
using namespace Ra::Engine::Data;
using namespace Ra::Engine::Rendering;
namespace RadiumNBR {
using namespace gl;
static int FullFeaturedRendererMagic = 0x0F0F0F0F;
static const GLenum buffers[] = { GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3,
GL_COLOR_ATTACHMENT4,
GL_COLOR_ATTACHMENT5,
GL_COLOR_ATTACHMENT6,
GL_COLOR_ATTACHMENT7 };
FullFeatureRenderer::FullFeatureRenderer() : NodeBasedRenderer() {}
FullFeatureRenderer::~FullFeatureRenderer() = default;
void FullFeatureRenderer::initializeInternal() {
NodeBasedRenderer::initializeInternal();
initPasses();
for ( const auto& t : sharedTextures() )
{ m_secondaryTextures.insert( { t.first, t.second.get() } ); }
}
void FullFeatureRenderer::initPasses() {
auto resourcesCheck = Ra::Core::Resources::getResourcesPath(
reinterpret_cast<void*>( &FullFeaturedRendererMagic ), { "Resources/RadiumNBR" } );
if ( !resourcesCheck )
{
LOG( Ra::Core::Utils::logERROR ) << "Unable to find resources for NodeBasedRenderer!";
return;
}
auto resourcesPath{ *resourcesCheck };
auto depthTexture = sharedTextures().find( "Depth (RadiumNBR)" );
auto colorTexture = sharedTextures().find( "Linear RGB (RadiumNBR)" );
/***
* 0 - clear the final picture
* Set the background color either to the global background color or to the env-map
*/
{
m_clearPass = std::make_shared<ClearPass>( nullptr, FullFeaturedRendererPasses::CLEAR_PASS );
m_clearPass->setOutput( *colorTexture );
m_clearPass->setBackground( getBackgroundColor() );
m_clearPass->initializePass( m_width, m_height, m_shaderProgramManager );
}
/***
* 1 Extract basic geometric information : position, normal and depth
* Only draw ont AOV Position and Normal
*/
{
// Zprepass takes all objects but transparent objects are expected to render only their
// opaque fragments.
m_zPrePass = std::make_shared<GeomPrePass>( allRenderObjects(),
FullFeaturedRendererPasses::Z_PASS );
// Add the shared depth texture
m_zPrePass->setOutput( *depthTexture );
// configure acces to shader files
m_zPrePass->setResourcesDir( resourcesPath );
m_zPrePass->initializePass( m_width, m_height, m_shaderProgramManager );
for ( auto&& t : m_zPrePass->getOutputImages() )
{
sharedTextures().insert( t );
}
}
/***
* Compute accessibiity buffer (ambient occlusion) from output of pass 1
* Screen space ambiant occlusion
*/
{
auto sphereSampler =
std::make_unique<SphereSampler>( m_aoSamplingMethod, m_aoSamplingPoints );
m_aoPass = std::make_shared<AccessibilityBufferPass>(
allRenderObjects(), FullFeaturedRendererPasses::ACCESSIBILITY_PASS );
m_aoPass->setResourcesDir( resourcesPath );
m_aoPass->setSampler( std::move( sphereSampler ) );
// Connect to the preceeding pass
auto posTexture = sharedTextures().find( "GeomPrePass::PosInWorld" );
auto nrmTexture = sharedTextures().find( "GeomPrePass::NormalInWorld" );
m_aoPass->setInputs( *posTexture, *nrmTexture );
m_aoPass->initializePass( m_width, m_height, m_shaderProgramManager );
for ( auto&& t : m_aoPass->getOutputImages() )
{
sharedTextures().insert( t );
}
}
auto ambientOcclusionTexture = sharedTextures().find( "SSDO::AOBuffer" );
/***
* 3 - Render emissivity
* Render Ambiant or emissivity color.
* Ambiant is 0.01 the base color. TODO -> set 0.01 a parameter of the pass
* Do not blend with output, replace the background color by the emissivity/ambiant color
*/
{
m_emissivityPass = std::make_shared<EmissivityPass>(
allRenderObjects(), FullFeaturedRendererPasses::EMISSIVITY_PASS );
m_emissivityPass->setResourcesDir( resourcesPath );
m_emissivityPass->setInputs( *depthTexture, *ambientOcclusionTexture );
m_emissivityPass->setOutput( *colorTexture );
m_emissivityPass->setBackground( getBackgroundColor() );
m_emissivityPass->initializePass( m_width, m_height, m_shaderProgramManager );
}
/***
* 4 - Render envlighting
* Only render scene if an envmap is set
* Blend with the previous color buffer
*/
{
m_envlightPass = std::make_shared<EnvLightPass>(
allRenderObjects(), FullFeaturedRendererPasses::ENVMAP_LIGHTING_OPAQUE_PASS );
m_envlightPass->setResourcesDir( resourcesPath );
m_envlightPass->setInputs( *depthTexture, *ambientOcclusionTexture );
m_envlightPass->setOutput( *colorTexture );
m_envlightPass->initializePass( m_width, m_height, m_shaderProgramManager );
}
/***
* 5 - Compute lighting - Opaque objects
*/
{
m_locallightPass = std::make_shared<LocalLightPass>(
allRenderObjects(), FullFeaturedRendererPasses::LIGHTING_OPAQUE_PASS );
m_locallightPass->setResourcesDir( resourcesPath );
m_locallightPass->setInputs( *depthTexture, *ambientOcclusionTexture );
m_locallightPass->setOutput( *colorTexture );
m_locallightPass->setLightManager( m_lightmanagers[0] );
m_locallightPass->initializePass( m_width, m_height, m_shaderProgramManager );
}
/***
* 6 - Compute lighting - Transparent objects
*/
{
m_transparencyPass = std::make_shared<TransparencyPass>(
&m_transparentRenderObjects, FullFeaturedRendererPasses::LIGHTING_TRANSPARENT_PASS );
m_transparencyPass->setResourcesDir( resourcesPath );
m_transparencyPass->setInputs( *depthTexture, *ambientOcclusionTexture );
m_transparencyPass->setOutput( *colorTexture );
m_transparencyPass->setLightManager( m_lightmanagers[0] );
m_transparencyPass->initializePass( m_width, m_height, m_shaderProgramManager );
}
/***
* 7 - Compute lighting for volume objects
*/
{
m_volumelightPass = std::make_shared<VolumeLightingPass>(
&m_volumetricRenderObjects, FullFeaturedRendererPasses::LIGHTING_VOLUME_PASS );
m_volumelightPass->setResourcesDir( resourcesPath );
m_volumelightPass->setInputs( *depthTexture, *colorTexture );
m_volumelightPass->setOutput( *colorTexture );
m_volumelightPass->setLightManager( m_lightmanagers[0] );
m_volumelightPass->initializePass( m_width, m_height, m_shaderProgramManager );
}
/***
* Option - Render in wireframe
* Render all objects as wireframe
* Render in white over an existing depth buffer
*/
{
m_wireframePass = std::make_shared<WireframePass>(
allRenderObjects(), FullFeaturedRendererPasses::WIREFRAME_PASS );
m_wireframePass->setResourcesDir( resourcesPath );
m_wireframePass->setInputs( *depthTexture );
m_wireframePass->setOutput( *colorTexture );
m_wireframePass->initializePass( m_width, m_height, m_shaderProgramManager );
}
// Build the sequence of active passes
addPass(m_clearPass, m_clearPass->index());
m_clearPass->activate();
addPass(m_zPrePass, m_zPrePass->index());
m_zPrePass->activate();
addPass( m_aoPass, m_aoPass->index() );
m_aoPass->activate();
addPass( m_emissivityPass, m_emissivityPass->index() );
m_emissivityPass->activate();
addPass( m_envlightPass, m_envlightPass->index() );
m_envlightPass->activate();
addPass( m_locallightPass, m_locallightPass->index(), true );
m_locallightPass->activate();
addPass( m_transparencyPass, m_transparencyPass->index() );
m_transparencyPass->activate();
addPass( m_volumelightPass, m_volumelightPass->index() );
m_volumelightPass->activate();
addPass( m_wireframePass, m_wireframePass->index() );
// Add intermediate textures to the texture explorer
for ( const auto& p : renderPasses() )
{
for ( auto&& t : p.second->getOutputImages() )
{
sharedTextures().insert( t );
}
}
}
// Todo : verify if the ro partition is the good one and that the passes use the right part.
void FullFeatureRenderer::updateStepInternal( const ViewingParameters& renderData ) {
// 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 );
if ( ( *it )->isTransparent() )
{
m_transparentRenderObjects.push_back( *it );
it = m_fancyRenderObjects.erase( it );
}
else
{
auto material = ( *it )->getMaterial();
if ( material &&
material->getMaterialAspect() == Material::MaterialAspect::MAT_DENSITY )
{
m_volumetricRenderObjects.push_back( *it );
it = m_fancyRenderObjects.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 );
}
void FullFeatureRenderer::setEnvMap( const std::string& files ) {
if ( files.empty() )
{
m_clearPass->setEnvMap( nullptr );
m_envlightPass->setEnvMap( nullptr );
m_envlightPass->deactivate();
m_volumelightPass->setEnvMap( nullptr );
m_hasEnvMap = false;
}
else
{
// Todo, add type VERTICALCROSS, HORIZONTALCROSS and differentiate between all types
// using file extension and file size
auto t = ( files.find( ';' ) != files.npos ) ? EnvMap::EnvMapType::ENVMAP_CUBE
: EnvMap::EnvMapType::ENVMAP_PFM;
if ( t == EnvMap::EnvMapType::ENVMAP_PFM )
{
auto ext = files.substr( files.size() - 3 );
if ( ext != "pfm" ) { t = EnvMap::EnvMapType::ENVMAP_LATLON; }
}
// for now, only skyboxes are managed
auto e = std::make_shared<EnvMap>( files, t, true );
m_clearPass->setEnvMap( e );
m_envlightPass->setEnvMap( e );
// activate the envmap pass only if wireframe is inactive ?
if ( !m_wireframePass->isActive() ) { m_envlightPass->activate(); }
m_volumelightPass->setEnvMap( e );
m_hasEnvMap = true;
}
}
void FullFeatureRenderer::showEnvMap( bool state ) {
m_clearPass->showEnvMap( state );
}
void FullFeatureRenderer::setEnvStrength( int s ) {
m_envlightPass->setEnvStrength( s );
}
Scalar FullFeatureRenderer::getAoRadius() const {
if ( m_aoPass ) { return m_aoPass->aoRadius(); }
return 5.0;
}
void FullFeatureRenderer::setAoRadius( Scalar r ) {
if ( m_aoPass ) { m_aoPass->setAoRadius( r ); }
}
int FullFeatureRenderer::getAoSamplingDensity() const {
return m_aoSamplingPoints;
}
void FullFeatureRenderer::setAoSamplingDensity( int d ) {
m_aoSamplingPoints = d;
auto sphereSampler = std::make_unique<SphereSampler>( m_aoSamplingMethod, m_aoSamplingPoints );
if ( m_aoPass ) { m_aoPass->setSampler( std::move( sphereSampler ) ); }
}
void FullFeatureRenderer::wireframeMode( bool status ) {
enableWireframe( status );
if ( m_wireframe ) {
m_wireframePass->activate();
m_aoPass->deactivate();
m_emissivityPass->deactivate();
m_envlightPass->deactivate();
m_locallightPass->deactivate();
m_transparencyPass->deactivate();
m_volumelightPass->deactivate();
} else {
m_wireframePass->deactivate();
m_aoPass->activate();
m_emissivityPass->activate();
m_envlightPass->activate();
m_locallightPass->activate();
m_transparencyPass->activate();
m_volumelightPass->activate();
}
}
} // namespace RadiumNBR
#pragma once
#include <RadiumNBR/NodeBasedRendererMacro.hpp>
#include <RadiumNBR/RenderPass.hpp>
#include <RadiumNBR/SphereSampler.hpp>
#include <RadiumNBR/NodeBasedRenderer.hpp>
namespace globjects {
class Framebuffer;
}
namespace Ra::Engine::Data {
class Texture;
} // namespace Ra::Engine::Data
namespace RadiumNBR {
class ClearPass;
class GeomPrePass;
class AccessibilityBufferPass;
class EmissivityPass;
class EnvLightPass;
class LocalLightPass;
class VolumeLightingPass;
class TransparencyPass;
class WireframePass;
/** Advanced renderer for the Radium Engine
* This class implements a forward rendering algorithm with Z-prepass, multipass light accumulation
* for opaque and transparent objects.
* Once renderer, the final is composited with Ui, debug and
* X-ray objects renderings on demand.
*
* @see rendering.md for description of the renderer
*/
class NodeBasedRenderer_LIBRARY_API FullFeatureRenderer final : public NodeBasedRenderer
{
public:
FullFeatureRenderer();
~FullFeatureRenderer() override;
[[nodiscard]] std::string getRendererName() const override { return "Full Featured Renderer"; }
void setEnvMap( const std::string& files );
void showEnvMap( bool state );
// TODO : define a way to configfure each passes without adding here specifi methods
// TODO the following might be removed in the future
Scalar getAoRadius() const;
void setAoRadius( Scalar r );
int getAoSamplingDensity() const;
void setAoSamplingDensity( int d );
void setEnvStrength( int s );
void wireframeMode( bool status );
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();
enum FullFeaturedRendererPasses : int {
CLEAR_PASS = 0,
Z_PASS,
ACCESSIBILITY_PASS,
EMISSIVITY_PASS,
ENVMAP_LIGHTING_OPAQUE_PASS,
LIGHTING_OPAQUE_PASS,
LIGHTING_TRANSPARENT_PASS,
LIGHTING_VOLUME_PASS,
WIREFRAME_PASS,
NUM_PASSES,
DEFAULT_PASS = LIGHTING_OPAQUE_PASS
};
protected:
/// Subset of the objects that are transparent and need special rendering
std::vector<RenderObjectPtr> m_transparentRenderObjects;
/// Subset of the objects that are volumetric
std::vector<RenderObjectPtr> m_volumetricRenderObjects;
/// The ambiant occlusion pass
std::shared_ptr<AccessibilityBufferPass> m_aoPass;
// The sampling method of the sphere sampler
SphereSampler::SamplingMethod m_aoSamplingMethod{ SphereSampler::SamplingMethod::HAMMERSLEY };
// The number of points for the sampler
int m_aoSamplingPoints{ 64 };
/// clear the final ouput image
std::shared_ptr<ClearPass> m_clearPass;
/// The zprepass
std::shared_ptr<GeomPrePass> m_zPrePass;
/// The emissivity pass
std::shared_ptr<EmissivityPass> m_emissivityPass;
/// The envlight pass
std::shared_ptr<EnvLightPass> m_envlightPass;
/// The local lighting pass
std::shared_ptr<LocalLightPass> m_locallightPass;
/// The volume lighting pass
std::shared_ptr<VolumeLightingPass> m_volumelightPass;
/// The transparency (Order independant transparency) pass
std::shared_ptr<TransparencyPass> m_transparencyPass;
/// The transparency (Order independant transparency) pass
std::shared_ptr<WireframePass> m_wireframePass;
/// Is an envmap attached to the renderer
bool m_hasEnvMap{ false };
};
} // namespace RadiumNBR
#include <RadiumNBR/Gui/NodeBasedRendererGui.hpp> #include <RadiumNBR/FullFeatureRenderer.hpp>
#include <RadiumNBR/NodeBasedRenderer.hpp> #include <RadiumNBR/Gui/FullFeaturedRendererGui.hpp>
namespace RadiumNBR { namespace RadiumNBR {
using namespace Gui; using namespace Gui;
RadiumNBR::Gui::RendererPanel* buildRadiumNBRGui( NodeBasedRenderer* renderer, RadiumNBR::Gui::RendererPanel* buildRadiumNBRGui( FullFeatureRenderer* renderer,
const std::function<void()>& appUpdateCallback ) { const std::function<void()>& appUpdateCallback ) {
auto controlPanel = new RendererPanel( renderer->getRendererName() ); auto controlPanel = new RendererPanel( renderer->getRendererName() );
......
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
#include <RadiumNBR/NodeBasedRendererMacro.hpp> #include <RadiumNBR/NodeBasedRendererMacro.hpp>
namespace RadiumNBR { namespace RadiumNBR {
class NodeBasedRenderer; class FullFeatureRenderer;
NodeBasedRenderer_LIBRARY_API RadiumNBR::Gui::RendererPanel* NodeBasedRenderer_LIBRARY_API RadiumNBR::Gui::RendererPanel*
buildRadiumNBRGui( NodeBasedRenderer* renderer, const std::function<void()>& appUpdateCallback ); buildRadiumNBRGui( FullFeatureRenderer* renderer, const std::function<void()>& appUpdateCallback );
} // namespace RadiumNBR } // namespace RadiumNBR
This diff is collapsed.
#pragma once #pragma once
#include <RadiumNBR/NodeBasedRendererMacro.hpp> #include <RadiumNBR/NodeBasedRendererMacro.hpp>
#include <RadiumNBR/RenderPass.hpp> #include <RadiumNBR/RenderPass.hpp>
#include <RadiumNBR/SphereSampler.hpp>
#include <Engine/Rendering/Renderer.hpp> #include <Engine/Rendering/Renderer.hpp>
...@@ -9,26 +8,19 @@ namespace globjects { ...@@ -9,26 +8,19 @@ namespace globjects {
class Framebuffer; class Framebuffer;
} }
namespace Ra::Engine::Data {
class Texture;
} // namespace Ra::Engine::Data
namespace RadiumNBR { namespace RadiumNBR {
class ClearPass;
class GeomPrePass; /** Node based for the Radium Engine
class AccessibilityBufferPass; * This Renderer is fully configurable, either dynammically or programatically.
class EmissivityPass; * It implements the Ra::Engine::Rendering/Renderer interface and cand be configured by adding
class EnvLightPass; * as many RadiumNBR::RenderPass rendering passes.
class LocalLightPass; *
class VolumeLightingPass; * It defines two textures that migh be shared between passes :
class TransparencyPass; * - a depth buffer attachable texture
class WireframePass; * - a Linear space RGBA color texture
*
/** Advanced renderer for the Radium Engine * It allows to apply a linearRGB to sRGB color transformation before displaying the image.
* This class implements a forward rendering algorithm with Z-prepass, multipass light accumulation *
* for opaque and transparent objects.
* Once renderer, the final is composited with Ui, debug and
* X-ray objects renderings on demand.
* *
* @see rendering.md for description of the renderer * @see rendering.md for description of the renderer
*/ */
...@@ -39,19 +31,23 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende ...@@ -39,19 +31,23 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende
NodeBasedRenderer(); NodeBasedRenderer();
~NodeBasedRenderer() override; ~NodeBasedRenderer() override;
[[nodiscard]] std::string getRendererName() const override { return "Node Based Renderer"; } [[nodiscard]] std::string getRendererName() const override { return "Configurable Renderer"; }
bool buildRenderTechnique( Ra::Engine::Rendering::RenderObject* ro ) const override; bool buildRenderTechnique( Ra::Engine::Rendering::RenderObject* ro ) const override;
void setEnvMap( const std::string& files ); /** add a pass to be executed at the given rank, and, optionally, is the default pass for the
void showEnvMap( bool state ); * renderer.
// TODO : define a way to configfure each passes without adding here specifi methods *
// TODO the following might be removed in the future * Passes are executed by increasing rank.
Scalar getAoRadius() const; * [not yet available : If two passes have the same rank, they will be
void setAoRadius( Scalar r ); * executed in arbitrary order].
int getAoSamplingDensity() const; *
void setAoSamplingDensity( int d ); * The default pass (rank 0) might be used for specific render operations.
void setEnvStrength( int s ); *
void wireframeMode( bool status ); * 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 );
protected: protected:
void initializeInternal() override; void initializeInternal() override;
...@@ -62,39 +58,34 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende ...@@ -62,39 +58,34 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende
void debugInternal( 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; void uiInternal( const Ra::Engine::Data::ViewingParameters& renderData ) override;
virtual void initShaders();
virtual void initBuffers();
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_allRenderObjects;
}
inline int defaultPass() const {
return m_defaultPass;
}
private: private:
void initPasses();
void initShaders();
void initBuffers();
#if 0
struct NodeBasedRendererPasses {
static constexpr Ra::Core::Utils::Index DEFAULT_PASS{0};
static constexpr Ra::Core::Utils::Index LIGHTING_OPAQUE_PASS{DEFAULT_PASS};
static constexpr Ra::Core::Utils::Index GEOM_PASS{1};
static constexpr Ra::Core::Utils::Index ACCESSIBILITY_PASS{2};
static constexpr Ra::Core::Utils::Index CLEAR_PASS{3};
static constexpr Ra::Core::Utils::Index ENVMAP_LIGHTING_OPAQUE_PASS{4};
static constexpr Ra::Core::Utils::Index EMISSIVITY_PASS{5};
static constexpr Ra::Core::Utils::Index LIGHTING_TRANSPARENT_PASS{6};
static constexpr Ra::Core::Utils::Index LIGHTING_VOLUME_PASS{7};
};
#else
enum NodeBasedRendererPasses : int {
DEFAULT_PASS = 0,
LIGHTING_OPAQUE_PASS = DEFAULT_PASS,
GEOM_PASS,
ACCESSIBILITY_PASS,
CLEAR_PASS,
ENVMAP_LIGHTING_OPAQUE_PASS,
EMISSIVITY_PASS,
LIGHTING_TRANSPARENT_PASS,
LIGHTING_VOLUME_PASS,
WIREFRAME_PASS,
NUM_PASSES
};
#endif
protected:
/// textures own by the Renderer but shared across passes /// textures own by the Renderer but shared across passes
std::map<std::string, std::shared_ptr<Ra::Engine::Data::Texture>> m_sharedTextures; std::map<std::string, std::shared_ptr<Ra::Engine::Data::Texture>> m_sharedTextures;
...@@ -102,51 +93,13 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende ...@@ -102,51 +93,13 @@ class NodeBasedRenderer_LIBRARY_API NodeBasedRenderer : public Ra::Engine::Rende
std::unique_ptr<globjects::Framebuffer> m_postprocessFbo; std::unique_ptr<globjects::Framebuffer> m_postprocessFbo;
/// vector of this renderer render passes, sorted by precedence (first pass is at index 0) /// vector of this renderer render passes, sorted by precedence (first pass is at index 0)
std::vector<std::shared_ptr<RenderPass>> m_renderPasses; std::map< int, std::shared_ptr<RenderPass> > m_renderPasses;
/// Subset of the objects that are transparent and need special rendering
std::vector<RenderObjectPtr> m_transparentRenderObjects;
/// Subset of the objects that are volumetric
std::vector<RenderObjectPtr> m_volumetricRenderObjects;
/// Backup of all objects so that global passses can execute /// Backup of all objects so that global passses can execute
std::vector<RenderObjectPtr> m_allRenderObjects; std::vector<RenderObjectPtr> m_allRenderObjects;
/// The ambiant occlusion pass /// The default pass
std::shared_ptr<AccessibilityBufferPass> m_aoPass; int m_defaultPass{-1};
// The sampling method of the sphere sampler
SphereSampler::SamplingMethod m_aoSamplingMethod{ SphereSampler::SamplingMethod::HAMMERSLEY };
// The number of points for the sampler
int m_aoSamplingPoints{ 64 };
/// clear the final ouput image
std::shared_ptr<ClearPass> m_clearPass;
/// The zprepass
std::shared_ptr<GeomPrePass> m_zPrePass;
/// The emissivity pass
std::shared_ptr<EmissivityPass> m_emissivityPass;
/// The envlight pass
std::shared_ptr<EnvLightPass> m_envlightPass;
/// The local lighting pass
std::shared_ptr<LocalLightPass> m_locallightPass;
/// The volume lighting pass
std::shared_ptr<VolumeLightingPass> m_volumelightPass;
/// The transparency (Order independant transparency) pass
std::shared_ptr<TransparencyPass> m_transparencyPass;
/// The transparency (Order independant transparency) pass
std::shared_ptr<WireframePass> m_wireframePass;
/// Is an envmap attached to the renderer
bool m_hasEnvMap{ false };
}; };
} // namespace RadiumNBR }
...@@ -124,6 +124,8 @@ class NodeBasedRenderer_LIBRARY_API RenderPass ...@@ -124,6 +124,8 @@ class NodeBasedRenderer_LIBRARY_API RenderPass
// is the pass active ? // is the pass active ?
[[nodiscard]] inline bool isActive() { return m_active; } [[nodiscard]] inline bool isActive() { return m_active; }
[[nodiscard]] inline int index() const { return int(m_idx); }
/// @todo : Having protected member is a bad idea /// @todo : Having protected member is a bad idea
/// @see https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c133-avoid-protected-data /// @see https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c133-avoid-protected-data
protected: protected:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment