1#include <Dataflow/Rendering/Renderer/DataflowRenderer.hpp>
3#include <Engine/Data/ShaderProgramManager.hpp>
4#include <Engine/Data/Texture.hpp>
5#include <Engine/Data/ViewingParameters.hpp>
7#include <Engine/Rendering/RenderObject.hpp>
9#include <Engine/Scene/DefaultCameraManager.hpp>
10#include <Engine/Scene/DefaultLightManager.hpp>
12#include <globjects/Framebuffer.h>
24using namespace Ra::Dataflow::Core;
26DataflowRenderer::RenderGraphController::RenderGraphController() :
27 Ra::Core::Resources::ObservableVoid() {}
35 if ( !m_graphToLoad.empty() ) {
36 loadGraph( m_graphToLoad );
41void DataflowRenderer::RenderGraphController::resize(
int w,
int h ) {
44 if ( m_renderGraph ) { m_renderGraph->resize( m_width, m_height ); }
41void DataflowRenderer::RenderGraphController::resize(
int w,
int h ) {
…}
49 if ( m_renderGraph && m_renderGraph->m_recompile ) {
51 m_renderGraph->init();
55 m_renderGraph->resize( m_width, m_height );
59void DataflowRenderer::RenderGraphController::loadGraph(
const std::string filename ) {
60 m_renderGraph.release();
62 m_renderGraph = std::make_unique<RenderingGraph>( graphName );
63 m_renderGraph->setShaderProgramManager( m_shaderMngr );
64 m_renderGraph->loadFromJson( filename );
68void DataflowRenderer::RenderGraphController::defferedLoadGraph(
const std::string filename ) {
69 m_graphToLoad = filename;
68void DataflowRenderer::RenderGraphController::defferedLoadGraph(
const std::string filename ) {
…}
72void DataflowRenderer::RenderGraphController::saveGraph(
const std::string filename ) {
73 if ( m_renderGraph ) {
75 m_renderGraph->saveToJson( filename );
76 m_renderGraph->setInstanceName( graphName );
80void DataflowRenderer::RenderGraphController::resetGraph() {
81 m_renderGraph.release();
82 m_renderGraph = std::make_unique<RenderingGraph>(
"untitled" );
83 m_renderGraph->setShaderProgramManager( m_shaderMngr );
91 Renderer(), m_controller { controller }, m_name { m_controller.getRendererName() } {
92 m_controller.
attachMember(
this, &DataflowRenderer::graphChanged );
97void DataflowRenderer::graphChanged() {
98 m_graphChanged =
true;
105 m_controller.
resize( m_width, m_height );
110 else {
return false; }
115 auto resourcesRootDir { RadiumEngine::getInstance()->getResourcesDir() +
"Shaders/" };
119 resourcesRootDir +
"2DShaders/Basic2D.vert.glsl",
120 resourcesRootDir +
"2DShaders/Hdr2Ldr.frag.glsl" } );
122 m_postprocessFbo = std::make_unique<globjects::Framebuffer>();
127 Ra::Engine::RadiumEngine::getInstance()->getSystem(
"DefaultCameraManager" ) );
128 if ( cmngr ==
nullptr ) {
130 Ra::Engine::RadiumEngine::getInstance()->registerSystem(
"DefaultCameraManager", cmngr );
133 Ra::Engine::RadiumEngine::getInstance()->getSystem(
"DefaultLightManager" ) );
134 if ( lmngr ==
nullptr ) {
136 Ra::Engine::RadiumEngine::getInstance()->registerSystem(
"DefaultLightManager", lmngr );
142 m_controller.
configure(
this, m_width, m_height );
145 for (
const auto& t : m_sharedTextures ) {
152 m_controller.
resize( m_width, m_height );
155 m_postprocessFbo->bind();
156 m_postprocessFbo->attachTexture( GL_COLOR_ATTACHMENT0,
m_fancyTexture->texture() );
158 if ( m_postprocessFbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE ) {
159 LOG( Ra::Core::Utils::logERROR ) <<
"FBO Error (NodeBasedRenderer::m_postprocessFbo) : "
160 << m_postprocessFbo->statusString();
164 globjects::Framebuffer::unbind();
170 m_controller.
update( renderData );
173 if ( m_graphChanged ) {
175 m_graphChanged =
false;
178 auto lights = getLights();
185 m_controller.
m_renderGraph->setDataSources( allRenderObjects(), lights );
201 const auto& images = m_controller.
m_renderGraph->getImagesOutput();
203 m_colorTexture = images[0];
205 else { m_colorTexture =
nullptr; }
209 if ( m_colorTexture ) {
210 m_postprocessFbo->bind();
213 GL_ASSERT( glDrawBuffer( GL_COLOR_ATTACHMENT0 ) );
214 GL_ASSERT( glDisable( GL_DEPTH_TEST ) );
215 GL_ASSERT( glDepthMask( GL_FALSE ) );
217 auto shader = m_postProcessEnabled
221 shader->setUniform(
"screenTexture", m_colorTexture, 0 );
222 m_quadMesh->render( shader );
224 GL_ASSERT( glDepthMask( GL_TRUE ) );
225 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
227 m_postprocessFbo->unbind();
241# include <RadiumNBR/NodeBasedRenderer.hpp>
243# include <Core/Containers/MakeShared.hpp>
246# include <Core/Utils/Log.hpp>
247using namespace Ra::Core::Utils;
250# include <Engine/Data/ShaderProgramManager.hpp>
251# include <Engine/Data/Texture.hpp>
252# include <Engine/Data/ViewingParameters.hpp>
254# include <Engine/Rendering/RenderObject.hpp>
255# include <Engine/Scene/DefaultCameraManager.hpp>
256# include <Engine/Scene/DefaultLightManager.hpp>
258# include <globjects/Framebuffer.h>
260# include <RadiumNBR/Passes/DebugPass.hpp>
261# include <RadiumNBR/Passes/UiPass.hpp>
270int NodeBasedRendererMagic = 0xFF0F00F0;
272static const GLenum buffers[] = { GL_COLOR_ATTACHMENT0 };
274static NodeBasedRenderer::RenderControlFunctor noOpController;
276NodeBasedRenderer::NodeBasedRenderer() :
Renderer(), m_controller{ noOpController } {}
278NodeBasedRenderer::NodeBasedRenderer( NodeBasedRenderer::RenderControlFunctor& controller ) :
279 Renderer(), m_controller{ controller }, m_name{ m_controller.getRendererName() } {
280 setDisplayNode( m_originalRenderGraph.getDisplayNode() );
283NodeBasedRenderer::~NodeBasedRenderer() {
284 m_displaySinkNode->detach( m_displayObserverId );
285 m_originalRenderGraph.destroy();
288bool NodeBasedRenderer::buildRenderTechnique(
RenderObject* ro )
const {
290 for (
size_t level = 0; level < m_originalRenderGraph.nodes_by_level()->size(); level++ )
292 for (
size_t node = 0; node < m_originalRenderGraph.nodes_by_level()->at( level ).size();
295 m_originalRenderGraph.nodes_by_level()->at( level ).at( node )->buildRenderTechnique(
300 ro->setRenderTechnique( rt );
304void NodeBasedRenderer::initResources() {
306 auto resourcesRootDir{ RadiumEngine::getInstance()->getResourcesDir() +
"Shaders/" };
308 m_shaderProgramManager->addShaderProgram(
310 resourcesRootDir +
"2DShaders/Basic2D.vert.glsl",
311 resourcesRootDir +
"2DShaders/Hdr2Ldr.frag.glsl" } );
313 m_postprocessFbo = std::make_unique<globjects::Framebuffer>();
316void NodeBasedRenderer::loadFromJson(
const std::string& jsonFilePath ) {
317 m_jsonFilePath = jsonFilePath;
319 if ( m_jsonFilePath !=
"" )
321 m_originalRenderGraph.loadFromJson( jsonFilePath );
322 m_originalRenderGraph.init();
328void NodeBasedRenderer::compileRenderGraph() {
329 m_originalRenderGraph.init();
330 m_originalRenderGraph.
resize( m_width, m_height );
331 buildAllRenderTechniques();
332 m_displayedTexture = m_fancyTexture.get();
335void NodeBasedRenderer::reloadRenderGraphFromJson() {
336 if ( m_jsonFilePath !=
"" )
340 m_originalRenderGraph.destroy();
343 m_originalRenderGraph.clear_nodes();
346 m_originalRenderGraph.loadFromJson( m_jsonFilePath );
347 m_originalRenderGraph.init();
348 m_originalRenderGraph.resize( m_width, m_height );
349 buildAllRenderTechniques();
352 m_displayedTexture = m_fancyTexture.get();
360void NodeBasedRenderer::initializeInternal() {
364 Ra::Engine::RadiumEngine::getInstance()->getSystem(
"DefaultCameraManager" ) );
365 if ( cmngr ==
nullptr )
368 Ra::Engine::RadiumEngine::getInstance()->registerSystem(
"DefaultCameraManager", cmngr );
371 Ra::Engine::RadiumEngine::getInstance()->getSystem(
"DefaultLightManager" ) );
372 if ( lmngr ==
nullptr )
375 Ra::Engine::RadiumEngine::getInstance()->registerSystem(
"DefaultLightManager", lmngr );
377 m_lightmanagers.push_back( lmngr );
381 m_controller.configure(
this, m_width, m_height );
383 for (
const auto& t : m_sharedTextures )
384 { m_secondaryTextures.insert( { t.first, t.second.get() } ); }
388 reinterpret_cast<void*
>( &RadiumNBR::NodeBasedRendererMagic ), {
"Resources/RadiumNBR" } );
389 if ( !resourcesCheck )
391 LOG( Ra::Core::Utils::logERROR ) <<
"Unable to find resources for NodeBasedRenderer!";
394 auto resourcesPath{ *resourcesCheck };
397void NodeBasedRenderer::resizeInternal() {
399 m_controller.resize( m_width, m_height );
400 m_originalRenderGraph.resize( m_width, m_height );
402 m_postprocessFbo->bind();
403 m_postprocessFbo->attachTexture( GL_COLOR_ATTACHMENT0, m_fancyTexture->texture() );
405 if ( m_postprocessFbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE )
407 LOG( Ra::Core::Utils::logERROR ) <<
"FBO Error (NodeBasedRenderer::m_postprocessFbo) : "
408 << m_postprocessFbo->checkStatus();
412 globjects::Framebuffer::unbind();
417 m_originalRenderGraph.execute();
427 m_postprocessFbo->bind();
428 GL_ASSERT( glDisable( GL_BLEND ) );
429 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
430 GL_ASSERT( glDepthMask( GL_FALSE ) );
431 GL_ASSERT( glDepthFunc( GL_LESS ) );
433 glDrawBuffers( 1, buffers );
435 for (
const auto& ro : m_debugRenderObjects )
440 DebugRender::getInstance()->render( renderData.viewMatrix, renderData.projMatrix );
442 m_postprocessFbo->unbind();
446 GL_ASSERT( glDepthMask( GL_TRUE ) );
447 GL_ASSERT( glClear( GL_DEPTH_BUFFER_BIT ) );
448 for (
const auto& ro : m_xrayRenderObjects )
450 if ( ro->isVisible() )
452 shader = ro->getRenderTechnique()->getShader();
457 shader->
setUniform(
"light.color", Ra::Core::Utils::Color::Grey( 5.0 ) );
458 shader->
setUniform(
"light.type", Light::LightType::DIRECTIONAL );
459 shader->
setUniform(
"light.directional.direction", Ra::Core::Vector3( 0, -1, 0 ) );
461 Ra::Core::Matrix4 M = ro->getTransformAsMatrix();
462 shader->
setUniform(
"transform.proj", renderData.projMatrix );
463 shader->
setUniform(
"transform.view", renderData.viewMatrix );
466 ro->getRenderTechnique()->getMaterial()->bind( shader );
469 ro->getMesh()->render();
472 m_uiXrayFbo->unbind();
484 glDrawBuffers( 1, buffers );
486 GL_ASSERT( glDepthMask( GL_TRUE ) );
487 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
488 GL_ASSERT( glDepthFunc( GL_LESS ) );
489 GL_ASSERT( glClear( GL_DEPTH_BUFFER_BIT ) );
490 for (
const auto& ro : m_uiRenderObjects )
492 if ( ro->isVisible() )
494 shader = ro->getRenderTechnique()->getShader();
499 Ra::Core::Matrix4 M = ro->getTransformAsMatrix();
500 Ra::Core::Matrix4 MV = renderData.viewMatrix * M;
501 Ra::Core::Vector3 V = MV.block<3, 1>( 0, 3 );
504 Ra::Core::Matrix4 S = Ra::Core::Matrix4::Identity();
505 S.coeffRef( 0, 0 ) = S.coeffRef( 1, 1 ) = S.coeffRef( 2, 2 ) = d;
509 shader->
setUniform(
"transform.proj", renderData.projMatrix );
510 shader->
setUniform(
"transform.view", renderData.viewMatrix );
513 ro->getRenderTechnique()->getMaterial()->bind( shader );
516 ro->getMesh()->render();
519 m_uiXrayFbo->unbind();
524 if ( m_colorTexture )
526 m_postprocessFbo->bind();
529 GL_ASSERT( glDrawBuffer( GL_COLOR_ATTACHMENT0 ) );
530 GL_ASSERT( glDisable( GL_DEPTH_TEST ) );
531 GL_ASSERT( glDepthMask( GL_FALSE ) );
533 auto shader = m_postProcessEnabled
534 ? m_shaderProgramManager->getShaderProgram(
"Hdr2Ldr" )
535 : m_shaderProgramManager->getShaderProgram(
"DrawScreen" );
537 shader->
setUniform(
"screenTexture", m_colorTexture, 0 );
538 m_quadMesh->render( shader );
540 GL_ASSERT( glDepthMask( GL_TRUE ) );
541 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
543 m_postprocessFbo->unbind();
547void NodeBasedRenderer::updateStepInternal(
const ViewingParameters& renderData ) {
550 reloadRenderGraphFromJson();
553 m_jsonFilePath = m_jsonFilePath.substr( 0, m_jsonFilePath.rfind(
'/' ) + 1 );
556 m_reloadJson =
false;
559 if ( m_originalRenderGraph.m_recompile )
561 std::cerr <<
"NodeBasedRenderer::updateStepInternal :Recompiling Graph\n";
562 compileRenderGraph();
563 m_originalRenderGraph.m_recompile =
false;
567 m_originalRenderGraph.getDataNode<NodeTypeRenderObject>()->setElements( *allRenderObjects() );
570 for (
size_t i = 0; i < getLightManager()->count(); i++ )
571 { lights.
push_back( getLightManager()->getLight( i ) ); }
572 m_originalRenderGraph.getDataNode<NodeTypeLight>()->setElements( lights );
576 m_originalRenderGraph.getDataNode<NodeTypeCamera>()->setElements( cameras );
579 m_originalRenderGraph.update();
582void NodeBasedRenderer::setDisplayNode( DisplaySinkNode* displayNode ) {
583 m_displaySinkNode = displayNode;
584 m_displayObserverId =
585 m_displaySinkNode->attachMember(
this, &NodeBasedRenderer::observeDisplaySink );
591 std::cout <<
"NodeBasedRenderer::observeDisplaySink - connected textures ("
592 << graphOutput.
size() <<
") : \n";
602 m_secondaryTextures.clear();
603 for (
const auto& t : m_sharedTextures )
604 { m_secondaryTextures.insert( { t.first, t.second.get() } ); }
606 bool colorTextureSet =
false;
607 if ( m_displaySinkNode )
609 auto textures = m_displaySinkNode->getTextures();
610 for (
const auto t : textures )
612# ifdef GRAPH_CALL_TRACE
617 if ( !colorTextureSet )
620 colorTextureSet =
true;
623 { m_secondaryTextures.insert( { t->getName(), t } ); }
628 if ( !colorTextureSet )
630 m_colorTexture = m_fancyTexture.get();
631 colorTextureSet =
true;
int attachMember(T *object, void(T::*observer)(Args...))
void updateStepInternal(const Ra::Engine::Data::ViewingParameters &renderData) override
void postProcessInternal(const Ra::Engine::Data::ViewingParameters &renderData) override
Do all post processing stuff. If you override this method, be careful to fill.
void renderInternal(const Ra::Engine::Data::ViewingParameters &renderData) override
All the scene rendering magics basically happens here.
virtual void initResources()
void resizeInternal() override
~DataflowRenderer() override
The destructor is used to destroy the render graph.
bool buildRenderTechnique(Ra::Engine::Rendering::RenderObject *ro) const override
void initializeInternal() override
Sets the display sink node.
void debugInternal(const Ra::Engine::Data::ViewingParameters &renderData) override
Add the debug layer with useful informations.
void uiInternal(const Ra::Engine::Data::ViewingParameters &renderData) override
Draw the UI data.
Ra::Engine::Scene::LightManager * getLightManager()
Access the default light manager.
Management of shader parameters with automatic binding of a named parameter to the corresponding glsl...
Core::Utils::optional< const Data::ShaderProgram * > addShaderProgram(const Data::ShaderConfiguration &config)
const Data::ShaderProgram * getShaderProgram(const std::string &id)
void setUniform(const char *name, const T &value) const
Uniform setters.
void render(const Data::RenderParameters &lightParams, const Data::ViewingParameters &viewParams, const Data::ShaderProgram *shader, const Data::RenderParameters &shaderParams)
Data::ShaderProgramManager * m_shaderProgramManager
std::vector< Ra::Engine::Scene::LightManager * > m_lightmanagers
int buildAllRenderTechniques() const
std::unique_ptr< Data::Texture > m_fancyTexture
Final color texture : might be attached to the main framebuffer.
std::map< std::string, Data::Texture * > m_secondaryTextures
Textures exposed in the texture section box to be displayed.
DefaultCameraManager. A simple Camera Manager with a list of Cameras.
DefaultLightManager. A simple Light Manager with a list of lights.
virtual size_t count() const
Number of lights. This is still a work in progress. The idea is to make it possible for a LightManage...
T find_last_of(T... args)
optional< std::string > getResourcesPath(void *symbol, const std::string &pattern)
Search for general resource path.
std::shared_ptr< T > make_shared(Args &&... args)
(GPU) Data representation, along with manager
Scene and how to communicate.
This namespace contains engine and ECS related stuff.
hepler function to manage enum as underlying types in VariableSet
virtual void resize(int w, int h)
virtual void update(const Ra::Engine::Data::ViewingParameters &renderData)
std::unique_ptr< RenderingGraph > m_renderGraph
virtual void configure(DataflowRenderer *renderer, int w, int h)
the set of viewing parameters extracted from the camera and given to the renderer