From 26159586cfe49d007eca3987cb5b2e82eee59633 Mon Sep 17 00:00:00 2001
From: Mathias Paulin <mathias.paulin@irit.fr>
Date: Thu, 11 Mar 2021 18:53:57 +0100
Subject: [PATCH] Add simple demo of a custom pipeline.

---
 src/CMakeLists.txt         |   3 +
 src/DemoApp/CMakeLists.txt |  88 ++++++++++++++++++++++++++
 src/DemoApp/main.cpp       | 124 +++++++++++++++++++++++++++++++++++++
 3 files changed, 215 insertions(+)
 create mode 100644 src/DemoApp/CMakeLists.txt
 create mode 100644 src/DemoApp/main.cpp

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ad746cd..7d3b25d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -5,4 +5,7 @@ endif (WITH_H3D_SUPPORT)
 add_subdirectory(Plugin)
 set(MARA_IN_BUILD_TREE True)
 add_subdirectory(Mara EXCLUDE_FROM_ALL)
+set(VIEWER_IN_BUILD_TREE True)
+add_subdirectory(DemoApp EXCLUDE_FROM_ALL)
+
 #add_subdirectory(Mara)
diff --git a/src/DemoApp/CMakeLists.txt b/src/DemoApp/CMakeLists.txt
new file mode 100644
index 0000000..e51389d
--- /dev/null
+++ b/src/DemoApp/CMakeLists.txt
@@ -0,0 +1,88 @@
+cmake_minimum_required(VERSION 3.6)
+if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_GREATER "3.9")
+    cmake_policy(SET CMP0071 NEW)
+endif ()
+if (APPLE)
+    cmake_policy(SET CMP0042 NEW)
+endif (APPLE)
+
+set(CMAKE_DISABLE_SOURCE_CHANGES ON)
+set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
+
+project(SimpleViewer VERSION 0.0.1)
+
+if (NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE Release)
+endif ()
+
+# Set default install location to installed-<Compiler_ID> folder in build dir
+# we do not want to install to /usr by default
+if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+    set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/installed-${CMAKE_CXX_COMPILER_ID}-${CMAKE_BUILD_TYPE}" CACHE PATH
+        "Install path prefix, prepended onto install directories." FORCE)
+    message("Set install prefix to ${CMAKE_INSTALL_PREFIX}")
+endif ()
+
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+# ///////////////////////////////
+find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
+set(Qt5_LIBRARIES Qt5::Core Qt5::Widgets)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+find_package(Radium REQUIRED Core Engine Gui PluginBase IO)
+
+set(app_sources
+    main.cpp
+    )
+set(app_headers
+    )
+
+set(app_uis
+    )
+qt5_wrap_ui(app_uis_moc ${app_uis})
+
+set(app_resources
+
+    )
+
+add_executable(${PROJECT_NAME} MACOSX_BUNDLE
+    ${app_sources}
+    ${app_headers}
+    ${app_uis}
+    ${app_resources}
+    )
+
+target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17)
+target_include_directories(${PROJECT_NAME} PRIVATE
+    ${RADIUM_INCLUDE_DIRS}
+    ${CMAKE_CURRENT_BINARY_DIR} # Moc
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    )
+
+
+
+if (VIEWER_IN_BUILD_TREE)
+    message(STATUS " *** ${PROJECT_NAME} *** Building application into the lib and plugin build tree")
+else ()
+    message(STATUS " *** ${PROJECT_NAME} *** Building application from the installed library")
+    # If the application is built as standalone, uses libGLTF from its installed tree
+    find_package(RadiumNBR REQUIRED)
+endif ()
+
+target_link_libraries(${PROJECT_NAME}
+    PUBLIC
+    Radium::Core Radium::Engine Radium::Gui Radium::IO
+    RadiumNBR::NBR
+    RadiumNBR::NBRGui
+#    ${Qt5_LIBRARIES}
+    )
+
+configure_radium_app(
+    NAME ${PROJECT_NAME}
+    USE_PLUGINS
+)
diff --git a/src/DemoApp/main.cpp b/src/DemoApp/main.cpp
new file mode 100644
index 0000000..defd1fb
--- /dev/null
+++ b/src/DemoApp/main.cpp
@@ -0,0 +1,124 @@
+// Include Radium base application and its simple Gui
+#include <Gui/BaseApplication.hpp>
+#include <Gui/RadiumWindow/SimpleWindowFactory.hpp>
+
+// Include the customizable renderer system (only the used part here)
+#include <RadiumNBR/NodeBasedRenderer.hpp>
+#include <RadiumNBR/Passes/ClearPass.hpp>
+#include <RadiumNBR/Passes/GeomPrepass.hpp>
+#include <RadiumNBR/Passes/WireframePass.hpp>
+
+
+/**
+ * This class parameterize the renderer just after the OpenGL system was initialized.
+ * In the functor, The OpenGL context of the drawing window is activated.
+ */
+class RendererBuilder {
+  public:
+    void operator ()(RadiumNBR::NodeBasedRenderer *renderer, int w, int h) {
+        LOG( Ra::Core::Utils::logINFO ) << "Customizing the renderer " << renderer->getRendererName();
+
+        //! [Caching some helpers and data from the Engine and the renderer]
+        auto resourcesCheck = Ra::Core::Resources::getResourcesPath(
+            reinterpret_cast<void*>( &RadiumNBR::NodeBasedRendererMagic ), { "Resources/RadiumNBR" } );
+        if ( !resourcesCheck )
+        {
+            LOG( Ra::Core::Utils::logERROR ) << "Unable to find resources for NodeBasedRenderer!";
+            return;
+        } else {
+            LOG( Ra::Core::Utils::logINFO ) << "NodeBasedRenderer Resources are at " << *resourcesCheck;
+        }
+        auto resourcesPath{ *resourcesCheck };
+        auto shaderManager = Ra::Engine::RadiumEngine::getInstance()->getShaderProgramManager();
+        auto colortexture = renderer->sharedTextures().find( "Linear RGB (RadiumNBR)");
+        auto depthtexture = renderer->sharedTextures().find( "Depth (RadiumNBR)" );
+        //! [Caching some helpers and data from the Engine and the renderer]
+
+        //! [Adding a clear-screen pass]
+        {
+            // pass that draw no object and is positionned at rank 0
+            auto pass = std::make_shared<RadiumNBR::ClearPass>( nullptr, 0 );
+            // set the output of the pass : clear the renderer Linear RGB output texture
+            pass->setOutput( *colortexture );
+            // set the clear color (pass internal state)
+            pass->setBackground( renderer->getBackgroundColor());
+            pass->initializePass( w, h, shaderManager );
+            // add the pass to the renderer and activate it
+            renderer->addPass(pass, pass->index());
+            pass->activate();
+        }
+        //! [Adding a clear-screen pass]
+
+        //! [Adding a Z-only pass]
+        {
+            // the z-only pass takes all the objects and draw them only on the shared depth buffer.
+            auto pass = std::make_shared<RadiumNBR::GeomPrePass>( renderer->allRenderObjects(), 1 );
+            // set the output to the shared depth texture
+            pass->setOutput( *depthtexture );
+            // configure access to shader/resources files and initialize the pass
+            pass->setResourcesDir( resourcesPath );
+            pass->initializePass( w, h, shaderManager );
+            // add the pass to the renderer and activate it
+            renderer->addPass(pass, pass->index());
+            pass->activate();
+        }
+        //! [Adding a Z-only pass]
+
+        //! [Adding a wireframe pass]
+        {
+            // this pass draw all the objects in wareframe, using the shared z-buffer for hidden line removal and drawing
+            // in the shared color buffer.
+            auto pass = std::make_shared<RadiumNBR::WireframePass>( renderer->allRenderObjects(), 2 );
+            // set the input/output textures
+            pass->setInputs( *depthtexture );
+            pass->setOutput( *colortexture );
+            // configure access to shader/resources files and initialize the pass
+            pass->setResourcesDir( resourcesPath );
+            pass->initializePass( w, h, shaderManager );
+            // add the pass to the renderer and activate it
+            renderer->addPass(pass, pass->index());
+            pass->activate();
+        }
+        //! [Adding a wireframe pass]
+    }
+};
+
+/**
+ * Define a factory that set the wanted renderer on the window
+ */
+class DemoWindowFactory : public Ra::Gui::BaseApplication::WindowFactory
+{
+  public:
+    DemoWindowFactory() = delete;
+    ~DemoWindowFactory() = default;
+    explicit DemoWindowFactory( std::shared_ptr<RadiumNBR::NodeBasedRenderer> r) : renderer(r) {}
+    inline Ra::Gui::MainWindowInterface* createMainWindow() const override {
+        auto window = new Ra::Gui::SimpleWindow();
+        window->addRenderer(renderer->getRendererName(), renderer);
+        return window;
+    }
+  private:
+    std::shared_ptr<RadiumNBR::NodeBasedRenderer> renderer;
+};
+
+int main( int argc, char* argv[] ) {
+    if ( argc < 2 )
+    {
+        std::cerr << "usage : " << argv[0] << " -f <scene_file>" << std::endl;
+        return 1;
+    }
+    //! [Instatiating the renderer giving a customization functor]
+    auto renderer = std::make_shared<RadiumNBR::NodeBasedRenderer>(RendererBuilder{} );
+    //! [Instatiating the renderer giving a customization functor]
+
+    //! [Instatiating the application]
+    Ra::Gui::BaseApplication app( argc, argv );
+    //! [Instatiating the application]
+
+    //! [Initializing the application]
+    // The customization functor is called here
+    app.initialize( DemoWindowFactory( renderer ) );
+    //! [Initializing the application]
+
+    return app.exec();
+}
-- 
GitLab