Hi all

May some one can suppport me in working out the artefacts in this
implementation (GLSL)

/regards
adrian

-- 
********************************************
Adrian Egli
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
*
* This application is open source and may be redistributed and/or modified   
* freely and without restriction, both in commericial and non commericial 
applications,
* as long as this copyright notice is maintained.
* 
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/

#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osg/CoordinateSystemNode>

#include <osg/Switch>
#include <osg/Uniform>

#include <osgText/Text>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osg/BlendFunc>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>

#include <iostream>

#include <osgFX/Effect>
#include <osgFX/Technique>
#include <osgFX/Registry>

#include <osg/TexGen>
#include <osg/Texture2D>

#include <osg/PolygonOffset>
#include <osgDB/WriteFile>



bool global_debug_on = false;

struct WriteCameraPostDrawCallback : public osg::Camera::DrawCallback
{
        WriteCameraPostDrawCallback(osg::Image* image,std::string filename, 
bool write):
_image(image),
_filename(filename) 
{
        char* write_file = getenv("DEBUG");
        global_debug_on = (write_file!=NULL) || write;
}

virtual void operator () (const osg::Camera& /*camera*/) const
{

        _image->dirty();

        if ( global_debug_on ) {
                std::cout << "write " << _filename << std::endl;
                osgDB::writeImageFile(*(_image.get()),_filename);
        }

}

osg::ref_ptr<osg::Image> _image;
std::string _filename;
};


namespace osgFX {
        class SSAO : public Effect {
        public:
                SSAO() {};
                SSAO(osg::Group*);
                SSAO(const SSAO& copy, const osg::CopyOp& copyop = 
osg::CopyOp::SHALLOW_COPY);

                META_Effect(osgFX, SSAO, 

                        "Screen Space Ambient Occlusion", 

                        "SSAO : test implementation", 

                        "Adrian Egli");
        protected:
                virtual ~SSAO() {}
                SSAO& operator=(const SSAO&) { return *this; }

                bool define_techniques();

                osg::ref_ptr<osg::Group> _root;
        };

}



using namespace osgFX;


namespace
{


        osg::Node* createBase(osg::Texture2D* texture ,osg::Texture2D* 
texture2=NULL )
        {

                osg::ref_ptr<osg::Geode> geode = new osg::Geode;

                // set up the texture of the base.
                osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
                
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
                if 
(texture2)stateset->setTextureAttributeAndModes(1,texture2,osg::StateAttribute::ON);
                geode->setStateSet( stateset.get() );


                osg::ref_ptr<osg::HeightField> grid = new osg::HeightField;
                grid->allocate(2,2);
                grid->setOrigin(osg::Vec3(0.0,0.0,0.0));
                grid->setXInterval(1.0);
                grid->setYInterval(1.0);

                grid->setHeight(0,0,-1.0);
                grid->setHeight(0,1,-1.0);
                grid->setHeight(1,1,-1.0);
                grid->setHeight(1,0,-1.0);

                geode->addDrawable(new osg::ShapeDrawable(grid.get()));

                osg::Group* group = new osg::Group;
                group->addChild(geode.get());

                return group;

        }

        Registry::Proxy proxy(new SSAO);

        class DefaultTechnique: public Technique {
        public:

                DefaultTechnique(osg::Group* scene,osg::Group* ssaoFX) :    
                  Technique(),
                          _scene(scene)
                  {

                          
////////////////////////////////////////////////////////////////////////// depth
                          // texture resolution 
                          _RTTInfoTangentDepth._resolution_x = 512;
                          _RTTInfoTangentDepth._resolution_y = 512;


                          // texture
                          _RTTInfoTangentDepth._texture = new osg::Texture2D;
                          
_RTTInfoTangentDepth._texture->setTextureSize(_RTTInfoTangentDepth._resolution_x,
 _RTTInfoTangentDepth._resolution_y);
                          
_RTTInfoTangentDepth._texture->setInternalFormat(GL_RGBA);
                          
_RTTInfoTangentDepth._texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
                          
_RTTInfoTangentDepth._texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);

                          // camera 
                          _RTTInfoTangentDepth._camera = new osg::Camera;
                          
_RTTInfoTangentDepth._camera->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
                          
_RTTInfoTangentDepth._camera->setClearMask(GL_COLOR_BUFFER_BIT | 
GL_DEPTH_BUFFER_BIT);
                          
_RTTInfoTangentDepth._camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
                          // set viewport
                          
_RTTInfoTangentDepth._camera->setViewport(0,0,_RTTInfoTangentDepth._resolution_x,_RTTInfoTangentDepth._resolution_y);
                          // set the camera to render before the main camera.
                          
_RTTInfoTangentDepth._camera->setRenderOrder(osg::Camera::PRE_RENDER);
                          // tell the camera to use OpenGL frame buffer object 
where supported.
                          
_RTTInfoTangentDepth._camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
                          // image (SSAO filter)
                          _RTTInfoTangentDepth._image=new osg::Image;
                          
_RTTInfoTangentDepth._image->allocateImage(_RTTInfoTangentDepth._resolution_x, 
_RTTInfoTangentDepth._resolution_y,  1, GL_RGBA, GL_UNSIGNED_BYTE);
                          
_RTTInfoTangentDepth._camera->attach(osg::Camera::COLOR_BUFFER, 
_RTTInfoTangentDepth._image.get(),0,0);
                          _RTTInfoTangentDepth._camera->setPostDrawCallback(new 
WriteCameraPostDrawCallback(_RTTInfoTangentDepth._image.get(),"RTTInfoDepth.png",false));
                          
_RTTInfoTangentDepth._texture->setImage(0,_RTTInfoTangentDepth._image.get());
                          // add subgraph to render
                          _RTTInfoTangentDepth._camera->addChild(_scene.get());


 
                          


                          
////////////////////////////////////////////////////////////////////////// SSAO 
difference
                          // texture resolution 
                          _RTTInfoSSAO._resolution_x = 512;
                          _RTTInfoSSAO._resolution_y = 512;

                          // texture
                          _RTTInfoSSAO._texture = new osg::Texture2D;
                          
_RTTInfoSSAO._texture->setTextureSize(_RTTInfoSSAO._resolution_x, 
_RTTInfoSSAO._resolution_y);
                          _RTTInfoSSAO._texture->setInternalFormat(GL_RGB);
                          
_RTTInfoSSAO._texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
                          
_RTTInfoSSAO._texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);

                          // camera 
                          _RTTInfoSSAO._camera = new osg::Camera;
                          
_RTTInfoSSAO._camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
                          
_RTTInfoSSAO._camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                          
_RTTInfoSSAO._camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
                          // set viewport
                          
_RTTInfoSSAO._camera->setViewport(0,0,_RTTInfoSSAO._resolution_x,_RTTInfoSSAO._resolution_y);
                          
_RTTInfoSSAO._camera->setViewMatrixAsLookAt(osg::Vec3(0.5,0.5,1),osg::Vec3(0.5,0.5,0),osg::Vec3(0,1,0));
                          
_RTTInfoSSAO._camera->setProjectionMatrixAsOrtho2D(-0.5,0.5,-0.5,0.5);

                          // set the camera to render before the main camera.
                          
_RTTInfoSSAO._camera->setRenderOrder(osg::Camera::PRE_RENDER);
                          // tell the camera to use OpenGL frame buffer object 
where supported.
                          
_RTTInfoSSAO._camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
                          // image (SSAO filter)
                          _RTTInfoSSAO._image=new osg::Image;
                          
_RTTInfoSSAO._image->allocateImage(_RTTInfoSSAO._resolution_x, 
_RTTInfoSSAO._resolution_y,  1, GL_RGB, GL_UNSIGNED_BYTE);
                          
_RTTInfoSSAO._camera->attach(osg::Camera::COLOR_BUFFER, 
_RTTInfoSSAO._image.get(),0,0);
                          _RTTInfoSSAO._camera->setPostDrawCallback(new 
WriteCameraPostDrawCallback(_RTTInfoSSAO._image.get(),"RTTInfoSSAO.png",false));
                          
_RTTInfoSSAO._texture->setImage(0,_RTTInfoSSAO._image.get());
                          // add subgraph to render
                          
_RTTInfoSSAO._camera->addChild(createBase(_RTTInfoTangentDepth._texture.get()));



                          
////////////////////////////////////////////////////////////////////////// 
Gaussian Vertical
                          // texture resolution 
                          _RTTInfoGaussianV._resolution_x = 512;
                          _RTTInfoGaussianV._resolution_y = 512;


                          // texture
                          _RTTInfoGaussianV._texture = new osg::Texture2D;
                          
_RTTInfoGaussianV._texture->setTextureSize(_RTTInfoGaussianV._resolution_x, 
_RTTInfoGaussianV._resolution_y);
                          _RTTInfoGaussianV._texture->setInternalFormat(GL_RGB);
                          
_RTTInfoGaussianV._texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
                          
_RTTInfoGaussianV._texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);

                          // camera 
                          _RTTInfoGaussianV._camera = new osg::Camera;
                          
_RTTInfoGaussianV._camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
                          
_RTTInfoGaussianV._camera->setClearMask(GL_COLOR_BUFFER_BIT | 
GL_DEPTH_BUFFER_BIT);
                          
_RTTInfoGaussianV._camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
                          // set viewport
                          
_RTTInfoGaussianV._camera->setViewport(0,0,_RTTInfoGaussianV._resolution_x,_RTTInfoGaussianV._resolution_y);
                          
_RTTInfoGaussianV._camera->setViewMatrixAsLookAt(osg::Vec3(0.5,0.5,1.0),osg::Vec3(0.5,0.5,0.0),osg::Vec3(0,1,0));
                          
_RTTInfoGaussianV._camera->setProjectionMatrixAsOrtho2D(-0.5,0.5,-0.5,0.5);
                          // set the camera to render before the main camera.
                          
_RTTInfoGaussianV._camera->setRenderOrder(osg::Camera::PRE_RENDER);
                          // tell the camera to use OpenGL frame buffer object 
where supported.
                          
_RTTInfoGaussianV._camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
                          // image (SSAO filter)
                          _RTTInfoGaussianV._image=new osg::Image;
                          
_RTTInfoGaussianV._image->allocateImage(_RTTInfoGaussianV._resolution_x, 
_RTTInfoGaussianV._resolution_y,  1, GL_RGB, GL_UNSIGNED_BYTE);
                          
_RTTInfoGaussianV._camera->attach(osg::Camera::COLOR_BUFFER, 
_RTTInfoGaussianV._image.get(),0,0);
                          _RTTInfoGaussianV._camera->setPostDrawCallback(new 
WriteCameraPostDrawCallback(_RTTInfoGaussianV._image.get(),"RTTInfoGaussianV.png",false));
                          
_RTTInfoGaussianV._texture->setImage(0,_RTTInfoGaussianV._image.get());
                          // add subgraph to render
                          
_RTTInfoGaussianV._camera->addChild(createBase(_RTTInfoSSAO._texture.get()));

                          
////////////////////////////////////////////////////////////////////////// 
Gaussian Horizontal
                          // texture resolution 
                          _RTTInfoGaussianH._resolution_x = 512;
                          _RTTInfoGaussianH._resolution_y = 512;


                          // texture
                          _RTTInfoGaussianH._texture = new osg::Texture2D;
                          
_RTTInfoGaussianH._texture->setTextureSize(_RTTInfoGaussianH._resolution_x, 
_RTTInfoGaussianH._resolution_y);
                          _RTTInfoGaussianH._texture->setInternalFormat(GL_RGB);
                          
_RTTInfoGaussianH._texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
                          
_RTTInfoGaussianH._texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);

                          // camera 
                          _RTTInfoGaussianH._camera = new osg::Camera;
                          
_RTTInfoGaussianH._camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
                          
_RTTInfoGaussianH._camera->setClearMask(GL_COLOR_BUFFER_BIT | 
GL_DEPTH_BUFFER_BIT);
                          
_RTTInfoGaussianH._camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
                          // set viewport
                          
_RTTInfoGaussianH._camera->setViewport(0,0,_RTTInfoGaussianH._resolution_x,_RTTInfoGaussianH._resolution_y);
                          
_RTTInfoGaussianH._camera->setViewMatrixAsLookAt(osg::Vec3(0.5,0.5,1),osg::Vec3(0.5,0.5,0),osg::Vec3(0,1,0));
                          
_RTTInfoGaussianH._camera->setProjectionMatrixAsOrtho2D(-0.5,0.5,-0.5,0.5);

                          // set the camera to render before the main camera.
                          
_RTTInfoGaussianH._camera->setRenderOrder(osg::Camera::PRE_RENDER);
                          // tell the camera to use OpenGL frame buffer object 
where supported.
                          
_RTTInfoGaussianH._camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
                          // image (SSAO filter)
                          _RTTInfoGaussianH._image=new osg::Image;
                          
_RTTInfoGaussianH._image->allocateImage(_RTTInfoGaussianH._resolution_x, 
_RTTInfoGaussianH._resolution_y,  1, GL_RGB, GL_UNSIGNED_BYTE);
                          
_RTTInfoGaussianH._camera->attach(osg::Camera::COLOR_BUFFER, 
_RTTInfoGaussianH._image.get(),0,0);
                          _RTTInfoGaussianH._camera->setPostDrawCallback(new 
WriteCameraPostDrawCallback(_RTTInfoGaussianH._image.get(),"RTTInfoGaussianH.png",false));
                          
_RTTInfoGaussianH._texture->setImage(0,_RTTInfoGaussianH._image.get());
                          // add subgraph to render
                          
_RTTInfoGaussianH._camera->addChild(createBase(_RTTInfoGaussianV._texture.get()));



                          
////////////////////////////////////////////////////////////////////////// SSAO 
final pass

                          osg::ref_ptr<osg::StateSet> ss = 
ssaoFX->getOrCreateStateSet();
                          {
                                  unsigned int textLoop(0); 
                                  // fake texture for baseTexture, add a fake 
texture
                                  // we support by default at least one texture 
layer
                                  // without this fake texture we can not 
support
                                  // textured and not textured scene

                                  // TODO: at the moment the PSSM supports just 
one texture layer in the GLSL shader, multitexture are
                                  //       not yet supported !

                                  osg::ref_ptr<osg::Image> image = new 
osg::Image;
                                  // allocate the image data, noPixels x 1 x 1 
with 4 rgba floats - equivalent to a Vec4!
                                  int noPixels = 1;
                                  
image->allocateImage(noPixels,1,1,GL_RGBA,GL_FLOAT);
                                  image->setInternalTextureFormat(GL_RGBA);
                                  // fill in the image data.
                                  osg::Vec4* dataPtr = 
(osg::Vec4*)image->data();
                                  osg::Vec4f color(1.0f,1.0f,1.0f,0.0f);
                                  *dataPtr = color;
                                  // make fake texture
                                  osg::ref_ptr<osg::Texture2D> texture = new 
osg::Texture2D;
                                  
texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
                                  
texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
                                  
texture->setBorderColor(osg::Vec4(1.0,1.0,1.0,1.0));
                                  
texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
                                  
texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
                                  texture->setImage(image.get());
                                  // add fake texture
                                  
ss->setTextureAttribute(textLoop,texture.get(),osg::StateAttribute::ON);
                                  
ss->setTextureMode(textLoop,GL_TEXTURE_1D,osg::StateAttribute::OFF);
                                  
ss->setTextureMode(textLoop,GL_TEXTURE_2D,osg::StateAttribute::ON);
                                  
ss->setTextureMode(textLoop,GL_TEXTURE_3D,osg::StateAttribute::OFF);
                          }


                          
ss->setTextureAttributeAndModes(1,_RTTInfoGaussianV._texture.get(),osg::StateAttribute::ON);

                          osg::ref_ptr<osg::Program> program = new osg::Program;
                          ss->setAttribute(program.get());

                          osg::ref_ptr<osg::Uniform> samplerText = new 
osg::Uniform("samplerText",0);
                          ss->addUniform(samplerText.get());

                          osg::ref_ptr<osg::Uniform> samplerRTScene = new 
osg::Uniform("samplerRTScene",1);
                          ss->addUniform(samplerRTScene.get());


                          osg::ref_ptr<osg::Shader> fragment_shader = new 
osg::Shader(osg::Shader::FRAGMENT,
                                  "uniform sampler2D samplerRTScene;"\
                                  "uniform sampler2D samplerText;"\
                                  "void main(void)"\
                                  "{"\
                                  " vec4 text = 
texture2D(samplerText,gl_TexCoord[0].st);"\
                                  "     vec4 ssao = texture2D(samplerRTScene, 
vec2(1.0/512.0*gl_FragCoord.x, 1.0/512.0*gl_FragCoord.y));"\
                                  "     gl_FragColor = 
(gl_Color*1.0+0.0*text*gl_Color) - ssao;"\
                                  "}"   
                                  );
                          program->addShader(fragment_shader.get());
                  }

                  virtual void getRequiredExtensions(std::vector<std::string>& 
extensions)
                  {
                  }

                  bool validate(osg::State& state) const
                  {
                          if (!Technique::validate(state)) return false;

                          //osg::TextureCubeMap::Extensions *ext = 
osg::TextureCubeMap::getExtensions(state.getContextID(), true);
                          //if (ext) {
                          //    return ext->isCubeMapSupported();
                          //}
                          return true;
                  }


                  /** optional: return a node that overrides the child node on 
a specified pass */
                  inline virtual osg::Node* getOverrideChild(int passNum)  { 
                          if ( passNum == 0 ) { //Depth
                                  return _RTTInfoTangentDepth._camera.get();
                          }
                          if ( passNum == 1 ) { // SSAO
                                  return _RTTInfoSSAO._camera.get();
                          }                      
                          if ( passNum == 2 ) { // Gaussian V
                                  return _RTTInfoGaussianV._camera.get();
                          }
                          if ( passNum == 3) { // Gaussian H
                                  return _RTTInfoGaussianH._camera.get();
                          }

                          return 0; 

                  }

                  inline virtual void traverse(osg::NodeVisitor& nv, Effect* 
fx) {

                          // special actions must be taken if the node visitor 
is actually a CullVisitor
                          osgUtil::CullVisitor *cv = 
dynamic_cast<osgUtil::CullVisitor *>(&nv);
                          if ( cv ) {   
                                  osgUtil::RenderStage* orig_rs = 
cv->getRenderStage();
                                  
_RTTInfoTangentDepth._camera->setViewMatrix(cv->getRenderInfo().getView()->getCamera()->getViewMatrix());
                                  
_RTTInfoTangentDepth._camera->setProjectionMatrix(cv->getRenderInfo().getView()->getCamera()->getProjectionMatrix());
                                  osg::ref_ptr<osg::Viewport> vp = 
cv->getRenderInfo().getView()->getCamera()->getViewport();
                                  osg::ref_ptr<osg::Viewport> vpCam = 
_RTTInfoTangentDepth._camera->getViewport();
                                  if ( vpCam->width()!=vp->width() || 
vpCam->height()!=vp->height()  ) {
                                          
_RTTInfoTangentDepth._camera->getViewport()->setViewport(
                                                  0,
                                                  0,
                                                  std::min((unsigned 
int)vp->width(),_RTTInfoTangentDepth._resolution_x),
                                                  std::min((unsigned 
int)vp->height(),_RTTInfoTangentDepth._resolution_y)
                                                  );            
                                  }

                                  double f,a,zn,zf;
                                  
cv->getRenderInfo().getView()->getCamera()->getProjectionMatrix().getPerspective(f,a,zn,zf);
                                  osg::Vec3 eye,center,up;
                                  
cv->getRenderInfo().getView()->getCamera()->getViewMatrixAsLookAt(eye,center,up);
                                  if ( _cameraPos.valid() ) 
_cameraPos->set(eye);
                                  if ( _nearUniform.valid() ) {
                                          _nearUniform->set((float)zn);
                                          std::cout << "_nearUniform" << zn << 
std::endl;
                                  }
                                  if ( _farUniform.valid() )  {
                                          _farUniform->set((float)zf); 
                                          std::cout << "_farUniform" << zf << 
std::endl;
                                  }
                                  if ( _inverseMVPWUniform.valid() ) {
                                          osg::Matrix matrix( 
cv->getRenderInfo().getView()->getCamera()->getViewMatrix() * 
cv->getRenderInfo().getView()->getCamera()->getProjectionMatrix());
                                          
matrix.postMult(cv->getRenderInfo().getView()->getCamera()->getViewport()->computeWindowMatrix());
                                          osg::Matrix inverseMVPW;
                                          inverseMVPW.invert(matrix);
                                          _inverseMVPWUniform->set(inverseMVPW);

                                          osg::Vec3f nearA = 
osg::Vec3(-1.0f,-1.0f, 0.0f) * inverseMVPW;
                                          osg::Vec3f nearB = osg::Vec3( 
1.0f,-1.0f, 0.0f) * inverseMVPW;
                                          osg::Vec3f nearC = osg::Vec3(-1.0f, 
1.0f, 0.0f) * inverseMVPW;
                                          osg::Vec3f farA  = 
osg::Vec3(-1.0f,-1.0f, 1.0f) * inverseMVPW;
                                          osg::Vec3f farB  = osg::Vec3( 
1.0f,-1.0f, 1.0f) * inverseMVPW;
                                          osg::Vec3f farC  = osg::Vec3(-1.0f, 
1.0f, 1.0f) * inverseMVPW;

                                          #if ( 0 )
                                                  osg::Vec3 vdir = center - 
eye;vdir.normalize();
                                                  std::cout << 
"*****************************************************************" << 
std::endl;
                                                  std::cout << "view  " << 
eye.x() << " , " << eye.y() << " , " << eye.z() << std::endl;
                                                  std::cout << "vdir  " << 
vdir.x() << " , " << vdir.y() << " , " << vdir.z() << std::endl;
                                                  std::cout << "up    " << 
up.x() << " , " << up.y() << " , " << up.z() << std::endl;
                                                  std::cout << "nearA  " << 
nearA.x() << " , " << nearA.y() << " , " << nearA.z() << std::endl;
                                                  std::cout << "nearB  " << 
nearB.x() << " , " << nearB.y() << " , " << nearB.z() << std::endl;
                                                  std::cout << "nearC  " << 
nearC.x() << " , " << nearC.y() << " , " << nearC.z() << std::endl;
                                                  std::cout << "farA   " << 
farA.x() << " , " << farA.y() << " , " << farA.z() << std::endl;
                                                  std::cout << "farB   " << 
farB.x() << " , " << farB.y() << " , " << farB.z() << std::endl;
                                                  std::cout << "farC   " << 
farC.x() << " , " << farC.y() << " , " << farC.z() << std::endl;
                      #endif

                                          if ( _nearA.valid() ) 
_nearA->set(nearA);
                                          if ( _nearB.valid() ) 
_nearB->set(nearB);
                                          if ( _nearC.valid() ) 
_nearC->set(nearC);
                                          if ( _farA.valid()  ) 
_farA->set(farA);
                                          if ( _farB.valid()  ) 
_farB->set(farB);
                                          if ( _farC.valid()  ) 
_farC->set(farC);


                                  }
                          }


                          traverse_implementation(nv, fx);

                  }


        protected:

                void define_passes()
                {
                        _cameraPos = new 
osg::Uniform("cameraPos",osg::Vec3f(0.0f,0.0f,0.0f));

                        _nearA = new 
osg::Uniform("nearA_Uniform",osg::Vec3f(0.0f,0.0f,0.0f));
                        _nearB = new 
osg::Uniform("nearB_Uniform",osg::Vec3f(0.0f,0.0f,0.0f));
                        _nearC = new 
osg::Uniform("nearC_Uniform",osg::Vec3f(0.0f,0.0f,0.0f));
                        _farA  = new 
osg::Uniform("farA_Uniform",osg::Vec3f(0.0f,0.0f,0.0f));
                        _farB  = new 
osg::Uniform("farB_Uniform",osg::Vec3f(0.0f,0.0f,0.0f));
                        _farC  = new 
osg::Uniform("farC_Uniform",osg::Vec3f(0.0f,0.0f,0.0f));

                        _nearUniform = new osg::Uniform("nearUniform",FLT_MIN);
                        _farUniform  = new osg::Uniform("farUniform",FLT_MAX);
                        osg::Matrixf mat;mat.identity();
                        _inverseMVPWUniform = new 
osg::Uniform("inverseMVPWUniform",mat);

                        {   //  Tangent Depth Pass 1
                                osg::ref_ptr<osg::StateSet> ss = new 
osg::StateSet;


                                osg::ref_ptr<osg::Program> program = new 
osg::Program;
                                ss->setAttribute(program.get());

                                ss->addUniform(_nearUniform.get());
                                ss->addUniform(_farUniform.get());
                                ss->addUniform(_cameraPos.get());


                                osg::ref_ptr<osg::Shader> vertex_shader = new 
osg::Shader(osg::Shader::VERTEX,
                                        "varying vec3 vTangent;"\
                                        "varying vec3 vVertex;"\
                                        "uniform vec3 cameraPos;"\
                                        "void main(void)"\
                                        "{"\
                                        "   vec3 n   = 
normalize(gl_NormalMatrix * gl_Normal);"\
                                        "   vec3 b   = 
normalize(gl_NormalMatrix * vec3(1.0,1.0,0.0));"\
                                        "   vec3 c   = normalize(cross(b,n));"\
                                        "   vTangent = normalize(cross(c,n));"\
                                        "   vVertex  = cameraPos - 
vec3(gl_ModelViewMatrix * gl_Vertex);"\
                                        "       gl_Position = ftransform();"\
                                        "}"
                                        );
                                program->addShader(vertex_shader.get());

                                osg::ref_ptr<osg::Shader> fragment_shader = new 
osg::Shader(osg::Shader::FRAGMENT,
                                        "uniform float nearUniform;"\
                                        "uniform float farUniform;"\
                                        "varying vec3 vVertex;"\
                                        "varying vec3 vTangent;"\
                                        " "\
                                        "void main() {"\
                                        "   float z = 
(gl_FragCoord.z/gl_FragCoord.w+1.0)/(farUniform);"\
                                        "       gl_FragColor = 
vec4(z*vec3(1.0,1.0,1.0)*1.0+0.0*normalize(vTangent),step(0.9,gl_FrontMaterial.diffuse.a));"\
                                        "} "
                                        );
                                program->addShader(fragment_shader.get());


                                addPass(ss.get());
                        }
                        
                        {   // SSAO 2
                                osg::ref_ptr<osg::StateSet> ss = new 
osg::StateSet;


                                osg::ref_ptr<osg::Program> program = new 
osg::Program;
                                ss->setAttribute(program.get());

                                osg::ref_ptr<osg::Uniform> samplerTangentDepth 
= new osg::Uniform("samplerTangentDepth",0);
                                ss->addUniform(samplerTangentDepth.get());
 

                                ss->addUniform(_nearUniform.get());
                                ss->addUniform(_farUniform.get());
                                
                                ss->addUniform(_nearA.get());
                                ss->addUniform(_nearB.get());
                                ss->addUniform(_nearC.get());
                                ss->addUniform(_farA.get());
                                ss->addUniform(_farB.get());
                                ss->addUniform(_farC.get());

                                ss->addUniform(_inverseMVPWUniform.get());

 

                                osg::ref_ptr<osg::Shader> vertex_shader = new 
osg::Shader(osg::Shader::VERTEX,
                                        "varying vec2 vTexCoord;"\
                                        "uniform float farUniform;"\
                                        "uniform float nearUniform;"\
                                        "void main(void)"\
                                        "{"\
                                        "       gl_Position = ftransform();"\
                                        "       vec2 Pos = gl_Vertex.xy;"\
                                        "       vTexCoord = Pos;"\
                                        "}"
                                        );
                                program->addShader(vertex_shader.get());


         
                                osg::ref_ptr<osg::Shader> fragment_shader = new 
osg::Shader(osg::Shader::FRAGMENT,
                                        "uniform sampler2D 
samplerTangentDepth;"\
                                        "uniform mat4 inverseMVPWUniform;"\
                                        "uniform float farUniform;"\
                                        "uniform float nearUniform;"\
                                        "uniform vec3 nearA_Uniform;"\
                                        "uniform vec3 nearB_Uniform;"\
                                        "uniform vec3 nearC_Uniform;"\
                                        "uniform vec3 farA_Uniform;"\
                                        "uniform vec3 farB_Uniform;"\
                                        "uniform vec3 farC_Uniform;"\
                                        "varying vec2 vTexCoord;"\
                                        "  "\
                                        "float readDepth( in vec2 coord ) {"\
                                        "       vec4 depth = 
texture2D(samplerTangentDepth,coord);"\
                                        "       return length(depth.rgb);"      
                                        "}"\
                                        "  "\
                                        "vec3 unProject( in vec2 coord, in 
float depth) {"\
                                        "       vec3 diffNx = (nearB_Uniform -  
nearA_Uniform);"\
                                        "       vec3 diffNy = (nearC_Uniform -  
nearA_Uniform);"\
                                        "       vec3 diffFx = (farB_Uniform  -  
 farA_Uniform);"\
                                        "       vec3 diffFy = (farC_Uniform  -  
 farA_Uniform);"\
                                        "       vec3 n = nearA_Uniform + 
diffNx*coord.x + diffNy*coord.y;"\
                                        "       vec3 f =  farA_Uniform + 
diffFx*coord.x + diffFy*coord.y;"\
                                        "       vec3 diffNF = (f-n);"\
                                        "   return (n + diffNF*depth);"\
                                        "}"\
                                        "  "\
                                        "vec3 readTanget( in vec2 coord ) {"\
                                        "       float tangentDepth1 = 
readDepth(coord+vec2(-1,-1)/512.0);"\
                                        "       float tangentDepth2 = 
readDepth(coord+vec2(-1, 1)/512.0);"\
                                        "       float tangentDepth3 = 
readDepth(coord+vec2( 1, 1)/512.0);"\
                                        "       float tangentDepth4 = 
readDepth(coord+vec2( 1,-1)/512.0);"\
                                        "   vec3 a = 
unProject(coord+vec2(-1,-1)/512.0,tangentDepth1);"\
                                        "   vec3 b = unProject(coord+vec2(-1, 
1)/512.0,tangentDepth2);"\
                                        "   vec3 c = unProject(coord+vec2( 1, 
1)/512.0,tangentDepth3);"\
                                        "   vec3 d = unProject(coord+vec2( 
1,-1)/512.0,tangentDepth4);"\
                                        "   vec3 e = abs(a-0.5*c);"\
                                        "   vec3 f = abs(b-0.5*d);"\
                                        "       return 0.5*(e+f);"\
                                        "}"\
                                        "  "\
                                        "void main(void)"\
                                        "{"\
                                        "       float depth0 = 
readDepth(vTexCoord.xy);"\
                                        "       vec3 tangent0 = 
readTanget(vTexCoord.xy);"\
                                        "       vec3 objectCoord0 = 
unProject(vTexCoord.xy,depth0);"\
                                        "       float runRmin = 2.0;"\
                                        "       float runRmax = 8.0;"\
                                        "       float runRfactor = 1.5;"\
                                        "       float runPhiStep = 30.0;"\
                                        "       float sampleCount = 0.0;"\
                                        "       float aoH = 0.0;"\
                                        "   for (float fPhi=0; fPhi < 
360.0+runPhiStep; fPhi+=runPhiStep)"\
                                        "   {"\
                                        "         float sampleCountR = 0.0;"\
                                        "     float maxAOH=0.0;"\
                                        "     for (float fRadius=runRmin; 
fRadius < runRmax; fRadius*=runRfactor)"\
                                        "     {"\
                                        "       sampleCountR = sampleCountR + 
1.0;"\
                                        "       float iX = fRadius * sin ( 
0.0175 * fPhi)/512.0;"\
                                        "       float iY = fRadius * cos ( 
0.0175 * fPhi)/512.0;"\
                                        "       vec2 offsetXY = vec2(iX,iY);"\
                                        "               float depth = 
readDepth(offsetXY+vTexCoord.xy);"\
                                        "           vec3 tangent = 
readTanget(offsetXY+vTexCoord.xy);"\
                                        "               vec3 objectCoord = 
unProject(offsetXY+vTexCoord.xy,depth);"\
                                        "               vec3 objectCoordDiff = 
normalize(objectCoord-objectCoord0);"\
                                        "       float angleDiff = 
(objectCoordDiff.z)/(length(objectCoordDiff.xy)+1/1024.0);"\
                                        "               float aoHDiff = 
angleDiff * step(abs(depth0-depth),0.05) * step(0.2693,angleDiff);"\
                                        "               float updateMaxAOH = 
step(maxAOH,aoHDiff);"\
                                        "               maxAOH = maxAOH + 
updateMaxAOH * aoHDiff + (1.0-updateMaxAOH)*(maxAOH*(1.0-(fRadius/runRmax)));"\
                                        "     }"\
                                        "     sampleCount = sampleCount + 
0.0+1.0*sampleCountR;"\
                                        "         aoH = aoH + sin( atan( maxAOH 
));"\
                                        "   }"\
                                        "   aoH = 
clamp(aoH/sampleCount,0.0,1.0);"\
                                        "   float aoTangle = atan( 
tangent0.z/length(tangent0.xy) );"\
                                        "   float aoT = sin( aoTangle );"\
                                        "   float ao = aoH + 0.0*aoT;"\
                                        "   float notValid = 
0.0*(1.0-step(0.0,depth0));"\
                                        "   float notValid_T = 
0.0*(step(1.5708,abs(aoTangle)));"\
                                        "   ao =  (1.0-notValid)  *ao;"\
                                        "   ao =  (1.0-notValid_T)*ao;"\
                                        "       gl_FragColor.rgb = 
tangent0*0.0+1.0*clamp(vec3(ao,ao,ao),0.0,1.0);"\
                                        "       gl_FragColor.a = 1.0;"\
                                        "}"     
                                        );

                                program->addShader(fragment_shader.get());
                                addPass(ss.get());
                        }

                        {   // Gaussian V  3
                                osg::ref_ptr<osg::StateSet> ss = new 
osg::StateSet;

                                osg::ref_ptr<osg::Program> program = new 
osg::Program;
                                ss->setAttribute(program.get());

                                osg::ref_ptr<osg::Uniform> samplerRTScene = new 
osg::Uniform("samplerRTScene",0);
                                ss->addUniform(samplerRTScene.get());


                                osg::ref_ptr<osg::Shader> vertex_shader = new 
osg::Shader(osg::Shader::VERTEX,
                                        "varying vec2 vTexCoord;"\
                                        "void main(void)"\
                                        "{"\
                                        "       gl_Position = ftransform();"\
                                        "       vec2 Pos = gl_Vertex.xy;"\
                                        "       vTexCoord = Pos;"\
                                        "}"
                                        );
                                program->addShader(vertex_shader.get());


                                osg::ref_ptr<osg::Shader> fragment_shader = new 
osg::Shader(osg::Shader::FRAGMENT,
                                        "uniform sampler2D samplerRTScene;"\
                                        "varying vec2 vTexCoord;"\
                                        "const float blurSize = 1.0/256.0; "\
                                        "void main(void)"\
                                        "{"\
                                        "       vec4 sum = vec4(0.0);"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x - 6.0*blurSize, vTexCoord.y)) *  
1.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x - 5.0*blurSize, vTexCoord.y)) *  
2.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x - 4.0*blurSize, vTexCoord.y)) *  
4.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x - 3.0*blurSize, vTexCoord.y)) *  
8.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x - 2.0*blurSize, vTexCoord.y)) * 
16.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x - blurSize    , vTexCoord.y)) * 
32.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x               , vTexCoord.y)) * 
64.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x + blurSize    , vTexCoord.y)) * 
32.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x + 2.0*blurSize, vTexCoord.y)) * 
16.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x + 3.0*blurSize, vTexCoord.y)) *  
8.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x + 4.0*blurSize, vTexCoord.y)) *  
4.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x + 5.0*blurSize, vTexCoord.y)) *  
2.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x + 6.0*blurSize, vTexCoord.y)) *  
1.0/190.0;"\
                                        "       gl_FragColor = sum;"\
                                        "}"     
                                        );
                                program->addShader(fragment_shader.get());


                                addPass(ss.get());
                        }
                        {   // Gaussian H  4
                                osg::ref_ptr<osg::StateSet> ss = new 
osg::StateSet;



                                osg::ref_ptr<osg::Program> program = new 
osg::Program;
                                ss->setAttribute(program.get());

                                osg::ref_ptr<osg::Uniform> samplerRTScene = new 
osg::Uniform("samplerRTScene",0);
                                ss->addUniform(samplerRTScene.get());


                                osg::ref_ptr<osg::Shader> vertex_shader = new 
osg::Shader(osg::Shader::VERTEX,
                                        "varying vec2 vTexCoord;"\
                                        "void main(void)"\
                                        "{"\
                                        "       gl_Position = ftransform();"\
                                        "       vec2 Pos = gl_Vertex.xy;"\
                                        "       vTexCoord = Pos;"\
                                        "}"
                                        );
                                program->addShader(vertex_shader.get());


                                osg::ref_ptr<osg::Shader> fragment_shader = new 
osg::Shader(osg::Shader::FRAGMENT,
                                        "uniform sampler2D samplerRTScene;"\
                                        "varying vec2 vTexCoord;"\
                                        "const float blurSize = 1.0/256.0; "\
                                        "void main(void)"\
                                        "{"\
                                        "       vec4 sum = vec4(0.0);"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y - 6.0*blurSize)) *  
1.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y - 5.0*blurSize)) *  
2.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y - 4.0*blurSize)) *  
4.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y - 3.0*blurSize)) *  
8.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y - 2.0*blurSize)) * 
16.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y - blurSize    )) * 
32.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y               )) * 
64.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y + blurSize    )) * 
32.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y + 2.0*blurSize)) * 
16.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y + 3.0*blurSize)) *  
8.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y + 4.0*blurSize)) *  
4.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y + 5.0*blurSize)) *  
2.0/190.0;"\
                                        "       sum += 
texture2D(samplerRTScene, vec2(vTexCoord.x, vTexCoord.y + 6.0*blurSize)) *  
1.0/190.0;"\
                                        "       gl_FragColor = sum;"\
                                        "}"     
                                        );
                                program->addShader(fragment_shader.get());
                                addPass(ss.get());
                        }



                        {   // Final Pass
                                osg::ref_ptr<osg::StateSet> ss = new 
osg::StateSet;
                                addPass(ss.get());
                        }
                }

        private:

                struct RTTInfo {
                        // RTT
                        osg::ref_ptr<osg::Camera>       _camera;
                        osg::ref_ptr<osg::TexGen>       _texgen;
                        osg::ref_ptr<osg::Texture2D>    _texture;
                        osg::ref_ptr<osg::StateSet>     _stateset;
                        osg::ref_ptr<osg::Image>        _image;

                        unsigned int                                    
_resolution_x;
                        unsigned int                                    
_resolution_y;
                };

                RTTInfo                                         
_RTTInfoTangentDepth;
                RTTInfo                                         _RTTInfoSSAO;

                RTTInfo                                         
_RTTInfoGaussianH;
                RTTInfo                                         
_RTTInfoGaussianV;

                osg::ref_ptr<osg::Group> _scene;

                osg::ref_ptr<osg::Uniform> _nearUniform;
                osg::ref_ptr<osg::Uniform> _farUniform;
                osg::ref_ptr<osg::Uniform> _cameraPos;

                osg::ref_ptr<osg::Uniform> _nearA;
                osg::ref_ptr<osg::Uniform> _nearB;
                osg::ref_ptr<osg::Uniform> _nearC;
                osg::ref_ptr<osg::Uniform> _farA;
                osg::ref_ptr<osg::Uniform> _farB;
                osg::ref_ptr<osg::Uniform> _farC;
 

                osg::ref_ptr<osg::Uniform> _inverseMVPWUniform;

        };

}

SSAO::SSAO(osg::Group* rootGrp)  :    Effect(),_root(rootGrp) {
}

SSAO::SSAO(const SSAO& copy, const osg::CopyOp& copyop)   :    Effect(copy, 
copyop){
}

bool SSAO::define_techniques()
{
        addTechnique(new DefaultTechnique(_root.get(),this));
        return true;
}





class SSAOViewerEventHandler : public osgGA::GUIEventHandler
{
public:
        SSAOViewerEventHandler(osg::Switch* s) : 
          _switch(s)
          {
          }
          virtual bool handle(const osgGA::GUIEventAdapter& 
ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor*) 
          { 
                  osgViewer::Viewer* viewer = 
dynamic_cast<osgViewer::Viewer*>(&aa);
                  if (!viewer) return false;



                  if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN)
                  {
                          switch (ea.getKey())
                          {
                          case 'a': 
                                  if ( _switch->getValue(0) ) {
                                          _switch->setAllChildrenOff();
                                          _switch->setValue(1,true);
                                  } else {
                                          _switch->setAllChildrenOff();
                                          _switch->setValue(0,true);
                                  }
                                  return true;
                          case 'q':
                                  global_debug_on = !global_debug_on;
                                  std::cout << ">> write debug images:" << 
global_debug_on << std::endl;
                                  return true;
                          }
                  }

                  return false;

          }

          osg::ref_ptr<osg::Switch> _switch;
};

int main(int argc, char** argv)
{

        putenv("OSG_WINDOW=128 128 512 512");

        // use an ArgumentParser object to manage the program arguments.
        osg::ArgumentParser arguments(&argc,argv);

        
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
        
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+"
 is the standard OpenSceneGraph example which loads and visualises 3d models.");
        
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+"
 [options] filename ...");
        arguments.getApplicationUsage()->addCommandLineOption("--image 
<filename>","Load an image and render it on a quad");
        arguments.getApplicationUsage()->addCommandLineOption("--dem 
<filename>","Load an image/DEM and render it on a HeightField");
        arguments.getApplicationUsage()->addCommandLineOption("--login <url> 
<username> <password>","Provide authentication information for http file 
access.");

        osgViewer::Viewer viewer(arguments);

        unsigned int helpType = 0;
        if ((helpType = arguments.readHelpType()))
        {
                arguments.getApplicationUsage()->write(std::cout, helpType);
                return 1;
        }

        // report any errors if they have occurred when parsing the program 
arguments.
        if (arguments.errors())
        {
                arguments.writeErrorMessages(std::cout);
                return 1;
        }

        if (arguments.argc()<=1)
        {
                
arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
                return 1;
        }

        std::string url, username, password;
        while(arguments.read("--login",url, username, password))
        {
                if (!osgDB::Registry::instance()->getAuthenticationMap())
                {
                        osgDB::Registry::instance()->setAuthenticationMap(new 
osgDB::AuthenticationMap);
                        
osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails(
                                url,
                                new osgDB::AuthenticationDetails(username, 
password)
                                );
                }
        }

        // set up the camera manipulators.
        {
                osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> 
keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;

                keyswitchManipulator->addMatrixManipulator( '1', "Trackball", 
new osgGA::TrackballManipulator() );
                keyswitchManipulator->addMatrixManipulator( '2', "Flight", new 
osgGA::FlightManipulator() );
                keyswitchManipulator->addMatrixManipulator( '3', "Drive", new 
osgGA::DriveManipulator() );
                keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new 
osgGA::TerrainManipulator() );

                std::string pathfile;
                char keyForAnimationPath = '5';
                while (arguments.read("-p",pathfile))
                {
                        osgGA::AnimationPathManipulator* apm = new 
osgGA::AnimationPathManipulator(pathfile);
                        if (apm || !apm->valid()) 
                        {
                                unsigned int num = 
keyswitchManipulator->getNumMatrixManipulators();
                                keyswitchManipulator->addMatrixManipulator( 
keyForAnimationPath, "Path", apm );
                                
keyswitchManipulator->selectMatrixManipulator(num);
                                ++keyForAnimationPath;
                        }
                }

                viewer.setCameraManipulator( keyswitchManipulator.get() );
        }

        // add the state manipulator
        viewer.addEventHandler( new 
osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );

        // add the thread model handler
        viewer.addEventHandler(new osgViewer::ThreadingHandler);

        // add the window size toggle handler
        viewer.addEventHandler(new osgViewer::WindowSizeHandler);

        // add the stats handler
        viewer.addEventHandler(new osgViewer::StatsHandler);

        // add the help handler
        viewer.addEventHandler(new 
osgViewer::HelpHandler(arguments.getApplicationUsage()));

        // add the record camera path handler
        viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);

        // add the LOD Scale handler
        viewer.addEventHandler(new osgViewer::LODScaleHandler);

        // add the screen capture handler
        viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);

        osg::ref_ptr<osg::Switch> switchNode = new osg::Switch;
        osg::ref_ptr<SSAOViewerEventHandler> ssaoViewerEventHandler= new 
SSAOViewerEventHandler(switchNode.get());
        viewer.addEventHandler(ssaoViewerEventHandler.get());


        // load the data
        osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
        if (!loadedModel) 
        {
                std::cout << arguments.getApplicationName() <<": No data 
loaded" << std::endl;
                loadedModel = osgDB::readNodeFile("cow.osg");
                if (!loadedModel) return 1;
        }

        // any option left unread are converted into errors to write out later.
        arguments.reportRemainingOptionsAsUnrecognized();

        // report any errors if they have occurred when parsing the program 
arguments.
        if (arguments.errors())
        {
                arguments.writeErrorMessages(std::cout);
                return 1;
        }


        // optimize the scene graph, remove redundant nodes and state etc.
        osgUtil::Optimizer optimizer;
        optimizer.optimize(loadedModel.get());

        // SWITCH
        switchNode->addChild(loadedModel.get(),false);

        // SSAO
        osg::ref_ptr<osg::Group> grpSSAOModel = new osg::Group;
        grpSSAOModel->addChild(loadedModel.get());
        osg::ref_ptr<SSAO> ssao = new SSAO(grpSSAOModel.get());
        ssao->addChild(grpSSAOModel.get());
        osg::ref_ptr<osg::Group> grpSSAO = new osg::Group;
        grpSSAO->addChild(ssao.get());
        switchNode->addChild(grpSSAO.get(),true);

        viewer.setSceneData( switchNode.get() );


        viewer.realize();

        return viewer.run();

}
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to