查看: 921|回复: 0

osg 获取深度纹理

[复制链接]

该用户从未签到

发表于 2015-11-28 16:38:36 | 显示全部楼层 |阅读模式
想获取深度纹理 然后传给Shader ,深度纹理没有值 但场景有阴影

  1. // osgTest.cpp : Defines the entry point for the console application.
  2. //

  3. #include "stdafx.h"


  4. #include <osg/ComputeBoundsVisitor>
  5. #include <osg/MatrixTransform>
  6. #include <osg/ShapeDrawable>
  7. #include <osgUtil/Tessellator>
  8. #include <osg/CullFace>
  9. #include <osg/PolygonOffset>
  10. #include <osg/StateSet>
  11. #include <osg/TexGen>
  12. #include <osg/Program>
  13. #include <osg/Light>
  14. #include <osg/LightSource>
  15. #include <osg/PositionAttitudeTransform>

  16. #include <osgDB/ReadFile>

  17. #include <osgGA/DriveManipulator>

  18. #include <osgViewer/Viewer>
  19. #include <osgViewer/ViewerEventHandlers>

  20. #include <osgWidget/PdfReader>

  21. #include <osgShadow/ShadowedScene>
  22. #include <osgShadow/SoftShadowMap>


  23. static int ReceivesShadowTraversalMask = 0x1;
  24. static int CastsShadowTraversalMask = 0x2;
  25. osg::Vec3 eyePos(0,0.0,10);
  26. osg::Vec3 targetPos(0.0,0.0,0.0);

  27. class CameraUpdateCallBack:public osg::NodeCallback
  28. {
  29. public:
  30.     CameraUpdateCallBack(osg::MatrixTransform*mat): _eye(0.0f,0,0)
  31.     {
  32.         _mat=mat;
  33.     }
  34.    
  35.     virtual ~CameraUpdateCallBack(){
  36.         
  37.     }
  38.     virtual void operator()(osg::Node*node,osg::NodeVisitor*nv){
  39.         osg::Camera*camera = dynamic_cast<osg::Camera*>(node);
  40.         if(camera){
  41.             //      if(camera->getName().compare("MasterCamera")==0){
  42.             osg::Vec3 eye,center,up;
  43.             double left,right,bottom,top,znear,zfar;
  44.             camera->getViewMatrixAsLookAt(eye, center, up);
  45.             camera->getProjectionMatrixAsOrtho(left, right, bottom, top, znear, zfar);
  46.             
  47.             _eye=eye;//记录相机坐标
  48.             
  49.         }
  50.         //    osg::MatrixTransform*mat=dynamic_cast<osg::MatrixTransform*>(node);
  51.         if(_mat){
  52.             osg::Matrix mm=_mat->getMatrix();
  53.             osg::Vec3 _eyeTmp=mm.getTrans();
  54.             mm.makeTranslate(_eyeTmp);
  55.             _mat->setMatrix(mm);
  56.             osg::Matrix m;
  57.             m.makeTranslate(_eye);
  58.             _mat->setMatrix(m);
  59.         }
  60.         traverse(node, nv);
  61.     }
  62. private:
  63.     osg::Vec3 _eye;
  64.     osg::MatrixTransform *_mat;
  65.    
  66. };

  67. static const char fragmentShaderSource_noBaseTexture[] =
  68. "uniform sampler2DShadow osgShadow_shadowTexture; \n"
  69. "uniform vec2 osgShadow_ambientBias; \n"
  70. "\n"
  71. "void main(void) \n"
  72. "{ \n"
  73. "    gl_FragColor =  vec4(1.0f,0.0f,0.0f,0.0f); \n"
  74. "}\n";




  75. class shadow_X;

  76. class CameraCullCallbackA : public osg::NodeCallback
  77. {
  78. public:
  79.     CameraCullCallbackA(shadow_X *s)
  80.     {
  81.         __shadow = s;
  82.     }
  83.     virtual void operator()(osg::Node*, osg::NodeVisitor* nv);
  84. protected:
  85.     shadow_X* __shadow;
  86. };

  87. class shadow_X:public osg::Object
  88. {
  89. public:
  90.     shadow_X(){
  91.         _textureSize = osg::Vec2(1024,1024) ;_dirty = true;
  92.         _baseTextureUnit = 0;
  93.         _shadowTextureUnit = 1;
  94.     }
  95.          shadow_X(const shadow_X& es, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): osg::Object(es,copyop)
  96.          {
  97.                
  98.          }
  99.         META_Object(osgshadow_X, shadow_X);
  100.     void traverse(osg::NodeVisitor& nv)
  101.     {
  102.         if (_dirty) init();
  103.         if (nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
  104.         {
  105.             update(nv);
  106.         }
  107.         
  108.         if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
  109.         {
  110.             osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
  111.             if (cv)
  112.                 cull(*cv);
  113.             else
  114.                 _scene->osg::Group::traverse(nv);
  115.         }
  116.         else
  117.         {
  118.             _scene->osg::Group::traverse(nv);
  119.         }
  120.     }
  121.     void cull(osgUtil::CullVisitor& cv)
  122.     {
  123.         // record the traversal mask on entry so we can reapply it later.
  124.         unsigned int traversalMask = cv.getTraversalMask();
  125.         
  126.         osgUtil::RenderStage* orig_rs = cv.getRenderStage();
  127.         
  128.         // do traversal of shadow recieving scene which does need to be decorated by the shadow map
  129.         {
  130.             cv.pushStateSet(_stateset.get());
  131.             
  132.             _scene->osg::Group::traverse(cv);
  133.             
  134.             cv.popStateSet();
  135.             
  136.         }
  137.         
  138.         cv.setTraversalMask( traversalMask );//????
  139.         
  140.         // do RTT camera traversal
  141.         _camera->accept(cv);
  142.         
  143.         _texgen->setMode(osg::TexGen::EYE_LINEAR);
  144.         
  145.         // compute the matrix which takes a vertex from local coords into tex coords
  146.         // We actually use two matrices one used to define texgen
  147.         // and second that will be used as modelview when appling to OpenGL
  148.         _texgen->setPlanesFromMatrix( _camera->getProjectionMatrix() *
  149.                                      osg::Matrix::translate(1.0,1.0,1.0) *
  150.                                      osg::Matrix::scale(0.5f,0.5f,0.5f) );
  151.         
  152.         // Place texgen with modelview which removes big offsets (making it float friendly)
  153.         osg::RefMatrix * refMatrix = new osg::RefMatrix
  154.         ( _camera->getInverseViewMatrix() * *cv.getModelViewMatrix() );
  155.         
  156.         cv.getRenderStage()->getPositionalStateContainer()->
  157.         addPositionedTextureAttribute( _shadowTextureUnit, refMatrix, _texgen.get() );
  158.         
  159.     }
  160.     void initTexture()
  161.     {
  162.         _texture = new osg::Texture2D;
  163.         _texture->setTextureSize(_textureSize.x(), _textureSize.y());
  164.         _texture->setInternalFormat(GL_DEPTH_COMPONENT);
  165.         _texture->setShadowComparison(true);
  166.         _texture->setShadowTextureMode(osg::Texture2D::LUMINANCE);
  167.         _texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
  168.         _texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
  169.         
  170.         _texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
  171.         _texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
  172.         _texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); //边缘部分深度全为1
  173.     }
  174.    
  175.     void initRTTCamera()
  176.     {
  177.         _camera = new osg::Camera;
  178.         _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT);//???
  179.         _camera->setCullCallback(new CameraCullCallbackA(this));
  180.         
  181.         _camera->setClearMask(GL_DEPTH_BUFFER_BIT);
  182.         _camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
  183.         _camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
  184.         _camera->setViewport(0,0,_textureSize.x(),_textureSize.y());
  185.         _camera->setViewMatrixAsLookAt(eyePos,targetPos,osg::Vec3(0,-1,0));
  186.         double aspectRatio=1.0;
  187.         double dNear=0.1;
  188.         double dFar=10;
  189.         _camera->setProjectionMatrixAsPerspective(45,aspectRatio,dNear,dFar);
  190.         _camera->setRenderOrder(osg::Camera::PRE_RENDER);
  191.         _camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
  192.         _camera->attach(osg::Camera::DEPTH_BUFFER, _texture.get());
  193.         
  194.         
  195.         osg::StateSet* stateset = _camera->getOrCreateStateSet();
  196.         
  197.         osg::ref_ptr<osg::CullFace> cull_face = new osg::CullFace;
  198.         cull_face->setMode(osg::CullFace::FRONT);
  199.         stateset->setAttribute(cull_face.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
  200.         stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
  201.         
  202.         float factor = -1.0;
  203.         float units =  -1.0;
  204.         
  205.         osg::ref_ptr<osg::PolygonOffset> polygon_offset = new osg::PolygonOffset;
  206.         polygon_offset->setFactor(factor);
  207.         polygon_offset->setUnits(units);
  208.         stateset->setAttribute(polygon_offset.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
  209.         stateset->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
  210.     }
  211.    
  212.     void createStateSet()
  213.     {
  214.         
  215.         _stateset = new osg::StateSet;
  216.         _stateset->setTextureAttributeAndModes(_shadowTextureUnit,_texture.get(),osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
  217.         _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
  218.         _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
  219.         _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
  220.         _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
  221.         
  222.         _texgen = new osg::TexGen;
  223.         
  224.         // add Program, when empty of Shaders then we are using fixed functionality
  225.         _program = new osg::Program;
  226.         _stateset->setAttribute(_program.get());
  227.         
  228.         //shader
  229.                 //osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_noBaseTexture);
  230.         osg::Shader* fragment_shader = osg::Shader::readShaderFile(osg::Shader::FRAGMENT,fragmentShaderSource_noBaseTexture);

  231.         _program->addShader(fragment_shader);
  232.         
  233.         //_ambientBias(0.5f,0.5f),
  234.         osg::Uniform* shadowTextureSampler = new osg::Uniform("osgShadow_shadowTexture",(int)_shadowTextureUnit);
  235.         osg::Uniform* baseTextureSampler = new osg::Uniform("osgShadow_baseTexture",(int)_baseTextureUnit);
  236.         
  237.         osg::Vec2 ambientBias(0.5f,0.5f);
  238.         osg::ref_ptr<osg::Uniform>  ambientBiasUniform = new osg::Uniform("osgShadow_ambientBias",ambientBias);
  239.         
  240.         _stateset->addUniform(shadowTextureSampler);
  241.         _stateset->addUniform(ambientBiasUniform);
  242.         _stateset->addUniform(baseTextureSampler);
  243.         
  244.         //fake image
  245.         osg::Image* image = new osg::Image;
  246.         // allocate the image data, noPixels x 1 x 1 with 4 rgba floats - equivilant to a Vec4!
  247.         int noPixels = 1;
  248.         image->allocateImage(noPixels,1,1,GL_RGBA,GL_FLOAT);
  249.         image->setInternalTextureFormat(GL_RGBA);
  250.         // fill in the image data.
  251.         osg::Vec4* dataPtr = (osg::Vec4*)image->data();
  252.         osg::Vec4 color(1,1,1,1);
  253.         *dataPtr = color;
  254.         // make fake texture
  255.         osg::Texture2D* fakeTex = new osg::Texture2D;
  256.         fakeTex->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_EDGE);
  257.         fakeTex->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_EDGE);
  258.         fakeTex->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
  259.         fakeTex->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
  260.         fakeTex->setImage(image);
  261.         // add fake texture
  262.         _stateset->setTextureAttribute(_baseTextureUnit,fakeTex,osg::StateAttribute::ON);
  263.         _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_2D,osg::StateAttribute::ON);
  264.         _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_3D,osg::StateAttribute::OFF);
  265.     }
  266.    
  267.         void update(osg::NodeVisitor &nv)
  268.         {
  269.                 _scene->osg::Group::traverse(nv);
  270.         }
  271.     void init()
  272.     {
  273.         initTexture();
  274.         initRTTCamera();
  275.         createStateSet();
  276.         
  277.         _dirty = false;
  278.     }
  279.    
  280.     void setScene(osg::Group * scene){_scene = scene;}
  281.    
  282.     osg::ref_ptr<osg::Group> getScene(){return _scene;}
  283. private:
  284.     bool _dirty;
  285.     osg::ref_ptr<osg::Texture2D>    _texture;
  286.     osg::ref_ptr<osg::Camera>       _camera;
  287.     osg::Vec2        _textureSize;
  288.     osg::ref_ptr<osg::StateSet>        _stateset;
  289.     unsigned int                    _baseTextureUnit;
  290.     unsigned int                    _shadowTextureUnit;
  291.     osg::ref_ptr<osg::TexGen>        _texgen;
  292.     osg::ref_ptr<osg::Program>        _program;
  293.     osg::ref_ptr<osg::Group>        _scene;
  294.    
  295. };


  296. void CameraCullCallbackA::operator()(osg::Node*, osg::NodeVisitor* nv)
  297. {
  298.     __shadow->getScene()->osg::Group::traverse(*nv);
  299. }

  300. class myNode :public osg::Group
  301. {
  302.     public :
  303.     myNode(shadow_X * s = nullptr){setNumChildrenRequiringUpdateTraversal(1); _shadow = s;}
  304.     void traverse(osg::NodeVisitor& nv)
  305.     {
  306.         if(_shadow)
  307.             _shadow->traverse(nv);
  308.         else
  309.             osg::Group::traverse(nv);
  310.     }
  311.     /** Resize any per context GLObject buffers to specified size. */
  312.          void resizeGLObjectBuffers(unsigned int maxSize)
  313.                 {
  314.                         if (_shadow) _shadow->resizeGLObjectBuffers(maxSize);
  315.                         Group::resizeGLObjectBuffers(maxSize);
  316.                 }

  317.         /** If State is non-zero, this function releases any associated OpenGL objects for
  318.            * the specified graphics context. Otherwise, releases OpenGL objects
  319.            * for all graphics contexts. */
  320.          void releaseGLObjects(osg::State* state) const
  321.                  {
  322.                          if (_shadow) _shadow->releaseGLObjects(state);
  323.                          Group::releaseGLObjects(state);
  324.                  }
  325. private:
  326.     shadow_X* _shadow;
  327. };

  328. osg::Geode* createWoodA(osg::ref_ptr<osg::Group> parent)
  329. {
  330.     osg::ref_ptr<osg::Geode> geode = new osg::Geode();
  331.     osg::Geometry* pointsGeom = new osg::Geometry();
  332.    
  333.     osg::Vec3Array* vertices = new osg::Vec3Array;
  334.     vertices->push_back(osg::Vec3(10, 10, 0));
  335.     vertices->push_back(osg::Vec3(-10,10, 0));
  336.     vertices->push_back(osg::Vec3(-10, -10,0));
  337.    
  338.     vertices->push_back(osg::Vec3(-10, -10,0));
  339.     vertices->push_back(osg::Vec3(10, -10,0));
  340.     vertices->push_back(osg::Vec3(10, 10,0));
  341.    
  342.     pointsGeom->setVertexArray(vertices);
  343.    
  344.     osg::Vec4Array* colors = new osg::Vec4Array;
  345.     colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
  346.     pointsGeom->setColorArray(colors, osg::Array::BIND_OVERALL);
  347.    
  348.    
  349.     // set the normal in the same way color.
  350.     /*osg::Vec3Array* normals = new osg::Vec3Array;
  351.      normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
  352.      pointsGeom->setNormalArray(normals, osg::Array::BIND_OVERALL);*/
  353.    
  354.     pointsGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,0,vertices->size()));
  355.     // add the points geometry to the geode.
  356.     geode->addDrawable(pointsGeom);
  357.    
  358.     parent->addChild(geode);
  359.    
  360.     return geode.release();
  361. }

  362. osg::Geode * createLineA(osg::ref_ptr<osg::Group> parent)
  363. {
  364.         osg::ref_ptr<osg::Geode> geode = new osg::Geode();
  365.     osg::Geometry* pointsGeom = new osg::Geometry();
  366.    
  367.     osg::Vec3Array* vertices = new osg::Vec3Array;
  368.      
  369.     vertices->push_back(eyePos);
  370.     vertices->push_back(targetPos);
  371.    
  372.         osg::Vec4Array* colors = new osg::Vec4Array;
  373.         colors->push_back(osg::Vec4(0.0f,1.0f,0.0f,1.0f));
  374.         pointsGeom->setColorArray(colors, osg::Array::BIND_OVERALL);

  375.     pointsGeom->setVertexArray(vertices);
  376.    
  377.     pointsGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,vertices->size()));
  378.     // add the points geometry to the geode.
  379.     geode->addDrawable(pointsGeom);
  380.    
  381.     parent->addChild(geode);
  382.    
  383.     return geode.release();
  384. }


  385. osg::Group* createModeA(osg::ref_ptr<osg::Group> parent)
  386. {
  387.    
  388.     osg::ref_ptr<osg::Node> cow  = osgDB::readNodeFile("glider.osg");
  389.     cow->setNodeMask(CastsShadowTraversalMask);
  390.    
  391.    
  392.     osg::ref_ptr<osg::MatrixTransform > cowScale = new osg::MatrixTransform;
  393.     osg::Matrix scale = osg::Matrix::scale(1,1,1);
  394.     osg::Matrix tansla = osg::Matrix::translate(0.0,0.0,2.0);
  395.     cowScale->setMatrix(tansla * scale);
  396.     cowScale->addChild(cow);
  397.    
  398.     parent->addChild(cowScale);
  399.    
  400.     osg::ComputeBoundsVisitor cbbv;
  401.     cowScale->accept(cbbv);
  402.    
  403.     osg::BoundingBox bb=cbbv.getBoundingBox();
  404.    
  405.     return cowScale.release();
  406. }

  407. osg::ref_ptr<osg::Node>createLightA()  
  408. {  
  409.    
  410.     osg::ref_ptr<osg::Light>lt=new osg::Light;  
  411.     lt->setLightNum(0);  
  412.    
  413.     //设置环境光的颜色  
  414.     lt->setAmbient(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
  415.     lt->setPosition(osg::Vec4(eyePos,0));

  416.     osg::ref_ptr<osg::LightSource>ls=new osg::LightSource();  
  417.    
  418.     ls->setLight(lt.get());  

  419.    
  420.     return ls.get();
  421. }

  422. int main()  
  423. {  
  424.    
  425.     osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();  
  426.     viewer->addEventHandler(new osgViewer::WindowSizeHandler);  
  427.     //创建一个组节点  
  428.    

  429.     shadow_X * sh = new shadow_X();
  430.      osg::ref_ptr<myNode> node = new myNode(sh);
  431.      sh->setScene(node);
  432.      
  433.      osg::ref_ptr<osg::Geode> wood = createWoodA(node);
  434.      osg::ref_ptr<osg::Group> cow = createModeA(node);
  435.          createLineA(node);

  436.   
  437.     viewer->setSceneData(node);
  438.     viewer->realize();  
  439.     viewer->run();  
  440.    
  441.     return 0 ;  
  442. }



复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表