diff --git a/src/MaraBoutage/RadiumPlayer.cpp b/src/MaraBoutage/RadiumPlayer.cpp index 7425bbbda07ffab2837784537ef60d8e28bd5fae..3cbec7dae97e4dc3a7ce5aa719652756a8b2f91d 100644 --- a/src/MaraBoutage/RadiumPlayer.cpp +++ b/src/MaraBoutage/RadiumPlayer.cpp @@ -171,6 +171,19 @@ class NodeCreator void RadiumPlayer::initializeNodeFactory() { NodeFactory::initializeNodeFactory(); + + // Demo + NodeFactory::registerNode<SimpleNode>( []( const nlohmann::json& data ) { + auto simpleNode = + new SimpleNode( "SimpleNode" + std::to_string( NodeFactory::newNodeId() ) ); + return simpleNode; + } ); + + NodeFactory::registerNode<DifferenceNode>( []( const nlohmann::json& data ) { + auto differenceNode = + new DifferenceNode( "DifferenceNode" + std::to_string( NodeFactory::newNodeId() ) ); + return differenceNode; + } ); } void RadiumPlayer::openNodeEditor( MainWindow* mainWindow, @@ -242,6 +255,14 @@ void RadiumPlayer::openNodeEditor( MainWindow* mainWindow, ret->registerModel<NodeAdapterModel<WireframeNode>>( NodeCreator<NodeAdapterModel<WireframeNode>>( renderer->getRenderGraph() ), "Premade Nodes" ); + + // Demo + ret->registerModel<NodeAdapterModel<SimpleNode>>( + NodeCreator<NodeAdapterModel<SimpleNode>>( renderer->getRenderGraph() ), + "Premade Nodes" ); + ret->registerModel<NodeAdapterModel<DifferenceNode>>( + NodeCreator<NodeAdapterModel<DifferenceNode>>( renderer->getRenderGraph() ), + "Premade Nodes" ); ret->registerModel<SourceNodeModel<NodeTypeColor>>( NodeCreator<SourceNodeModel<NodeTypeColor>>( renderer->getRenderGraph() ), diff --git a/src/libRender/CMakeLists.txt b/src/libRender/CMakeLists.txt index db1efed14a99596726e34beaae2cac4bb9e66081..5ebf3411c6a60e333834d466fa28f03956c54916 100644 --- a/src/libRender/CMakeLists.txt +++ b/src/libRender/CMakeLists.txt @@ -104,6 +104,8 @@ set(public_headers RadiumNBR/NodeGraph/PremadeNodes/UINode.hpp RadiumNBR/NodeGraph/PremadeNodes/WireframeNode.hpp RadiumNBR/NodeGraph/PremadeNodes/DisplaySinkNode.hpp + RadiumNBR/NodeGraph/PremadeNodes/Demo/SimpleNode.hpp + RadiumNBR/NodeGraph/PremadeNodes/Demo/DifferenceNode.hpp RadiumNBR/NodeGraph/PremadeNodes/PremadeNodesIncludes.hpp # MULTI PASS diff --git a/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/Demo/DifferenceNode.hpp b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/Demo/DifferenceNode.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3ba478661032ae4a8e9fa9af54cc60c890e6a5e7 --- /dev/null +++ b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/Demo/DifferenceNode.hpp @@ -0,0 +1,138 @@ +#pragma once +#include <RadiumNBR/NodeGraph/Node.hpp> + +#include <globjects/Framebuffer.h> + +#include <Core/Geometry/MeshPrimitives.hpp> +#include <Engine/Data/Mesh.hpp> +#include <Engine/Data/RenderParameters.hpp> + +class NodeBasedRenderer_LIBRARY_API DifferenceNode : public Node +{ + public: + explicit DifferenceNode( const std::string& name ) : Node( name ) { + auto portInColor1 = new PortIn<NodeTypeTexture>( "inColorTexture1", this ); + addInput( portInColor1 ); + portInColor1->mustBeLinked(); + auto portInColor2 = new PortIn<NodeTypeTexture>( "inColorTexture2", this ); + addInput( portInColor2 ); + portInColor2->mustBeLinked(); + + Ra::Engine::Data::TextureParameters colorTexParams = { "Color Texture", + gl::GL_TEXTURE_2D, + 1, + 1, + 1, + gl::GL_RGBA, + gl::GL_RGBA32F, + gl::GL_FLOAT, + gl::GL_CLAMP_TO_EDGE, + gl::GL_CLAMP_TO_EDGE, + gl::GL_CLAMP_TO_EDGE, + gl::GL_LINEAR, + gl::GL_LINEAR, + nullptr }; + m_colorTexture = new Ra::Engine::Data::Texture( colorTexParams ); + + auto portOutColorTex = new PortOut<NodeTypeTexture>( "outColorTexture", this ); + addOutput( portOutColorTex, m_colorTexture ); + } + + void init() override { + m_framebuffer = new globjects::Framebuffer(); + + 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 composeVertexShader{ "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) * 0.5;\n" + "}\n" }; + const std::string composeFragmentShader{ + "layout (location = 0) out vec4 out_diff;\n" + "uniform sampler2D tex1_sampler;\n" + "uniform sampler2D tex2_sampler;\n" + "in vec2 varTexcoord;\n" + "void main() {\n" + " out_diff = texture(tex1_sampler, varTexcoord) - texture(tex2_sampler, varTexcoord);\n" + "}" }; + + Ra::Engine::Data::ShaderConfiguration config{ "ComposeDifference" }; + config.addShaderSource( Ra::Engine::Data::ShaderType::ShaderType_VERTEX, + composeVertexShader ); + config.addShaderSource( Ra::Engine::Data::ShaderType::ShaderType_FRAGMENT, + composeFragmentShader ); + auto added = m_shaderMngr->addShaderProgram( config ); + if ( added ) { m_shader = added.value(); } + } + + void update() override {} + + void execute() override { + Ra::Engine::Data::RenderParameters inPassParams; + + // Texture 1 + auto inputColor1 = + dynamic_cast<PortIn<NodeTypeTexture>*>( m_inputs[0].get() ); + NodeTypeTexture* texColor1 = &inputColor1->getData(); + + // Texture 2 + auto inputColor2 = dynamic_cast<PortIn<NodeTypeTexture>*>( m_inputs[1].get() ); + NodeTypeTexture* texColor2 = &inputColor2->getData(); + + m_framebuffer->bind(); + m_framebuffer->attachTexture( gl::GL_COLOR_ATTACHMENT0, m_colorTexture->texture() ); + + const gl::GLenum buffers[] = { gl::GL_COLOR_ATTACHMENT0 }; + gl::glDrawBuffers( 1, buffers ); + gl::glDisable( gl::GL_DEPTH_TEST ); + gl::glDepthMask( gl::GL_FALSE ); + gl::glColorMask( gl::GL_TRUE, gl::GL_TRUE, gl::GL_TRUE, gl::GL_TRUE ); + + float clearBlack[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + gl::glClearBufferfv( gl::GL_COLOR, 0, clearBlack ); + + gl::glDisable( gl::GL_BLEND ); + + m_shader->bind(); + m_shader->setUniform( "tex1_sampler", texColor1, 0 ); + m_shader->setUniform( "tex2_sampler", texColor2, 1 ); + + m_quadMesh->render( m_shader ); + + m_framebuffer->detach( gl::GL_COLOR_ATTACHMENT0 ); + m_framebuffer->unbind(); + } + + void destroy() override { + delete m_framebuffer; + delete m_colorTexture; + } + + void resize( uint32_t width, uint32_t height ) override { + m_colorTexture->resize( width, height ); + } + + void buildRenderTechnique( const Ra::Engine::Rendering::RenderObject* ro, + Ra::Engine::Rendering::RenderTechnique& rt ) const override { + + } + + static const std::string getTypename() { return "Difference"; } + + private: + Ra::Engine::Data::Texture* m_colorTexture{ nullptr }; + + std::unique_ptr<Ra::Engine::Data::Displayable> m_quadMesh{ nullptr }; + + const Ra::Engine::Data::ShaderProgram* m_shader{ nullptr }; + + globjects::Framebuffer* m_framebuffer{ nullptr }; +}; diff --git a/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/Demo/SimpleNode.hpp b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/Demo/SimpleNode.hpp new file mode 100644 index 0000000000000000000000000000000000000000..263198a3e66100cb1c70ca732eadcb66055ef097 --- /dev/null +++ b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/Demo/SimpleNode.hpp @@ -0,0 +1,207 @@ +#pragma once +#include <RadiumNBR/NodeGraph/Node.hpp> + +#include <globjects/Framebuffer.h> + +class NodeBasedRenderer_LIBRARY_API SimpleNode : public Node +{ + public: + explicit SimpleNode(const std::string& name) : Node( name ) { + 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 ); + + Ra::Engine::Data::TextureParameters colorTexParams = { "Color Texture", + gl::GL_TEXTURE_2D, + 1, + 1, + 1, + gl::GL_RGBA, + gl::GL_RGBA32F, + gl::GL_FLOAT, + gl::GL_CLAMP_TO_EDGE, + gl::GL_CLAMP_TO_EDGE, + gl::GL_CLAMP_TO_EDGE, + gl::GL_LINEAR, + gl::GL_LINEAR, + nullptr }; + m_colorTexture = new Ra::Engine::Data::Texture( colorTexParams ); + + auto portOutColorTex = new PortOut<NodeTypeTexture>( "outColorTexture", this ); + addOutput( portOutColorTex, m_colorTexture ); + } + + void init() override { + m_framebuffer = new globjects::Framebuffer(); + + Ra::Engine::Data::TextureParameters depthTexParams = { "Depth Texture", + gl::GL_TEXTURE_2D, + 1, + 1, + 1, + gl::GL_DEPTH_COMPONENT, + gl::GL_DEPTH_COMPONENT24, + gl::GL_UNSIGNED_INT, + gl::GL_CLAMP_TO_EDGE, + gl::GL_CLAMP_TO_EDGE, + gl::GL_CLAMP_TO_EDGE, + gl::GL_NEAREST, + gl::GL_NEAREST, + nullptr }; + m_depthTexture = new Ra::Engine::Data::Texture( depthTexParams ); + + float blankAO[4] = { 1.f, 1.f, 1.f, 1.f }; + Ra::Engine::Data::TextureParameters texParams; + texParams.target = gl::GL_TEXTURE_2D; + texParams.width = 1; + texParams.height = 1; + texParams.internalFormat = gl::GL_RGBA32F; + texParams.format = gl::GL_RGBA; + texParams.type = gl::GL_FLOAT; + texParams.minFilter = gl::GL_NEAREST; + texParams.magFilter = gl::GL_NEAREST; + texParams.name = "Blank AO"; + texParams.texels = &blankAO; + m_blankAO = new Ra::Engine::Data::Texture( texParams ); + m_blankAO->initializeGL(); + } + + void update() override { + + } + + void execute() override { + Ra::Engine::Data::RenderParameters inPassParams; + + // Render objects + auto inputRO = + dynamic_cast<PortIn<std::vector<NodeTypeRenderObject>>*>( m_inputs[0].get() ); + std::vector<NodeTypeRenderObject> renderObjects; + if ( !inputRO->isLinked() ) + { +#ifdef GRAPH_CALL_TRACE + std::cout << "RenderObjects port is not linked, no render object" << std::endl; +#endif + } + 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[1].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[2].get() ); + std::vector<NodeTypeLight> lights; + if ( !inputLight->isLinked() ) + { +#ifdef GRAPH_CALL_TRACE + std::cout << "Lights port is not linked, 0 light" << std::endl; +#endif + } + else + { + lights = inputLight->getData(); +#ifdef GRAPH_CALL_TRACE + std::cout << lights.size() << " lights" << std::endl; +#endif + } + + inPassParams.addParameter( "amb_occ_sampler", m_blankAO ); + + m_framebuffer->bind(); + m_framebuffer->attachTexture( gl::GL_DEPTH_ATTACHMENT, m_depthTexture->texture() ); + m_framebuffer->attachTexture( gl::GL_COLOR_ATTACHMENT0, m_colorTexture->texture() ); + + const gl::GLenum buffers[] = { gl::GL_COLOR_ATTACHMENT0 }; + gl::glDrawBuffers( 1, buffers ); + gl::glEnable( gl::GL_DEPTH_TEST ); + gl::glDepthMask( gl::GL_TRUE ); + gl::glDepthFunc( gl::GL_LESS ); + gl::glColorMask( gl::GL_TRUE, gl::GL_TRUE, gl::GL_TRUE, gl::GL_TRUE ); + + float clearBlack[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + float clearDepth = 1.0f; + gl::glClearBufferfv( gl::GL_COLOR, 0, clearBlack ); + gl::glClearBufferfv( gl::GL_DEPTH, 0, &clearDepth ); + + gl::glDisable( gl::GL_BLEND ); + + if ( lights.size() > 0 ) + { + for ( const auto& l : lights ) + { + l->getRenderParameters( inPassParams ); + + for ( const auto& ro : renderObjects ) + { ro->render( inPassParams, cameras[0], m_idx ); } + } + } + + m_framebuffer->detach( gl::GL_DEPTH_ATTACHMENT ); + m_framebuffer->detach( gl::GL_COLOR_ATTACHMENT0 ); + m_framebuffer->unbind(); + } + + void destroy() override { + delete m_framebuffer; + delete m_colorTexture; + delete m_depthTexture; + } + + void resize(uint32_t width, uint32_t height) override { + m_colorTexture->resize( width, height ); + m_depthTexture->resize( width, height ); + } + + void buildRenderTechnique(const Ra::Engine::Rendering::RenderObject* ro, + Ra::Engine::Rendering::RenderTechnique& rt) const override { + auto mat = const_cast<Ra::Engine::Rendering::RenderObject*>( ro )->getMaterial(); + // Volumes are not used in EnvLightPass + if ( mat->getMaterialAspect() == Ra::Engine::Data::Material::MaterialAspect::MAT_DENSITY ) + { return; } + + if ( auto cfg = Ra::Engine::Data::ShaderConfigurationFactory::getConfiguration( + { "LocalLightPass::" + mat->getMaterialName() } ) ) + { rt.setConfiguration( *cfg, m_idx ); } + else + { + std::string resourcesRootDir = m_resourceDir; + // Build the shader configuration + Ra::Engine::Data::ShaderConfiguration theConfig{ + { "LocalLightPass::" + mat->getMaterialName() }, + resourcesRootDir + "Shaders/LocalLightPass/lightpass.vert.glsl", + resourcesRootDir + "Shaders/LocalLightPass/lightpass.frag.glsl" }; + // add the material interface to the fragment shader + theConfig.addInclude( "\"" + mat->getMaterialName() + ".glsl\"", + Ra::Engine::Data::ShaderType::ShaderType_FRAGMENT ); + // Add to the ShaderConfigManager + Ra::Engine::Data::ShaderConfigurationFactory::addConfiguration( theConfig ); + // Add to the RenderTechnique + rt.setConfiguration( theConfig, m_idx ); + } + rt.setParametersProvider( mat, m_idx ); + } + + static const std::string getTypename() { return "Simple Render Pass"; } + + private: + Ra::Engine::Data::Texture* m_colorTexture{ nullptr }; + Ra::Engine::Data::Texture* m_depthTexture{ nullptr }; + + Ra::Engine::Data::Texture* m_blankAO{ nullptr }; + + globjects::Framebuffer* m_framebuffer{ nullptr }; +}; diff --git a/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/LocalLightNode.cpp b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/LocalLightNode.cpp index ca2bb1ee5529bb2a2d4ea6d1735f136d0ba9f593..bfe98daf6306fbd9f727243dd852164d81c509fd 100644 --- a/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/LocalLightNode.cpp +++ b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/LocalLightNode.cpp @@ -22,9 +22,6 @@ LocalLightNode::LocalLightNode( const std::string& name ) : Node( name ) { auto portOutColorTex = new PortOut<NodeTypeTexture>( "outColorTexture", this ); addOutput( portOutColorTex, m_colorTexture ); - - auto editableDepthWrite = new EditableParameter( "depth write ?", &m_editableDepthWrite ); - addEditableParameter( editableDepthWrite ); } void LocalLightNode::init() { @@ -120,19 +117,8 @@ void LocalLightNode::execute() { const gl::GLenum buffers[] = {gl::GL_COLOR_ATTACHMENT0}; gl::glDrawBuffers( 1, buffers ); gl::glEnable( gl::GL_DEPTH_TEST ); - if ( m_editableDepthWrite ) { - float clearDepth = 1.0f; - gl::glClearBufferfv( gl::GL_DEPTH, 0, &clearDepth ); - gl::glDepthMask( gl::GL_TRUE ); - gl::glDepthFunc( gl::GL_LESS ); - gl::glPolygonOffset( 1.1f, 1.0f ); - gl::glEnable( gl::GL_POLYGON_OFFSET_FILL ); - } - else - { - gl::glDepthMask( gl::GL_FALSE ); - gl::glDepthFunc( gl::GL_EQUAL ); - } + gl::glDepthMask( gl::GL_FALSE ); + gl::glDepthFunc( gl::GL_EQUAL ); gl::glColorMask( gl::GL_TRUE, gl::GL_TRUE, gl::GL_TRUE, gl::GL_TRUE ); diff --git a/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/LocalLightNode.hpp b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/LocalLightNode.hpp index 49ce0d20a8fe662685627ffad1abd65f8621afbe..1744235c3f480b32540f61cb873b8a95c99ac913 100644 --- a/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/LocalLightNode.hpp +++ b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/LocalLightNode.hpp @@ -23,6 +23,4 @@ class NodeBasedRenderer_LIBRARY_API LocalLightNode : public Node Ra::Engine::Data::Texture* m_blankAO{ nullptr }; globjects::Framebuffer* m_framebuffer{ nullptr }; - - bool m_editableDepthWrite{ false }; }; diff --git a/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/PremadeNodesIncludes.hpp b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/PremadeNodesIncludes.hpp index ae67ce1d974e5cbbfd3e6d0f87e74c786c9d3a33..9e1926219b56ea696ad448d5bd2ad3f9a4a2e220 100644 --- a/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/PremadeNodesIncludes.hpp +++ b/src/libRender/RadiumNBR/NodeGraph/PremadeNodes/PremadeNodesIncludes.hpp @@ -19,4 +19,6 @@ #include <RadiumNBR/NodeGraph/PremadeNodes/VolumeNode.hpp> #include <RadiumNBR/NodeGraph/PremadeNodes/VolumeVizualisationNode.hpp> #include <RadiumNBR/NodeGraph/PremadeNodes/WireframeNode.hpp> -#include <RadiumNBR/NodeGraph/PremadeNodes/ZGeomPrepassNode.hpp> \ No newline at end of file +#include <RadiumNBR/NodeGraph/PremadeNodes/ZGeomPrepassNode.hpp> +#include <RadiumNBR/NodeGraph/PremadeNodes/Demo/SimpleNode.hpp> +#include <RadiumNBR/NodeGraph/PremadeNodes/Demo/DifferenceNode.hpp> \ No newline at end of file