##########################################
Applying Tone Mapping on a Completed Image
##########################################


During pure software rendering, all the post processes (``RED::PostProcess``) are applied during the image calculation. Once the image is completed (i.e. ``RED::IWindow::FrameTracing`` if finished), the post processes are no longer applied. If you change the tone mapping values, you will notice that the completed image is not updated. This tutorial is here to show you how HOOPS Luminate can tackle this problem.

*********************
Visualizing the Issue
*********************

In the first step of the tutorial, we create a simple scene and configure it to do software rendering. Nothing really difficult here.

The RFK framework provides a useful built-in tool to change the post processes options dynamically in any application: the tone mapping inspector (``RFK::IPR_TONEMAPPING``). We add a button in the application tool bar to display it.

.. code:: cpp
        
    RC_TEST( RFK::TutorialApplication::CreateCommand( g_cmd_tonemapping, "Tone mapping", "../Resources/camera_edit.png", "", OnToneMapping, NULL, CMD_FLAG_CHECKABLE ) );
    RC_TEST( RFK::TutorialApplication::AddCommand( tb, g_cmd_tonemapping ) );


Then a callback function is created to open and close the post process panel:

.. code:: cpp
        
    RED_RC OnToneMapping( int iCommand )
    {
        int state = RFK::TutorialApplication::GetCommandState( iCommand );

        if( state & CMD_FLAG_CHECKED )
        {
            RC_TEST( RFK::TutorialApplication::ShowInspector( RFK::IPR_TONEMAPPING, RFK::TutorialApplication::GetViewpoint() ) );
        }
        else
        {
            RFK::TutorialApplication::HideInspector( RFK::IPR_TONEMAPPING );
        }

        return RED_OK;
    }


.. figure:: wf_ApplyingToneMappingOnACompletedImage01.jpg
    :align: center
    
    **The tone mapping inspector on the right**

In fact, the tutorial framework always uses HOOPS Luminate in hybrid mode (see :doc:`/tasks/ta_ca/ta_ca_application/tk_hardware_or_software_startup`). Thus you will not be able to see the issue here.

.. note:: 
    
    In hybrid mode, the issue does not happens because the tone mapping is done on GPU and is updated even after the image is calculated, which is not the case in pure software mode.

We will do as if we were in full CPU mode and continue as if we have to tackle the problem. If we were in pure software mode, the changes in tone mapping and post processes would be visible during the image calculation but not anymore once finished.

*************************************************
Applying Post Process after the Image Calculation
*************************************************

In order to change tone mapping options after the completion of an image, we will use the ``RED::IWindow::FrameTracingImages`` function instead of the ``RED::IWindow::FrameTracing`` one to calculate the image. This function performs the same operation but returns the color and depth rendered images. The tutorial framework allows to switch from ``RED::IWindow::FrameTracing`` to ``RED::IWindow::FrameTracingImages`` by calling the RFK::TutorialApplication::AddFrameTracingImages function.

.. code:: cpp

    // Create render images:
    RC_TEST( iresmgr->CreateImage2D( g_vrl_color_image, iresmgr->GetState() ) );
    RC_TEST( iresmgr->CreateImage2D( g_vrl_depth_image, iresmgr->GetState() ) );

    // Tells the tutorial to use these render images with a RED::IWindow::FrameTracingImages.
    RC_TEST( RFK::TutorialApplication::AddFrameTracingImages( g_vrl_color_image, g_vrl_depth_image, RFK::TutorialApplication::GetViewpoint() ) );


Then, once the image is calculated, we will stop calling ``RED::IWindow::FrameTracingImages`` and call ``RED::IWindow::FrameDrawing`` instead. We switch from software to hardware rendering after re-injecting the completed software image (retrieved using ``RED::IWindow::FrameTracingImages``) in the ``RED::IViewpointRenderList``. The next code sample is written in the ``RFK::EVT_RENDER_COMPLETE`` event callback:

.. code:: cpp

    // Set viewpoint soft images before switching from software to active mode:
    // This will allow to do post processing after the software image is calculated.
    RC_TEST( ivrl->SetViewpointSoftImages( g_vrl_color_image, g_vrl_depth_image,
                                        RFK::TutorialApplication::GetViewpoint(),
                                        iresmgr->GetState() ) );

    // Set active hardware rendering mode after the frame tracing is done:
    // This will call RED::IWindow::FrameDrawing instead of RED::IWindow::FrameTracingImages.
    RC_TEST( RFK::TutorialApplication::SetLoopMode( RFK::LM_ACTIVE ) );

Of course, when the rendering needs to be restarted, for instance when the user changes the camera with the mouse, you have to switch back to software loop mode:

.. code:: cpp

    RC_TEST( RFK::TutorialApplication::SetLoopMode( RFK::LM_SOFTWARE_BY_BLOCKS ) );


.. figure:: wf_ApplyingToneMappingOnACompletedImage02.png
    :align: center
    
    **The complete process**

This time, after launching the tutorial application, you can see that you can change the post process parameters even after the image is fully calculated.
