|
想获取深度纹理 然后传给Shader ,深度纹理没有值 但场景有阴影
- // osgTest.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
-
- #include <osg/ComputeBoundsVisitor>
- #include <osg/MatrixTransform>
- #include <osg/ShapeDrawable>
- #include <osgUtil/Tessellator>
- #include <osg/CullFace>
- #include <osg/PolygonOffset>
- #include <osg/StateSet>
- #include <osg/TexGen>
- #include <osg/Program>
- #include <osg/Light>
- #include <osg/LightSource>
- #include <osg/PositionAttitudeTransform>
- #include <osgDB/ReadFile>
- #include <osgGA/DriveManipulator>
- #include <osgViewer/Viewer>
- #include <osgViewer/ViewerEventHandlers>
- #include <osgWidget/PdfReader>
- #include <osgShadow/ShadowedScene>
- #include <osgShadow/SoftShadowMap>
- static int ReceivesShadowTraversalMask = 0x1;
- static int CastsShadowTraversalMask = 0x2;
- osg::Vec3 eyePos(0,0.0,10);
- osg::Vec3 targetPos(0.0,0.0,0.0);
- class CameraUpdateCallBack:public osg::NodeCallback
- {
- public:
- CameraUpdateCallBack(osg::MatrixTransform*mat): _eye(0.0f,0,0)
- {
- _mat=mat;
- }
-
- virtual ~CameraUpdateCallBack(){
-
- }
- virtual void operator()(osg::Node*node,osg::NodeVisitor*nv){
- osg::Camera*camera = dynamic_cast<osg::Camera*>(node);
- if(camera){
- // if(camera->getName().compare("MasterCamera")==0){
- osg::Vec3 eye,center,up;
- double left,right,bottom,top,znear,zfar;
- camera->getViewMatrixAsLookAt(eye, center, up);
- camera->getProjectionMatrixAsOrtho(left, right, bottom, top, znear, zfar);
-
- _eye=eye;//记录相机坐标
-
- }
- // osg::MatrixTransform*mat=dynamic_cast<osg::MatrixTransform*>(node);
- if(_mat){
- osg::Matrix mm=_mat->getMatrix();
- osg::Vec3 _eyeTmp=mm.getTrans();
- mm.makeTranslate(_eyeTmp);
- _mat->setMatrix(mm);
- osg::Matrix m;
- m.makeTranslate(_eye);
- _mat->setMatrix(m);
- }
- traverse(node, nv);
- }
- private:
- osg::Vec3 _eye;
- osg::MatrixTransform *_mat;
-
- };
-
- static const char fragmentShaderSource_noBaseTexture[] =
- "uniform sampler2DShadow osgShadow_shadowTexture; \n"
- "uniform vec2 osgShadow_ambientBias; \n"
- "\n"
- "void main(void) \n"
- "{ \n"
- " gl_FragColor = vec4(1.0f,0.0f,0.0f,0.0f); \n"
- "}\n";
- class shadow_X;
- class CameraCullCallbackA : public osg::NodeCallback
- {
- public:
- CameraCullCallbackA(shadow_X *s)
- {
- __shadow = s;
- }
- virtual void operator()(osg::Node*, osg::NodeVisitor* nv);
- protected:
- shadow_X* __shadow;
- };
- class shadow_X:public osg::Object
- {
- public:
- shadow_X(){
- _textureSize = osg::Vec2(1024,1024) ;_dirty = true;
- _baseTextureUnit = 0;
- _shadowTextureUnit = 1;
- }
- shadow_X(const shadow_X& es, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): osg::Object(es,copyop)
- {
-
- }
- META_Object(osgshadow_X, shadow_X);
- void traverse(osg::NodeVisitor& nv)
- {
- if (_dirty) init();
- if (nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
- {
- update(nv);
- }
-
- if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
- {
- osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
- if (cv)
- cull(*cv);
- else
- _scene->osg::Group::traverse(nv);
- }
- else
- {
- _scene->osg::Group::traverse(nv);
- }
- }
- void cull(osgUtil::CullVisitor& cv)
- {
- // record the traversal mask on entry so we can reapply it later.
- unsigned int traversalMask = cv.getTraversalMask();
-
- osgUtil::RenderStage* orig_rs = cv.getRenderStage();
-
- // do traversal of shadow recieving scene which does need to be decorated by the shadow map
- {
- cv.pushStateSet(_stateset.get());
-
- _scene->osg::Group::traverse(cv);
-
- cv.popStateSet();
-
- }
-
- cv.setTraversalMask( traversalMask );//????
-
- // do RTT camera traversal
- _camera->accept(cv);
-
- _texgen->setMode(osg::TexGen::EYE_LINEAR);
-
- // compute the matrix which takes a vertex from local coords into tex coords
- // We actually use two matrices one used to define texgen
- // and second that will be used as modelview when appling to OpenGL
- _texgen->setPlanesFromMatrix( _camera->getProjectionMatrix() *
- osg::Matrix::translate(1.0,1.0,1.0) *
- osg::Matrix::scale(0.5f,0.5f,0.5f) );
-
- // Place texgen with modelview which removes big offsets (making it float friendly)
- osg::RefMatrix * refMatrix = new osg::RefMatrix
- ( _camera->getInverseViewMatrix() * *cv.getModelViewMatrix() );
-
- cv.getRenderStage()->getPositionalStateContainer()->
- addPositionedTextureAttribute( _shadowTextureUnit, refMatrix, _texgen.get() );
-
- }
- void initTexture()
- {
- _texture = new osg::Texture2D;
- _texture->setTextureSize(_textureSize.x(), _textureSize.y());
- _texture->setInternalFormat(GL_DEPTH_COMPONENT);
- _texture->setShadowComparison(true);
- _texture->setShadowTextureMode(osg::Texture2D::LUMINANCE);
- _texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
- _texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
-
- _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.0f,1.0f,1.0f,1.0f)); //边缘部分深度全为1
- }
-
- void initRTTCamera()
- {
- _camera = new osg::Camera;
- _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT);//???
- _camera->setCullCallback(new CameraCullCallbackA(this));
-
- _camera->setClearMask(GL_DEPTH_BUFFER_BIT);
- _camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
- _camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
- _camera->setViewport(0,0,_textureSize.x(),_textureSize.y());
- _camera->setViewMatrixAsLookAt(eyePos,targetPos,osg::Vec3(0,-1,0));
- double aspectRatio=1.0;
- double dNear=0.1;
- double dFar=10;
- _camera->setProjectionMatrixAsPerspective(45,aspectRatio,dNear,dFar);
- _camera->setRenderOrder(osg::Camera::PRE_RENDER);
- _camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
- _camera->attach(osg::Camera::DEPTH_BUFFER, _texture.get());
-
-
- osg::StateSet* stateset = _camera->getOrCreateStateSet();
-
- osg::ref_ptr<osg::CullFace> cull_face = new osg::CullFace;
- cull_face->setMode(osg::CullFace::FRONT);
- stateset->setAttribute(cull_face.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
- stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
-
- float factor = -1.0;
- float units = -1.0;
-
- osg::ref_ptr<osg::PolygonOffset> polygon_offset = new osg::PolygonOffset;
- polygon_offset->setFactor(factor);
- polygon_offset->setUnits(units);
- stateset->setAttribute(polygon_offset.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
- stateset->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
- }
-
- void createStateSet()
- {
-
- _stateset = new osg::StateSet;
- _stateset->setTextureAttributeAndModes(_shadowTextureUnit,_texture.get(),osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
- _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
- _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
- _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
- _stateset->setTextureMode(_shadowTextureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
-
- _texgen = new osg::TexGen;
-
- // add Program, when empty of Shaders then we are using fixed functionality
- _program = new osg::Program;
- _stateset->setAttribute(_program.get());
-
- //shader
- //osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_noBaseTexture);
- osg::Shader* fragment_shader = osg::Shader::readShaderFile(osg::Shader::FRAGMENT,fragmentShaderSource_noBaseTexture);
- _program->addShader(fragment_shader);
-
- //_ambientBias(0.5f,0.5f),
- osg::Uniform* shadowTextureSampler = new osg::Uniform("osgShadow_shadowTexture",(int)_shadowTextureUnit);
- osg::Uniform* baseTextureSampler = new osg::Uniform("osgShadow_baseTexture",(int)_baseTextureUnit);
-
- osg::Vec2 ambientBias(0.5f,0.5f);
- osg::ref_ptr<osg::Uniform> ambientBiasUniform = new osg::Uniform("osgShadow_ambientBias",ambientBias);
-
- _stateset->addUniform(shadowTextureSampler);
- _stateset->addUniform(ambientBiasUniform);
- _stateset->addUniform(baseTextureSampler);
-
- //fake image
- osg::Image* image = new osg::Image;
- // allocate the image data, noPixels x 1 x 1 with 4 rgba floats - equivilant 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::Vec4 color(1,1,1,1);
- *dataPtr = color;
- // make fake texture
- osg::Texture2D* fakeTex = new osg::Texture2D;
- fakeTex->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_EDGE);
- fakeTex->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_EDGE);
- fakeTex->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
- fakeTex->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
- fakeTex->setImage(image);
- // add fake texture
- _stateset->setTextureAttribute(_baseTextureUnit,fakeTex,osg::StateAttribute::ON);
- _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_2D,osg::StateAttribute::ON);
- _stateset->setTextureMode(_baseTextureUnit,GL_TEXTURE_3D,osg::StateAttribute::OFF);
- }
-
- void update(osg::NodeVisitor &nv)
- {
- _scene->osg::Group::traverse(nv);
- }
- void init()
- {
- initTexture();
- initRTTCamera();
- createStateSet();
-
- _dirty = false;
- }
-
- void setScene(osg::Group * scene){_scene = scene;}
-
- osg::ref_ptr<osg::Group> getScene(){return _scene;}
- private:
- bool _dirty;
- osg::ref_ptr<osg::Texture2D> _texture;
- osg::ref_ptr<osg::Camera> _camera;
- osg::Vec2 _textureSize;
- osg::ref_ptr<osg::StateSet> _stateset;
- unsigned int _baseTextureUnit;
- unsigned int _shadowTextureUnit;
- osg::ref_ptr<osg::TexGen> _texgen;
- osg::ref_ptr<osg::Program> _program;
- osg::ref_ptr<osg::Group> _scene;
-
- };
- void CameraCullCallbackA::operator()(osg::Node*, osg::NodeVisitor* nv)
- {
- __shadow->getScene()->osg::Group::traverse(*nv);
- }
- class myNode :public osg::Group
- {
- public :
- myNode(shadow_X * s = nullptr){setNumChildrenRequiringUpdateTraversal(1); _shadow = s;}
- void traverse(osg::NodeVisitor& nv)
- {
- if(_shadow)
- _shadow->traverse(nv);
- else
- osg::Group::traverse(nv);
- }
- /** Resize any per context GLObject buffers to specified size. */
- void resizeGLObjectBuffers(unsigned int maxSize)
- {
- if (_shadow) _shadow->resizeGLObjectBuffers(maxSize);
- Group::resizeGLObjectBuffers(maxSize);
- }
- /** If State is non-zero, this function releases any associated OpenGL objects for
- * the specified graphics context. Otherwise, releases OpenGL objects
- * for all graphics contexts. */
- void releaseGLObjects(osg::State* state) const
- {
- if (_shadow) _shadow->releaseGLObjects(state);
- Group::releaseGLObjects(state);
- }
- private:
- shadow_X* _shadow;
- };
- osg::Geode* createWoodA(osg::ref_ptr<osg::Group> parent)
- {
- osg::ref_ptr<osg::Geode> geode = new osg::Geode();
- osg::Geometry* pointsGeom = new osg::Geometry();
-
- osg::Vec3Array* vertices = new osg::Vec3Array;
- vertices->push_back(osg::Vec3(10, 10, 0));
- vertices->push_back(osg::Vec3(-10,10, 0));
- vertices->push_back(osg::Vec3(-10, -10,0));
-
- vertices->push_back(osg::Vec3(-10, -10,0));
- vertices->push_back(osg::Vec3(10, -10,0));
- vertices->push_back(osg::Vec3(10, 10,0));
-
- pointsGeom->setVertexArray(vertices);
-
- osg::Vec4Array* colors = new osg::Vec4Array;
- colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
- pointsGeom->setColorArray(colors, osg::Array::BIND_OVERALL);
-
-
- // set the normal in the same way color.
- /*osg::Vec3Array* normals = new osg::Vec3Array;
- normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
- pointsGeom->setNormalArray(normals, osg::Array::BIND_OVERALL);*/
-
- pointsGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,0,vertices->size()));
- // add the points geometry to the geode.
- geode->addDrawable(pointsGeom);
-
- parent->addChild(geode);
-
- return geode.release();
- }
- osg::Geode * createLineA(osg::ref_ptr<osg::Group> parent)
- {
- osg::ref_ptr<osg::Geode> geode = new osg::Geode();
- osg::Geometry* pointsGeom = new osg::Geometry();
-
- osg::Vec3Array* vertices = new osg::Vec3Array;
-
- vertices->push_back(eyePos);
- vertices->push_back(targetPos);
-
- osg::Vec4Array* colors = new osg::Vec4Array;
- colors->push_back(osg::Vec4(0.0f,1.0f,0.0f,1.0f));
- pointsGeom->setColorArray(colors, osg::Array::BIND_OVERALL);
- pointsGeom->setVertexArray(vertices);
-
- pointsGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,vertices->size()));
- // add the points geometry to the geode.
- geode->addDrawable(pointsGeom);
-
- parent->addChild(geode);
-
- return geode.release();
- }
-
- osg::Group* createModeA(osg::ref_ptr<osg::Group> parent)
- {
-
- osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile("glider.osg");
- cow->setNodeMask(CastsShadowTraversalMask);
-
-
- osg::ref_ptr<osg::MatrixTransform > cowScale = new osg::MatrixTransform;
- osg::Matrix scale = osg::Matrix::scale(1,1,1);
- osg::Matrix tansla = osg::Matrix::translate(0.0,0.0,2.0);
- cowScale->setMatrix(tansla * scale);
- cowScale->addChild(cow);
-
- parent->addChild(cowScale);
-
- osg::ComputeBoundsVisitor cbbv;
- cowScale->accept(cbbv);
-
- osg::BoundingBox bb=cbbv.getBoundingBox();
-
- return cowScale.release();
- }
- osg::ref_ptr<osg::Node>createLightA()
- {
-
- osg::ref_ptr<osg::Light>lt=new osg::Light;
- lt->setLightNum(0);
-
- //设置环境光的颜色
- lt->setAmbient(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
- lt->setPosition(osg::Vec4(eyePos,0));
- osg::ref_ptr<osg::LightSource>ls=new osg::LightSource();
-
- ls->setLight(lt.get());
-
- return ls.get();
- }
- int main()
- {
-
- osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
- viewer->addEventHandler(new osgViewer::WindowSizeHandler);
- //创建一个组节点
-
-
- shadow_X * sh = new shadow_X();
- osg::ref_ptr<myNode> node = new myNode(sh);
- sh->setScene(node);
-
- osg::ref_ptr<osg::Geode> wood = createWoodA(node);
- osg::ref_ptr<osg::Group> cow = createModeA(node);
- createLineA(node);
-
-
- viewer->setSceneData(node);
- viewer->realize();
- viewer->run();
-
- return 0 ;
- }
-
复制代码 |
|