Time for action — selecting a color channel

We are going to use the previous code, but we have to add and delete a lot:

  1. Start with the fragment program. Besides the normal parameter, add a float4 uniform parameter to store the color channel factors. Use these factors to multiply the color we retrieved from the original scene texture:
    void MyFragmentShader10(float2 uv : TEXCOORD0,
    out float4 color : COLOR,
    uniform sampler2D texture,
    uniform float4 factors
    )
    {
    color = tex2D(texture, uv);
    color *= factors;
    }
    
  2. Create a new material that uses the fragment shader and add the parameter with the default value of (1,1,1,0). This means that without changing the parameter, the scene will be rendered normally:
    fragment_program MyFragmentShader10 cg
    {
    source Ogre3DBeginnerGuideShaders.cg
    entry_point MyFragmentShader10
    profiles ps_1_1 arbfp1
    default_params
    {
    param_named factors float4 1 1 1 0
    }
    }
    material Ogre3DBeginnersGuide/Comp7
    {
    technique
    {
    pass
    {
    fragment_program_ref MyFragmentShader10
    {
    }
    texture_unit
    {
    }
    }
    }
    }
    
  3. Then add a compositor that uses this material:
    compositor Compositor9
    {
    technique
    {
    texture scene target_width target_height PF_R8G8B8
    target scene
    {
    input previous
    }
    target_output
    {
    input none
    pass render_quad
    {
    material Ogre3DBeginnersGuide/Comp7
    input 0 scene
    }
    }
    }
    }
    
  4. We have three color channels, so we will need three compositor listeners to change the parameters accordingly. First, add the one for the red color channel. Only set the color factors in the setup of the material and we don't need them to change during runtime:
    class CompositorListener2 : public Ogre::CompositorInstance::Listener
    {
    public:
    void notifyMaterialSetup (uint32 pass_id, MaterialPtr &mat)
    {
    mat->getBestTechnique()->getPass(pass_id)->getFragmentProgramParameters()->setNamedConstant("factors",Ogre::Vector3(1,0,0));
    }
    }
    
  5. Now, add the compositor for the green and blue color channels:
    class CompositorListener3 : public Ogre::CompositorInstance::Listener
    {
    public:
    void notifyMaterialSetup (uint32 pass_id, MaterialPtr &mat)
    {
    mat->getBestTechnique()->getPass(pass_id)->getFragmentProgramParameters()->setNamedConstant("factors",Ogre::Vector3(0,1,0));
    }
    };
    class CompositorListener4 : public Ogre::CompositorInstance::Listener
    {
    public:
    void notifyMaterialSetup (uint32 pass_id, MaterialPtr &mat)
    {
    mat->getBestTechnique()->getPass(pass_id)->getFragmentProgramParameters()->setNamedConstant("factors",Ogre::Vector3(0,0,1));
    }
    };
    
  6. Instead of the camera pointer, add four viewport pointers to the application:
    class Example83 : public ExampleApplication
    color channelcolor channelselecting{
    private:
    Ogre::Viewport* vp;
    Ogre::Viewport* vp2;
    Ogre::Viewport* vp3;
    Ogre::Viewport* vp4;
    
  7. Create the camera we are going to use and position it so that it looks at the front of Sinbad:
    void createCamera()
    {
    mCamera = mSceneMgr->createCamera("MyCamera1");
    mCamera->setPosition(0,10,20);
    mCamera->lookAt(0,0,0);
    mCamera->setNearClipDistance(5);
    }
    
  8. Adjust the createViewport() function to only use one camera and add the needed code for the two new viewports:
    void createViewports()
    {
    vp = mWindow->addViewport(mCamera,0,0.0,0.0,0.5,0.5);
    vp->setBackgroundColour(ColourValue(0.0f,0.0f,0.0f));
    vp2 = mWindow->addViewport(mCamera,1,0.5,0.0,0.5,0.5);
    vp2->setBackgroundColour(ColourValue(0.0f,0.0f,0.0f));
    vp3 = mWindow->addViewport(mCamera,2,0.0,0.5,0.5,0.5);
    vp3->setBackgroundColour(ColourValue(0.0f,0.0f,0.0f));
    vp4 = mWindow->addViewport(mCamera,3,0.5,0.5,0.5,0.5);
    vp4->setBackgroundColour(ColourValue(0.0f,0.0f,0.0f));
    mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
    }
    
  9. Add three pointers for storing the Compositor Listeners we have created above the application:
    CompositorListener2* compListener;
    CompositorListener3* compListener2;
    CompositorListener4* compListener3;
    
  10. Init each of them with NULL in the constructor:
    Example83()
    {
    compListener = NULL;
    compListener2 = NULL;
    compListener3 = NULL;
    }
    
  11. And, of course, delete them in the destructor:
    ~Example83()
    {
    if(compListener)
    {
    delete compListener;
    }
    if(compListener2)
    {
    delete compListener2;
    }
    if(compListener3)
    {
    delete compListener3;
    }
    }
    
  12. In the createScene() function, after the creation of the model instance and the scene node, add the code needed to add the compositor to our first viewport , enable it, and attach to it the compositor listener that only allows the red color channel to be rendered:
    Ogre::CompositorManager::getSingleton().addCompositor(vp, "Compositor9");
    Ogre::CompositorManager::getSingleton().setCompositorEnabled(vp, "Compositor9", true);
    Ogre::CompositorInstance* comp = Ogre::CompositorManager::getSingleton().getCompositorChain(vp)->getCompositor("Compositor9");
    compListener = new CompositorListener2();
    comp->addListener(compListener);
    
  13. Do the same for the second and third viewports using the green and blue only compositor listeners:
    Ogre::CompositorManager::getSingleton().addCompositor(vp2, "Compositor9");
    Ogre::CompositorManager::getSingleton().setCompositorEnabled(vp2, "Compositor9", true);
    Ogre::CompositorInstance* comp2 = Ogre::CompositorManager::getSingleton().getCompositorChain(vp2)->getCompositor("Compositor9");
    compListener2 = new CompositorListener3();
    comp2->addListener(compListener2);
    Ogre::CompositorManager::getSingleton().addCompositor(vp3, "Compositor9");
    Ogre::CompositorManager::getSingleton().setCompositorEnabled(vp3, "Compositor9", true);
    Ogre::CompositorInstance* comp3 = Ogre::CompositorManager::getSingleton().getCompositorChain(vp3)->getCompositor("Compositor9");
    compListener3 = new CompositorListener4();
    comp3->addListener(compListener3);
    
  14. Now run and compile the application. You should see the four identical images, only with different color channels rendered. At the top left, there is only the red color channel visible; on the top right, only the green; on the bottom left, the blue; and on the bottom right, the image with all the color channels:

What just happened?

We used the knowledge we gathered from the examples in this chapter to create an application that uses four viewports and one compositor in combination with three compositor listeners to see each color channel on its own and the combined result. Nothing really new has happened in this example; if needed, consult the other examples to understand this one.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.79.241