From 65ab3c09d65e8444ee5fff13bb63fea8add8c174 Mon Sep 17 00:00:00 2001
From: ZaOniRinku <zaonirinku@gmail.com>
Date: Thu, 3 Feb 2022 11:47:06 +0100
Subject: [PATCH] seminar demo

---
 src/MaraBoutage/RadiumPlayer.cpp              |  21 ++
 src/libRender/CMakeLists.txt                  |   2 +
 .../PremadeNodes/Demo/DifferenceNode.hpp      | 138 ++++++++++++
 .../PremadeNodes/Demo/SimpleNode.hpp          | 207 ++++++++++++++++++
 .../NodeGraph/PremadeNodes/LocalLightNode.cpp |  18 +-
 .../NodeGraph/PremadeNodes/LocalLightNode.hpp |   2 -
 .../PremadeNodes/PremadeNodesIncludes.hpp     |   4 +-
 7 files changed, 373 insertions(+), 19 deletions(-)
 create mode 100644 src/libRender/RadiumNBR/NodeGraph/PremadeNodes/Demo/DifferenceNode.hpp
 create mode 100644 src/libRender/RadiumNBR/NodeGraph/PremadeNodes/Demo/SimpleNode.hpp

diff --git a/src/MaraBoutage/RadiumPlayer.cpp b/src/MaraBoutage/RadiumPlayer.cpp
index 7425bbb..3cbec7d 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 db1efed..5ebf341 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 0000000..3ba4786
--- /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 0000000..263198a
--- /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 ca2bb1e..bfe98da 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 49ce0d2..1744235 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 ae67ce1..9e19262 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
-- 
GitLab