From 2e73c25a255b13b7fb41fdbf1557abc3f2b7c6f6 Mon Sep 17 00:00:00 2001 From: Nessim DAHMANI <ndahmani@bramer.irit.fr> Date: Fri, 4 Feb 2022 15:09:13 +0100 Subject: [PATCH] split volviz node in two files and economy on render techniques indices --- doc/HowToNodes-Developer.md | 5 +- src/libRender/CMakeLists.txt | 1 + .../PremadeNodes/VolumeVizualisationNode.cpp | 254 +++++++++++++++++ .../PremadeNodes/VolumeVizualisationNode.hpp | 259 +----------------- .../RadiumNBR/NodeGraph/RenderGraph.cpp | 9 +- .../RadiumNBR/NodeGraph/RenderGraph.hpp | 1 + 6 files changed, 276 insertions(+), 253 deletions(-) create mode 100644 src/libRender/RadiumNBR/NodeGraph/PremadeNodes/VolumeVizualisationNode.cpp diff --git a/doc/HowToNodes-Developer.md b/doc/HowToNodes-Developer.md index 7ad1bb5..74efc39 100644 --- a/doc/HowToNodes-Developer.md +++ b/doc/HowToNodes-Developer.md @@ -93,7 +93,6 @@ void NewNode::resize( uint32_t width, uint32_t height) { ``` - **buildRenderTechnique( const Ra::Engine::Rendering::RenderObject\* ro, Ra::Engine::Rendering::RenderTechnique& rt) const**: Called once per render object to create the render technique needed for this pass. - ```CPP void NewNode::buildRenderTechnique( const Ra::Engine::Rendering::RenderObject* ro, Ra::Engine::Rendering::RenderTechnique& rt) const { auto mat = const_cast<Ra::Engine::Rendering::RenderObject*>( ro )->getMaterial(); @@ -138,13 +137,13 @@ NodeFactory::registerNode<NewNode>( [] ( const nlohmann::json& data ) { ``` ## Adding the node to the Qt GUI (NodeEditor) -If you are using the Qt windowing system, you can add your node to NodeEditor in the ``openNodeEditor()`` function of ``RadiumPlayer.cpp``. +If you are using the Qt windowing system, you can add your node to NodeEditor by using the ``DataModelRegistry``. In the general case, you just want to use the already available ``NodeAdapterModel`` with your node. ```CPP ret->registerModel<NodeAdapterModel<NewNode>( NodeCreator<NodeAdapterModel<NewNode>( - renderer->getRenderGraph() ), "Premade Nodes" ); + renderer->getRenderGraph() ), "Premade Nodes" ); // ret is an instance of NodeEditor's DataModelRegistry ``` The widgets will be created according to the editable parameters defined in your node's constructor. The type of widget depends on the type of the editable parameter. If the type does not have a widget associated to it, you can add one yourself: diff --git a/src/libRender/CMakeLists.txt b/src/libRender/CMakeLists.txt index 5ebf341..d8de086 100644 --- a/src/libRender/CMakeLists.txt +++ b/src/libRender/CMakeLists.txt @@ -42,6 +42,7 @@ set(sources RadiumNBR/NodeGraph/PremadeNodes/TransparencyNode.cpp RadiumNBR/NodeGraph/PremadeNodes/UINode.cpp RadiumNBR/NodeGraph/PremadeNodes/VolumeNode.cpp + RadiumNBR/NodeGraph/PremadeNodes/VolumeVizualisationNode.cpp RadiumNBR/NodeGraph/PremadeNodes/WireframeNode.cpp RadiumNBR/NodeGraph/PremadeNodes/ZGeomPrepassNode.cpp diff --git a/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/VolumeVizualisationNode.cpp b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/VolumeVizualisationNode.cpp new file mode 100644 index 0000000..491ff9b --- /dev/null +++ b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/VolumeVizualisationNode.cpp @@ -0,0 +1,254 @@ +#include <RadiumNBR/NodeGraph/PremadeNodes/VolumeVizualisationNode.hpp> + +VolumeVizualisationNode::VolumeVizualisationNode( const std::string& name ) : Node( name ) { + auto portInColor = new PortIn<NodeTypeTexture>( "inColorTexture", this ); + addInput( portInColor ); + portInColor->mustBeLinked(); + auto portInDepth = new PortIn<NodeTypeTexture>( "inDepthTexture", this ); + addInput( portInDepth ); + portInDepth->mustBeLinked(); + auto portInRO = new PortIn<std::vector<NodeTypeRenderObject>>( "inRenderObjects", this ); + addInput( portInRO ); + auto portInC = new PortIn<std::vector<NodeTypeCamera>>( "inCameras", this ); + addInput( portInC ); + portInC->mustBeLinked(); + auto portInL = new PortIn<std::vector<NodeTypeLight>>( "inLights", this ); + addInput( portInL ); + + auto portOutColorTex = new PortOut<NodeTypeTexture>( "outColorTexture", this ); + addOutput( portOutColorTex, m_colorTexture ); + + auto editableTransferFunction = new EditableParameter<std::array<float, 256 * 4>>( "transfer function", &m_editableTransferFunction); + addEditableParameter( editableTransferFunction ); +} + +void VolumeVizualisationNode::init() { + m_framebuffer = new globjects::Framebuffer(); + m_volumeFramebuffer = new globjects::Framebuffer(); + + Ra::Engine::Data::TextureParameters texParams; + texParams.target = gl::GL_TEXTURE_2D; + texParams.minFilter = gl::GL_LINEAR; + texParams.magFilter = gl::GL_LINEAR; + texParams.internalFormat = gl::GL_RGBA32F; + texParams.format = gl::GL_RGBA; + texParams.type = gl::GL_FLOAT; + texParams.name = "Volume"; + m_volumeTexture = new Ra::Engine::Data::Texture( texParams ); + + Ra::Core::Geometry::TriangleMesh mesh = + Ra::Core::Geometry::makeZNormalQuad( Ra::Core::Vector2( -1.f, 1.f ) ); + auto qm = std::make_unique<Ra::Engine::Data::Mesh>( "caller" ); + qm->loadGeometry( std::move( mesh ) ); + m_quadMesh = std::move( qm ); + m_quadMesh->updateGL(); + + const std::string vrtxSrc{"layout (location = 0) in vec3 in_position;\n" + "out vec2 varTexcoord;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(in_position, 1.0);\n" + " varTexcoord = (in_position.xy + 1.0) / 2.0;\n" + "}\n"}; + const std::string frgSrc{ + "out vec4 fragColor;\n" + "in vec2 varTexcoord;\n" + "uniform sampler2D volumeImage;\n" + "void main()\n" + "{\n" + " vec2 size = vec2(textureSize(volumeImage, 0));\n" + " vec4 volColor = texelFetch(volumeImage, ivec2(varTexcoord.xy * size), 0);\n" + " if (volColor.a < 1)\n" + " discard;\n" + " fragColor = vec4(volColor.rgb, 0);\n" + "}\n"}; + Ra::Engine::Data::ShaderConfiguration config{"ComposeVolumeVizualisation"}; + config.addShaderSource( Ra::Engine::Data::ShaderType::ShaderType_VERTEX, vrtxSrc ); + config.addShaderSource( Ra::Engine::Data::ShaderType::ShaderType_FRAGMENT, frgSrc ); + auto added = m_shaderMngr->addShaderProgram( config ); + if ( added ) { m_shader = added.value(); } + + std::array<float, 256 * 4> transferInit; + for ( int i = 0; i < 256 * 4; i += 4 ) + { transferInit[i] = 1.f; } + Ra::Engine::Data::TextureParameters transferTexParams{ "Transfer function", + gl::GL_TEXTURE_2D, + 256, + 1, + 0, + gl::GL_RGBA, + gl::GL_RGBA8, + gl::GL_FLOAT, + gl::GL_CLAMP_TO_BORDER, + gl::GL_CLAMP_TO_BORDER, + gl::GL_CLAMP_TO_BORDER, + gl::GL_LINEAR, + gl::GL_LINEAR, + transferInit.data() }; + m_transferFunctionTexture = new Ra::Engine::Data::Texture( transferTexParams ); + m_transferFunctionTexture->initializeGL(); +#ifdef GRAPH_CALL_TRACE + std::cout << "\e[33m\e[1mVolumeVizualisationNode\e[0m \"" << m_name << "\": initialization." << std::endl; +#endif +} + +void VolumeVizualisationNode::update() { +#ifdef GRAPH_CALL_TRACE + std::cout << "\e[33m\e[1mVolumeVizualisationNode\e[0m \"" << m_name << "\": update." << std::endl; +#endif +} + +void VolumeVizualisationNode::execute() { + Ra::Engine::Data::RenderParameters inPassParams; + // Color + auto inputColor = dynamic_cast<PortIn<NodeTypeTexture>*>( m_inputs[0].get() ); + m_colorTexture = &inputColor->getData(); + auto outputColor = dynamic_cast<PortOut<NodeTypeTexture>*>( m_outputs[0].get() ); + outputColor->setData( m_colorTexture ); + + // Depth + auto inputDepth = dynamic_cast<PortIn<NodeTypeTexture>*>( m_inputs[1].get() ); + NodeTypeTexture* depthTexture = &inputDepth->getData(); + + // Render objects + auto inputRO = dynamic_cast<PortIn<std::vector<NodeTypeRenderObject>>*>( m_inputs[2].get() ); + std::vector<NodeTypeRenderObject> renderObjects; + if ( !inputRO->isLinked() ) + { std::cout << "RenderObjects port is not linked, no render object" << std::endl; } + else + { + renderObjects = inputRO->getData(); +#ifdef GRAPH_CALL_TRACE + std::cout << renderObjects.size() << " render objects" << std::endl; +#endif + } + + // Cameras + auto inputCamera = dynamic_cast<PortIn<std::vector<NodeTypeCamera>>*>( m_inputs[3].get() ); + std::vector<NodeTypeCamera> cameras = inputCamera->getData(); +#ifdef GRAPH_CALL_TRACE + std::cout << cameras.size() << " cameras" << std::endl; +#endif + + // Lights + auto inputLight = dynamic_cast<PortIn<std::vector<NodeTypeLight>>*>( m_inputs[4].get() ); + std::vector<NodeTypeLight> lights; + if ( !inputLight->isLinked() ) + { std::cout << "Lights port is not linked, 0 light" << std::endl; } + else + { + lights = inputLight->getData(); +#ifdef GRAPH_CALL_TRACE + std::cout << lights.size() << " lights" << std::endl; +#endif + } + + m_transferFunctionTexture->updateData( m_editableTransferFunction.data() ); + + static const float clearZeros[4] = {0.0, 0.0, 0.0, 0.0}; + const gl::GLenum buffers[] = {gl::GL_COLOR_ATTACHMENT0}; + m_volumeFramebuffer->bind(); + m_volumeFramebuffer->attachTexture( gl::GL_DEPTH_ATTACHMENT, depthTexture->texture() ); + + gl::glDrawBuffers( 1, buffers ); + gl::glClearBufferfv( gl::GL_COLOR, 0, clearZeros ); + gl::glDepthMask( gl::GL_FALSE ); + gl::glDisable( gl::GL_BLEND ); + gl::glDepthFunc( gl::GL_LEQUAL ); + gl::glEnable( gl::GL_DEPTH_TEST ); + gl::glDepthMask( gl::GL_FALSE ); + inPassParams.addParameter( "material.transferFunction", m_transferFunctionTexture ); + + for ( const auto& l : lights ) + { + inPassParams.addParameter( "imageColor", m_colorTexture ); + inPassParams.addParameter( "imageDepth", depthTexture ); + l->getRenderParameters( inPassParams ); + + for ( const auto& ro : renderObjects ) + { + ro->render( inPassParams, cameras[0], m_idx ); + } + } + + m_framebuffer->bind(); + m_framebuffer->attachTexture( gl::GL_COLOR_ATTACHMENT0, m_colorTexture->texture() ); + gl::glDrawBuffers( 1, buffers ); + gl::glDisable( gl::GL_DEPTH_TEST ); + gl::glEnable( gl::GL_BLEND ); + gl::glBlendFunc( gl::GL_ONE_MINUS_SRC_ALPHA, gl::GL_SRC_ALPHA ); + { + m_shader->bind(); + m_shader->setUniform( "volumeImage", m_volumeTexture, 0 ); + m_quadMesh->render( m_shader ); + } + + // Reset + gl::glDisable( gl::GL_BLEND ); + gl::glEnable( gl::GL_DEPTH_TEST ); + m_framebuffer->detach( gl::GL_COLOR_ATTACHMENT0 ); + m_framebuffer->unbind(); +#ifdef GRAPH_CALL_TRACE + std::cout << "\e[33m\e[1mVolumeVizualisationNode\e[0m \"" << m_name << "\": execute." << std::endl; +#endif +} + +void VolumeVizualisationNode::destroy() { + delete m_framebuffer; + + delete m_transferFunctionTexture; +#ifdef GRAPH_CALL_TRACE + std::cout << "\e[33m\e[1mVolumeVizualisationNode\e[0m \"" << m_name << "\": destroy." << std::endl; +#endif +} + +void VolumeVizualisationNode::resize( uint32_t width, uint32_t height ) { + m_volumeTexture->resize( width, height ); + + m_volumeFramebuffer->bind(); + m_volumeFramebuffer->attachTexture( gl::GL_COLOR_ATTACHMENT0, + m_volumeTexture->texture() ); + + globjects::Framebuffer::unbind(); +#ifdef GRAPH_CALL_TRACE + std::cout << "\e[33m\e[1mVolumeVizualisationNode\e[0m \"" << m_name << "\": resize: " << width << "x" + << height << "." << std::endl; +#endif +} + +void VolumeVizualisationNode::buildRenderTechnique( const Ra::Engine::Rendering::RenderObject* ro, + Ra::Engine::Rendering::RenderTechnique& rt ) const { + std::string resourcesRootDir = m_resourceDir; + auto mat = const_cast<Ra::Engine::Rendering::RenderObject*>( ro )->getMaterial(); + // Only volumes are used by this pass + if ( mat->getMaterialAspect() != Ra::Engine::Data::Material::MaterialAspect::MAT_DENSITY ) + { return; } + // Compute gradients + auto mro = const_cast<Ra::Engine::Rendering::RenderObject*>( ro ); + auto volume = + dynamic_cast<Ra::Core::Geometry::VolumeGrid&>( mro->getMesh()->getAbstractGeometry() ); + auto paramProvider = + std::make_shared<VolumeWithGradientParameterProvider>( mat, volume ); + + if ( auto cfg = Ra::Engine::Data::ShaderConfigurationFactory::getConfiguration( + {"VolumeLightingPass::" + mat->getMaterialName()} ) ) + { rt.setConfiguration( *cfg, m_idx ); } + else + { + // Build the shader configuration + Ra::Engine::Data::ShaderConfiguration theConfig{ + {"VolumeLightingPass::" + mat->getMaterialName()}, + resourcesRootDir + "Shaders/VolumeVisualization/volviz.vert.glsl", + resourcesRootDir + "Shaders/VolumeVisualization/volviz.frag.glsl"}; + /* + // add the material interface to the fragment shader + theConfig.addInclude( "\"" + mat->getMaterialName() + ".glsl\"", + Ra::Engine::ShaderType::ShaderType_FRAGMENT ); + */ + // Add to the ShaderConfigManager + Ra::Engine::Data::ShaderConfigurationFactory::addConfiguration( theConfig ); + // Add to the RenderTechniq + rt.setConfiguration( theConfig, m_idx ); + } + rt.setParametersProvider( paramProvider, m_idx ); +} \ No newline at end of file diff --git a/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/VolumeVizualisationNode.hpp b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/VolumeVizualisationNode.hpp index dc29ec0..2f94508 100644 --- a/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/VolumeVizualisationNode.hpp +++ b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/VolumeVizualisationNode.hpp @@ -5,9 +5,12 @@ #include <Core/Geometry/Volume.hpp> #include <Engine/Data/Material.hpp> +#include <Engine/Data/Texture.hpp> #include <Engine/Data/Mesh.hpp> #include <Engine/Data/ShaderConfigFactory.hpp> +#include <RadiumNBR/NodeGraph/Node.hpp> + #include <numeric> class VolumeWithGradientParameterProvider : public Ra::Engine::Data::ShaderParameterProvider { @@ -55,258 +58,16 @@ class VolumeWithGradientParameterProvider : public Ra::Engine::Data::ShaderParam class VolumeVizualisationNode : public Node { public: - explicit VolumeVizualisationNode( const std::string& name ) : Node( name ) { - auto portInColor = new PortIn<NodeTypeTexture>( "inColorTexture", this ); - addInput( portInColor ); - portInColor->mustBeLinked(); - auto portInDepth = new PortIn<NodeTypeTexture>( "inDepthTexture", this ); - addInput( portInDepth ); - portInDepth->mustBeLinked(); - auto portInRO = new PortIn<std::vector<NodeTypeRenderObject>>( "inRenderObjects", this ); - addInput( portInRO ); - auto portInC = new PortIn<std::vector<NodeTypeCamera>>( "inCameras", this ); - addInput( portInC ); - portInC->mustBeLinked(); - auto portInL = new PortIn<std::vector<NodeTypeLight>>( "inLights", this ); - addInput( portInL ); - - auto portOutColorTex = new PortOut<NodeTypeTexture>( "outColorTexture", this ); - addOutput( portOutColorTex, m_colorTexture ); - - auto editableTransferFunction = new EditableParameter<std::array<float, 256 * 4>>( "transfer function", &m_editableTransferFunction); - addEditableParameter( editableTransferFunction ); - } - - void init() override { - m_framebuffer = new globjects::Framebuffer(); - m_volumeFramebuffer = new globjects::Framebuffer(); - - Ra::Engine::Data::TextureParameters texParams; - texParams.target = gl::GL_TEXTURE_2D; - texParams.minFilter = gl::GL_LINEAR; - texParams.magFilter = gl::GL_LINEAR; - texParams.internalFormat = gl::GL_RGBA32F; - texParams.format = gl::GL_RGBA; - texParams.type = gl::GL_FLOAT; - texParams.name = "Volume"; - m_volumeTexture = new Ra::Engine::Data::Texture( texParams ); - - Ra::Core::Geometry::TriangleMesh mesh = - Ra::Core::Geometry::makeZNormalQuad( Ra::Core::Vector2( -1.f, 1.f ) ); - auto qm = std::make_unique<Ra::Engine::Data::Mesh>( "caller" ); - qm->loadGeometry( std::move( mesh ) ); - m_quadMesh = std::move( qm ); - m_quadMesh->updateGL(); - - const std::string vrtxSrc{"layout (location = 0) in vec3 in_position;\n" - "out vec2 varTexcoord;\n" - "void main()\n" - "{\n" - " gl_Position = vec4(in_position, 1.0);\n" - " varTexcoord = (in_position.xy + 1.0) / 2.0;\n" - "}\n"}; - const std::string frgSrc{ - "out vec4 fragColor;\n" - "in vec2 varTexcoord;\n" - "uniform sampler2D volumeImage;\n" - "void main()\n" - "{\n" - " vec2 size = vec2(textureSize(volumeImage, 0));\n" - " vec4 volColor = texelFetch(volumeImage, ivec2(varTexcoord.xy * size), 0);\n" - " if (volColor.a < 1)\n" - " discard;\n" - " fragColor = vec4(volColor.rgb, 0);\n" - "}\n"}; - Ra::Engine::Data::ShaderConfiguration config{"ComposeVolumeVizualisation"}; - config.addShaderSource( Ra::Engine::Data::ShaderType::ShaderType_VERTEX, vrtxSrc ); - config.addShaderSource( Ra::Engine::Data::ShaderType::ShaderType_FRAGMENT, frgSrc ); - auto added = m_shaderMngr->addShaderProgram( config ); - if ( added ) { m_shader = added.value(); } - - std::array<float, 256 * 4> transferInit; - for ( int i = 0; i < 256 * 4; i += 4 ) - { transferInit[i] = 1.f; } - Ra::Engine::Data::TextureParameters transferTexParams{ "Transfer function", - gl::GL_TEXTURE_2D, - 256, - 1, - 0, - gl::GL_RGBA, - gl::GL_RGBA8, - gl::GL_FLOAT, - gl::GL_CLAMP_TO_BORDER, - gl::GL_CLAMP_TO_BORDER, - gl::GL_CLAMP_TO_BORDER, - gl::GL_LINEAR, - gl::GL_LINEAR, - transferInit.data() }; - m_transferFunctionTexture = new Ra::Engine::Data::Texture( transferTexParams ); - m_transferFunctionTexture->initializeGL(); -#ifdef GRAPH_CALL_TRACE - std::cout << "\e[33m\e[1mVolumeVizualisationNode\e[0m \"" << m_name << "\": initialization." << std::endl; -#endif - } - - void update() override { -#ifdef GRAPH_CALL_TRACE - std::cout << "\e[33m\e[1mVolumeVizualisationNode\e[0m \"" << m_name << "\": update." << std::endl; -#endif - } - - void execute() override { - Ra::Engine::Data::RenderParameters inPassParams; - // Color - auto inputColor = dynamic_cast<PortIn<NodeTypeTexture>*>( m_inputs[0].get() ); - m_colorTexture = &inputColor->getData(); - auto outputColor = dynamic_cast<PortOut<NodeTypeTexture>*>( m_outputs[0].get() ); - outputColor->setData( m_colorTexture ); - - // Depth - auto inputDepth = dynamic_cast<PortIn<NodeTypeTexture>*>( m_inputs[1].get() ); - NodeTypeTexture* depthTexture = &inputDepth->getData(); - - // Render objects - auto inputRO = dynamic_cast<PortIn<std::vector<NodeTypeRenderObject>>*>( m_inputs[2].get() ); - std::vector<NodeTypeRenderObject> renderObjects; - if ( !inputRO->isLinked() ) - { std::cout << "RenderObjects port is not linked, no render object" << std::endl; } - else - { - renderObjects = inputRO->getData(); -#ifdef GRAPH_CALL_TRACE - std::cout << renderObjects.size() << " render objects" << std::endl; -#endif - } - - // Cameras - auto inputCamera = dynamic_cast<PortIn<std::vector<NodeTypeCamera>>*>( m_inputs[3].get() ); - std::vector<NodeTypeCamera> cameras = inputCamera->getData(); -#ifdef GRAPH_CALL_TRACE - std::cout << cameras.size() << " cameras" << std::endl; -#endif - - // Lights - auto inputLight = dynamic_cast<PortIn<std::vector<NodeTypeLight>>*>( m_inputs[4].get() ); - std::vector<NodeTypeLight> lights; - if ( !inputLight->isLinked() ) - { std::cout << "Lights port is not linked, 0 light" << std::endl; } - else - { - lights = inputLight->getData(); -#ifdef GRAPH_CALL_TRACE - std::cout << lights.size() << " lights" << std::endl; -#endif - } + explicit VolumeVizualisationNode( const std::string& name ); - m_transferFunctionTexture->updateData( m_editableTransferFunction.data() ); - - static const float clearZeros[4] = {0.0, 0.0, 0.0, 0.0}; - const gl::GLenum buffers[] = {gl::GL_COLOR_ATTACHMENT0}; - m_volumeFramebuffer->bind(); - m_volumeFramebuffer->attachTexture( gl::GL_DEPTH_ATTACHMENT, depthTexture->texture() ); - - gl::glDrawBuffers( 1, buffers ); - gl::glClearBufferfv( gl::GL_COLOR, 0, clearZeros ); - gl::glDepthMask( gl::GL_FALSE ); - gl::glDisable( gl::GL_BLEND ); - gl::glDepthFunc( gl::GL_LEQUAL ); - gl::glEnable( gl::GL_DEPTH_TEST ); - gl::glDepthMask( gl::GL_FALSE ); - inPassParams.addParameter( "material.transferFunction", m_transferFunctionTexture ); - - for ( const auto& l : lights ) - { - inPassParams.addParameter( "imageColor", m_colorTexture ); - inPassParams.addParameter( "imageDepth", depthTexture ); - l->getRenderParameters( inPassParams ); - - for ( const auto& ro : renderObjects ) - { - ro->render( inPassParams, cameras[0], m_idx ); - } - } - - m_framebuffer->bind(); - m_framebuffer->attachTexture( gl::GL_COLOR_ATTACHMENT0, m_colorTexture->texture() ); - gl::glDrawBuffers( 1, buffers ); - gl::glDisable( gl::GL_DEPTH_TEST ); - gl::glEnable( gl::GL_BLEND ); - gl::glBlendFunc( gl::GL_ONE_MINUS_SRC_ALPHA, gl::GL_SRC_ALPHA ); - { - m_shader->bind(); - m_shader->setUniform( "volumeImage", m_volumeTexture, 0 ); - m_quadMesh->render( m_shader ); - } - - // Reset - gl::glDisable( gl::GL_BLEND ); - gl::glEnable( gl::GL_DEPTH_TEST ); - m_framebuffer->detach( gl::GL_COLOR_ATTACHMENT0 ); - m_framebuffer->unbind(); -#ifdef GRAPH_CALL_TRACE - std::cout << "\e[33m\e[1mVolumeVizualisationNode\e[0m \"" << m_name << "\": execute." << std::endl; -#endif - } - - void destroy() override { - delete m_framebuffer; - - delete m_transferFunctionTexture; -#ifdef GRAPH_CALL_TRACE - std::cout << "\e[33m\e[1mVolumeVizualisationNode\e[0m \"" << m_name << "\": destroy." << std::endl; -#endif - } - - void resize( uint32_t width, uint32_t height ) override { - m_volumeTexture->resize( width, height ); - - m_volumeFramebuffer->bind(); - m_volumeFramebuffer->attachTexture( gl::GL_COLOR_ATTACHMENT0, - m_volumeTexture->texture() ); - - globjects::Framebuffer::unbind(); -#ifdef GRAPH_CALL_TRACE - std::cout << "\e[33m\e[1mVolumeVizualisationNode\e[0m \"" << m_name << "\": resize: " << width << "x" - << height << "." << std::endl; -#endif - } + void init() override; + void update() override; + void execute() override; + void destroy() override; + void resize( uint32_t width, uint32_t height ) override; void buildRenderTechnique( const Ra::Engine::Rendering::RenderObject* ro, - Ra::Engine::Rendering::RenderTechnique& rt ) const override { - std::string resourcesRootDir = m_resourceDir; - auto mat = const_cast<Ra::Engine::Rendering::RenderObject*>( ro )->getMaterial(); - // Only volumes are used by this pass - if ( mat->getMaterialAspect() != Ra::Engine::Data::Material::MaterialAspect::MAT_DENSITY ) - { return; } - // Compute gradients - auto mro = const_cast<Ra::Engine::Rendering::RenderObject*>( ro ); - auto volume = - dynamic_cast<Ra::Core::Geometry::VolumeGrid&>( mro->getMesh()->getAbstractGeometry() ); - auto paramProvider = - std::make_shared<VolumeWithGradientParameterProvider>( mat, volume ); - - if ( auto cfg = Ra::Engine::Data::ShaderConfigurationFactory::getConfiguration( - {"VolumeLightingPass::" + mat->getMaterialName()} ) ) - { rt.setConfiguration( *cfg, m_idx ); } - else - { - // Build the shader configuration - Ra::Engine::Data::ShaderConfiguration theConfig{ - {"VolumeLightingPass::" + mat->getMaterialName()}, - resourcesRootDir + "Shaders/VolumeVisualization/volviz.vert.glsl", - resourcesRootDir + "Shaders/VolumeVisualization/volviz.frag.glsl"}; - /* - // add the material interface to the fragment shader - theConfig.addInclude( "\"" + mat->getMaterialName() + ".glsl\"", - Ra::Engine::ShaderType::ShaderType_FRAGMENT ); - */ - // Add to the ShaderConfigManager - Ra::Engine::Data::ShaderConfigurationFactory::addConfiguration( theConfig ); - // Add to the RenderTechniq - rt.setConfiguration( theConfig, m_idx ); - } - rt.setParametersProvider( paramProvider, m_idx ); - } + Ra::Engine::Rendering::RenderTechnique& rt ) const override; static const std::string getTypename() { return "Volume Vizualisation Pass"; } diff --git a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp index 1969de4..26bc5ae 100644 --- a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp +++ b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp @@ -476,7 +476,14 @@ bool RenderGraph::compile() { { if ( infoNodes.find( n.get() ) != infoNodes.end() ) { - n->setIndex( idx++ ); + for ( size_t i = 0; i < n->getInputs().size(); i++ ) { + // If the node accepts render objects as input + // then it needs an index for the render techniques + if (n->getInputs()[i]->getType() == typeid(std::vector<NodeTypeRenderObject>).hash_code()) { + n->setIndex( idx++ ); + break; + } + } n->setResourcesDir( m_resourceDir ); n->setShaderProgramManager( m_shaderMngr ); afterCullingNodes.push_back( n ); diff --git a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.hpp b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.hpp index 6393b2f..dad855d 100644 --- a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.hpp +++ b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.hpp @@ -4,6 +4,7 @@ #include <RadiumNBR/NodeGraph/PremadeNodes/DataNode.hpp> #include <RadiumNBR/NodeGraph/PremadeNodes/DisplaySinkNode.hpp> +// TODO : Find a new name, it is not a RENDER graph only anymore class NodeBasedRenderer_LIBRARY_API RenderGraph : public Node { public: /// Constructor. -- GitLab