Hi Robert,

this is my first implementation test for a wazabee 3D Multiview (fullscreen)
display. this implementation has the right interlacer implement as a GLSL
shader. i am awar of the fact that the osgFX Effect / Technic wouldn't be
the
correct place to implement just display support, but it was the fastest way
for prototyping of the interlacer. I don't longer need the spatial view
interlacing SDK, even under Mac or Linux this should work.

/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/Uniform>

#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/Texture2D>

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

#include <sstream>
 


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

                META_Effect(osgFX, Wazabee, 

                        "Wazabee : Spatial View Integration : 1440 x 900 (19'') 
Screen ", 

                        "Wazabee : This is just a first hack. ( :-( )", 

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

                bool define_techniques();

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

}



using namespace osgFX;


namespace
{


        osg::Group* createBase()
        {

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

                // set up the texture of the base.
                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 Wazabee);

        class DefaultTechnique: public Technique {
        public:

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

                          osg::ref_ptr<osg::StateSet> ss = 
sceneFinal->getOrCreateStateSet();

                          for (unsigned int iLoop=0;iLoop<5;iLoop++) {


                                  // texture resolution 
                                  _RTTCameras[iLoop]._resolution_x = 1440;
                                  _RTTCameras[iLoop]._resolution_y = 900;

                                  // texture
                                  _RTTCameras[iLoop]._texture = new 
osg::Texture2D;
                                  
_RTTCameras[iLoop]._texture->setTextureSize(_RTTCameras[iLoop]._resolution_x, 
_RTTCameras[iLoop]._resolution_y);
                                  
_RTTCameras[iLoop]._texture->setInternalFormat(GL_RGBA);
                                  
_RTTCameras[iLoop]._texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
                                  
_RTTCameras[iLoop]._texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);
                                  
_RTTCameras[iLoop]._texture->setResizeNonPowerOfTwoHint(false);

                                  // camera 
                                  _RTTCameras[iLoop]._camera = new osg::Camera;

                                  /* 
                                  // debug interlacing with color coded texture
                                  osg::Vec4 cc;
                                  switch(iLoop)
                                  {
                                  case 0:
                                          cc.set(1,0,0,1);
                                          break;
                                  case 1:
                                          cc.set(0,1,0,1);
                                          break;
                                  case 2:
                                          cc.set(0,0,1,1);
                                          break;
                                  case 3:
                                          cc.set(1,1,0,1);
                                          break;
                                  case 4:
                                          cc.set(0,1,1,1);
                                          break;
                                  default:
                                          cc.set(0,0,0,1);
                                          break;
                                  }
                                  _RTTCameras[iLoop]._camera->setClearColor(cc);
                                  */
                                  
_RTTCameras[iLoop]._camera->setClearMask(GL_COLOR_BUFFER_BIT | 
GL_DEPTH_BUFFER_BIT);
                                  
_RTTCameras[iLoop]._camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
                                  // set viewport
                                  
_RTTCameras[iLoop]._camera->setViewport(0,0,_RTTCameras[iLoop]._resolution_x,_RTTCameras[iLoop]._resolution_y);
                                  // set the camera to render before the main 
camera.
                                  
_RTTCameras[iLoop]._camera->setRenderOrder(osg::Camera::PRE_RENDER);
                                  // tell the camera to use OpenGL frame buffer 
object where supported.
                                  
_RTTCameras[iLoop]._camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
                                  
_RTTCameras[iLoop]._camera->attach(osg::Camera::COLOR_BUFFER, 
_RTTCameras[iLoop]._texture.get());
                                  // add subgraph to render
                                  
_RTTCameras[iLoop]._camera->addChild(_scene.get());  

                          }

                          for (unsigned int iLoop=0;iLoop<5;iLoop++) {
                                  
//////////////////////////////////////////////////////////////////////////
                                  // set effect textures....(5 textures)
                                  
ss->setTextureAttributeAndModes(iLoop,_RTTCameras[iLoop]._texture.get(),osg::StateAttribute::ON);
                                  std::stringstream sstrSamplerRTT;
                                  sstrSamplerRTT << "samplerRTT" << iLoop; 
                                  osg::ref_ptr<osg::Uniform> samplerText = new 
osg::Uniform(osg::Uniform::SAMPLER_2D,sstrSamplerRTT.str().c_str());
                                  samplerText->set((int)iLoop);
                                  ss->addUniform(samplerText.get());
                          }

                          _inter_image=new osg::Image;
                          _inter_image->allocateImage(1440, 900,  1, GL_RGBA, 
GL_FLOAT);
                          // texture
                          _inter_texture = new osg::Texture2D;
                          _inter_texture->setImage(0,_inter_image.get());
                          _inter_texture->setTextureSize(1440, 900);
                          _inter_texture->setInternalFormat(GL_RGBA);
                          
_inter_texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
                          
_inter_texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);
                          _inter_texture->setResizeNonPowerOfTwoHint(false);

                          
ss->setTextureAttributeAndModes(5,_inter_texture.get(),osg::StateAttribute::ON);
                          osg::ref_ptr<osg::Uniform> samplerText = new 
osg::Uniform(osg::Uniform::SAMPLER_2D,"samplerSelectText");
                          samplerText->set(5);
                          ss->addUniform(samplerText.get());

                          // fill in the image data.
                          const int interSchemaS[5] = {1,4,2,0,3};
                          const int interSchemaT[5] = {4,3,2,1,0};
                          for (unsigned int t=0;t<900;t++){
                                  for (unsigned int s=0;s<1440;s++){
                                          int ms = s % 5;
                                          int mt = t % 5;
                                          double v = ((double)(  
(interSchemaS[ms]+interSchemaT[mt]) % 5) )/5.0;
                                          //if ( t < 5  && s < 5) std::cout << 
"(" << (v*5) << ")";
                                          osg::Vec4 color(v,v,v,v);
                                          osg::Vec4* dataPtr = 
(osg::Vec4*)_inter_image->data(s,t);
                                          *dataPtr = color;
                                  }
                                  //if ( t < 5 ) std::cout << std::endl;
                          }
 
                          osg::ref_ptr<osg::Program> program = new osg::Program;
                          ss->setAttribute(program.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 samplerRTT0;"\
                                  "uniform sampler2D samplerRTT1;"\
                                  "uniform sampler2D samplerRTT2;"\
                                  "uniform sampler2D samplerRTT3;"\
                                  "uniform sampler2D samplerRTT4;"\
                                  "uniform sampler2D samplerSelectText;"\
                                  "varying vec2 vTexCoord;"\
                                  "void main(void)"\
                                  "{"\
                                  " float modS = 
step(mod(vTexCoord.s*512.0,5.0),0.0);"\
                                  " float modT = 
step(mod(vTexCoord.t*512.0,5.0),0.0);"\
                                  " vec4 cS = 
texture2D(samplerSelectText,vTexCoord.st);"\
                                  " vec4 final = vec4(1,1,1,1);"\
                                  " vec4 c0 = 
texture2D(samplerRTT0,vTexCoord.st);"\
                                  " vec4 c1 = 
texture2D(samplerRTT1,vTexCoord.st);"\
                                  " vec4 c2 = 
texture2D(samplerRTT2,vTexCoord.st);"\
                                  " vec4 c3 = 
texture2D(samplerRTT3,vTexCoord.st);"\
                                  " vec4 c4 = 
texture2D(samplerRTT4,vTexCoord.st);"\
                                  " float sel = 0.0;"\
                                  " float selTmp = 0.0;"\
                                  " sel = step(cS.x,0.01);"\
                                  " final = sel*c0;"\
                                  " selTmp = 
clamp((1.0-sel)*step(cS.x,0.21),0.0,1.0);"\
                                  " sel = clamp(sel+selTmp,0.0,1.0);"\
                                  " final = final + selTmp*c1;"\
                                  " selTmp = 
clamp((1.0-sel)*step(cS.x,0.41),0.0,1.0);"\
                                  " sel = clamp(sel+selTmp,0.0,1.0);"\
                                  " final = final + selTmp*c2;"\
                                  " selTmp = 
clamp((1.0-sel)*step(cS.x,0.61),0.0,1.0);"\
                                  " sel = clamp(sel+selTmp,0.0,1.0);"\
                                  " final = final + selTmp*c3;"\
                                  " selTmp = 
clamp((1.0-sel)*step(cS.x,0.81),0.0,1.0);"\
                                  " sel = clamp(sel+selTmp,0.0,1.0);"\
                                  " final = final + selTmp*c4;"\
                                  " gl_FragColor = final;"\
                                  "}"   
                                  );
                          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;

                          return true;
                  }


                  /** optional: return a node that overrides the child node on 
a specified pass */
                  inline virtual osg::Node* getOverrideChild(int passNum)  { 
                          if ( passNum < 5 ) { 
                                  return _RTTCameras[passNum]._camera.get();
                          }
                           

                          return _sceneFinal.get(); 

                  }

                  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();
                                  
                                  for (unsigned int iLoop=0;iLoop<5;iLoop++) {

                                          
_RTTCameras[iLoop]._camera->setViewMatrix(cv->getRenderInfo().getView()->getCamera()->getViewMatrix());
                                          
_RTTCameras[iLoop]._camera->setProjectionMatrix(cv->getRenderInfo().getView()->getCamera()->getProjectionMatrix());
                                          osg::ref_ptr<osg::Viewport> vp = 
cv->getRenderInfo().getView()->getCamera()->getViewport();
                                          osg::ref_ptr<osg::Viewport> vpCam = 
_RTTCameras[iLoop]._camera->getViewport();
                                          if ( vpCam->width()!=vp->width() || 
vpCam->height()!=vp->height()  ) {
                                                  
_RTTCameras[iLoop]._camera->getViewport()->setViewport(
                                                          0,
                                                          0,
                                                          std::min((unsigned 
int)vp->width(),_RTTCameras[iLoop]._resolution_x),
                                                          std::min((unsigned 
int)vp->height(),_RTTCameras[iLoop]._resolution_y)
                                                          );            
                                          }

                                         
                                          double fusionDistance = 
1.0;//cv->getRenderInfo().getView()->getCameraManipulator()->getFusionDistanceValue();
                                          double eyeSeparation  = 
osg::DisplaySettings::instance()->getEyeSeparation();//cv->getRenderInfo().getView()->getDisplaySettings()->getEyeSeparation();
                                          double screenDistance = 
osg::DisplaySettings::instance()->getScreenDistance();//cv->getRenderInfo().getView()->getDisplaySettings()->getScreenDistance();
std::cout << eyeSeparation << "," << screenDistance << std::endl;
                                          osg::Matrixd masterProjection = 
cv->getRenderInfo().getView()->getCamera()->getProjectionMatrix();
                                          int cameraCount = 5;
                                           
                                          double es = 
(eyeSeparation/screenDistance);
                                          double start = 0.5 * (es * 
(cameraCount - 1));
                                          osg::Matrix offsetP;
                                          offsetP.ptr()[8] = start - (es * 
iLoop);
                                          
_RTTCameras[iLoop]._camera->setProjectionMatrix(offsetP * masterProjection);
                                   

                                          osg::Matrixd masterView = 
cv->getRenderInfo().getView()->getCamera()->getViewMatrix();

                                          es = fusionDistance * 
(eyeSeparation/screenDistance);
                                          start = 0.5 * (es * (cameraCount - 
1));
                                          osg::Matrix offsetV;
                                          offsetV.ptr()[12] = start - (es * 
iLoop); 
                                         
_RTTCameras[iLoop]._camera->setViewMatrix(masterView * offsetV);
                                           

                                  }
                          }


                          traverse_implementation(nv, fx);

                  }


        protected:

                void define_passes()
                {
 

                        for (unsigned int iLoop=0;iLoop<5+1;iLoop++) {
                            // 5 + 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::Texture2D>    _texture;
                        osg::ref_ptr<osg::StateSet>     _stateset;
                        osg::ref_ptr<osg::Image>        _image;

                        unsigned int                                    
_resolution_x;
                        unsigned int                                    
_resolution_y;
                };

                RTTInfo                                  _RTTCameras[5];
 
                osg::ref_ptr<osg::Group> _scene;
                osg::ref_ptr<osg::Group> _sceneFinal;
                osg::ref_ptr<osg::Texture2D> _inter_texture;
                osg::ref_ptr<osg::Image> _inter_image;

        };

}

Wazabee::Wazabee(osg::Group* rootGrp)  :    Effect(),_root(rootGrp) {



        int resolution_x = 1440;
        int resolution_y = 900;

        // camera 
        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
        camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
        // set viewport
        camera->setViewport(0,0,resolution_x,resolution_y);
        
camera->setViewMatrixAsLookAt(osg::Vec3(0.5,0.5,1),osg::Vec3(0.5,0.5,0),osg::Vec3(0,1,0));
        camera->setProjectionMatrixAsOrtho2D(-0.5,0.5,-0.5,0.5);

        osg::Group* base = createBase();
        osg::PolygonMode* polyModeObj = new osg::PolygonMode;
        
polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::FILL ); 
        base->getOrCreateStateSet()->setAttribute(polyModeObj);


        _baseRoot = camera.get();
        camera->addChild(base);
 
}
Wazabee::Wazabee(const Wazabee& copy, const osg::CopyOp& copyop)   :    
Effect(copy, copyop){
}

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




 
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);

  

        // 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());

 
        // Wazabee
        osg::ref_ptr<osg::Group> grpWazabeeModel = new osg::Group;
        grpWazabeeModel->addChild(loadedModel.get());
        osg::ref_ptr<Wazabee> wazabee = new Wazabee(grpWazabeeModel.get());
        wazabee->addChild(loadedModel.get());
        osg::ref_ptr<osg::Group> grpWazabee = new osg::Group;
        grpWazabee->addChild(wazabee.get());
 
        viewer.setSceneData( grpWazabee.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