RenderBufferBinding example

/**
* This example demonstrates how to change resolution of a render target/buffer using logic,
after the render buffer scene object was already created in a scene but was not created by the renderer yet.
* This can be useful if an asset is created and exported with a certain initial resolution but there is a need to adjust it
* in runtime upon loading to match platform display resolution or a certain level of detail.
*/

/// Helper method which creates a simple ramses scene with render target.
ramses::Scene* CreateSceneWithRenderTarget(ramses::RamsesClient& client);

int main()
{
    /// Use simple class to create ramses framework objects which are not essential for this example.
    SimpleRenderer renderer;

    /// Create a simple Ramses scene with a render target which gets a triangle rendered into and then its contents are displayed on a quad as texture.
    auto scene = CreateSceneWithRenderTarget(*renderer.getClient());

    ramses::LogicEngine& logicEngine{ *scene->createLogicEngine() };
    logicEngine.setStatisticsLoggingRate(0u);

    /// Create interface for logic which will control the resolution of the render target and viewport in scene created above
    ramses::LuaInterface* logicInterface = logicEngine.createLuaInterface(R"(
        function interface(IN)
            IN.resolution = Type:Int32()
        end
    )", "logicInterface");

    /**
    * Now we create CameraBinding and RenderBufferBinding which will be used to link the appropriate properties for the resolution change
    * to be correctly applied.
    * In order to change the resolution of our render target in our scene, we need to link the render buffer width and height and also
    * viewport witdth and height of the camera used for the render pass rendering into the render target.
    */
    ramses::CameraBinding* cameraBinding = logicEngine.createCameraBinding(*scene->findObject<ramses::Camera>("renderTargetCamera"), "cameraBinding");
    logicEngine.link(
        *logicInterface->getOutputs()->getChild("resolution"),
        *cameraBinding->getInputs()->getChild("viewport")->getChild("width"));
    logicEngine.link(
        *logicInterface->getOutputs()->getChild("resolution"),
        *cameraBinding->getInputs()->getChild("viewport")->getChild("height"));

    ramses::RenderBufferBinding* renderBufferBinding = logicEngine.createRenderBufferBinding(*scene->findObject<ramses::RenderBuffer>("renderBuffer"), "renderBufferBinding");
    logicEngine.link(
        *logicInterface->getOutputs()->getChild("resolution"),
        *renderBufferBinding->getInputs()->getChild("width"));
    logicEngine.link(
        *logicInterface->getOutputs()->getChild("resolution"),
        *renderBufferBinding->getInputs()->getChild("height"));
    /**
     * Note that we do not link all the RenderBufferBinding input properties ('sampleCount' is not used here),
     * meaning it will stay untouched and use the initial value given when RenderBuffer was created.
     */

    /**
     * Changing resolution of a render buffer via RenderBufferBinding has a very important limitation, it can only be done BEFORE the scene
     * is rendered (before it reaches RendererSceneState::Ready state to be precise), any attempt to change resolution later will have no effect
     * (only an error will be logged).
     */
    /// The actual change of resolution in our scene is then as simple as calling a setter on the logic interface we created
    logicInterface->getInputs()->getChild("resolution")->set(256);

    /// Show the scene on the renderer.
    renderer.showScene(scene->getSceneId());

    /// Simulate an application loop.
    while (!renderer.isWindowClosed())
    {
        /// Update the LogicEngine. This will apply changes to Ramses scene from any running script.
        logicEngine.update();

        /// In order to commit the changes to Ramses scene we need to "flush" them.
        scene->flush();

        /// Process window events, check if window was closed
        renderer.processEvents();

        /// Throttle the simulation loop by sleeping for a bit.
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }