查看: 1958|回复: 3

关于DepthPartition与天空球结合的几个问题

[复制链接]

该用户从未签到

发表于 2013-8-7 11:02:37 | 显示全部楼层 |阅读模式
本帖最后由 Mooneast 于 2013-8-7 11:21 编辑

做了这样一个实验工程,使用《OSG编程实践》中的立方图纹理做了一个天空球,如下:
  1. struct TexMatCallback:public osg::NodeCallback
  2. {
  3. public:
  4.         TexMatCallback(osg::TexMat& tm):_texMat(tm)
  5.         {

  6.         }

  7.         virtual void operator()(osg::Node*node,osg::NodeVisitor*nv)
  8.         {
  9.                 osgUtil::CullVisitor* cv=dynamic_cast<osgUtil::CullVisitor*>(nv);
  10.                 if (cv)
  11.                 {
  12.                         const osg::Matrix& mv=*(cv->getModelViewMatrix());
  13.                         const osg::Matrix R=osg::Matrix::rotate(osg::DegreesToRadians(112.0f),0.0f,0.0f,1.0f)*osg::Matrix::rotate(osg::DegreesToRadians(90.0f),1.0f,0.0f,0.0f);

  14.                         osg::Quat q=mv.getRotate();
  15.                         const osg::Matrix C=osg::Matrix::rotate(q.inverse());

  16.                         _texMat.setMatrix(C*R);
  17.                 }

  18.                 traverse(node,nv);
  19.         }

  20.         osg::TexMat& _texMat;
  21. };

  22. class MoveWithEyePoint:public osg::Transform
  23. {
  24. public:
  25.         MoveWithEyePoint()
  26.         {
  27.         }

  28.         ~MoveWithEyePoint()
  29.         {

  30.         }

  31.         virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor*nv)const
  32.         {
  33.                 osgUtil::CullVisitor* cv=dynamic_cast<osgUtil::CullVisitor*>(nv);

  34.                 if (cv)
  35.                 {
  36.                         osg::Vec3 eyePointLocal=cv->getEyeLocal();
  37.                         matrix.preMult(osg::Matrix::translate(eyePointLocal));
  38.                 }

  39.                 return true;
  40.         }

  41.         virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor*nv)const
  42.         {
  43.                 osgUtil::CullVisitor* cv=dynamic_cast<osgUtil::CullVisitor*>(nv);

  44.                 if (cv)
  45.                 {
  46.                         osg::Vec3 eyePointLocal=cv->getEyeLocal();
  47.                         matrix.postMult(osg::Matrix::translate(-eyePointLocal));
  48.                 }

  49.                 return true;
  50.         }
  51. };
  52. //创建天空球函数
  53. osg::ref_ptr<osg::Node> CreateSphere(void)
  54. {
  55.         osg::ref_ptr<osg::Image> srcImage=osgDB::readImageFile(m_strBackGroundFile);

  56.         unsigned width=srcImage->s()/4;
  57.         unsigned height=srcImage->t()/3;

  58.         //下面的代码是用来将一个整张的图片中的几个面的贴图截出来的,与主题没有太大关系
  59.         osg::ref_ptr<osg::Image> topImage=getSubImage(srcImage,width,height*2,0,width,height,1);
  60.         osg::ref_ptr<osg::Image> bottomImage=getSubImage(srcImage,width,0,0,width,height,1);
  61.         osg::ref_ptr<osg::Image> rightImage=getSubImage(srcImage,width*2,height,0,width,height,1);
  62.         osg::ref_ptr<osg::Image> leftImage=getSubImage(srcImage,0,height,0,width,height,1);
  63.         osg::ref_ptr<osg::Image> frontImage=getSubImage(srcImage,width,height,0,width,height,1);
  64.         osg::ref_ptr<osg::Image> backImage=getSubImage(srcImage,width*3,height,0,width,height,1);

  65.         osg::ref_ptr<osg::TextureCubeMap> tcm=new osg::TextureCubeMap;

  66.         {
  67.                 tcm->setImage(osg::TextureCubeMap::POSITIVE_X,rightImage);
  68.                 tcm->setImage(osg::TextureCubeMap::NEGATIVE_X,leftImage);
  69.                 tcm->setImage(osg::TextureCubeMap::POSITIVE_Y,bottomImage);
  70.                 tcm->setImage(osg::TextureCubeMap::NEGATIVE_Y,topImage);
  71.                 tcm->setImage(osg::TextureCubeMap::POSITIVE_Z,frontImage);
  72.                 tcm->setImage(osg::TextureCubeMap::NEGATIVE_Z,backImage);

  73.                 tcm->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
  74.                 tcm->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
  75.                 tcm->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE);

  76.                 tcm->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_NEAREST);
  77.                 tcm->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
  78.         }

  79.         osg::ref_ptr<osg::StateSet> stateset=new osg::StateSet;

  80.         osg::ref_ptr<osg::TexEnv> te=new osg::TexEnv;
  81.         te->setMode(osg::TexEnv::REPLACE);
  82.         stateset->setTextureAttributeAndModes(0,te,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);

  83.         osg::ref_ptr<osg::TexGen> tg=new osg::TexGen;
  84.         tg->setMode(osg::TexGen::NORMAL_MAP);
  85.         stateset->setTextureAttributeAndModes(0,tg,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);

  86.         osg::ref_ptr<osg::TexMat> tm=new osg::TexMat;
  87.         stateset->setTextureAttribute(0,tm);

  88.         stateset->setTextureAttributeAndModes(0,tcm,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);

  89.         stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
  90.         stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);

  91.         osg::ref_ptr<osg::Depth> depth=new osg::Depth;
  92.         depth->setFunction(osg::Depth::ALWAYS);
  93.         depth->setRange(1.0,1.0);
  94.         stateset->setAttributeAndModes(depth,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);

  95.         stateset->setRenderBinDetails(-1,"RenderBin");

  96.         osg::ref_ptr<osg::Drawable> drawable=new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0,0.0,0.0),1.0));

  97.         osg::ref_ptr<osg::Geode> geode=new osg::Geode;
  98.         geode->setCullingActive(false);
  99.         geode->setStateSet(stateset);
  100.         geode->addDrawable(drawable);

  101.         osg::ref_ptr<osg::Transform> transform=new MoveWithEyePoint();
  102.         transform->addChild(geode);
  103.         transform->setCullingActive(false);
  104.         transform->setCullCallback(new TexMatCallback(*tm));

  105.         return transform;
  106. }
复制代码
在主函数中,实现如下:
  1. int main()
  2. {
  3.         osg::ref_ptr<osgViewer::Viewer> viewer=new osgViewer::Viewer;

  4.         osg::ref_ptr<osg::Group> root=new osg::Group;
  5.         osg::ref_ptr<osg::Node> scene=osgDB::readNodeFile("lz.osg");
  6.         osg::ref_ptr<osg::Node> node=CreateSphere();

  7.         osg::ref_ptr<osg::GraphicsContext::Traits> traits=new osg::GraphicsContext::Traits;
  8.         traits->x=400;
  9.         traits->y=50;
  10.         traits->width=800;
  11.         traits->height=600;
  12.         traits->windowName="Main";
  13.         traits->windowDecoration=true;
  14.         traits->sharedContext=0;
  15.         traits->doubleBuffer=true;
  16.         traits->stencil=8;

  17.         osg::ref_ptr<osg::GraphicsContext> gc=osg::GraphicsContext::createGraphicsContext(traits);

  18.         if (gc->valid())
  19.         {
  20.                 gc->setClearColor(osg::Vec4(1.0,0.0,0.0,1.0));
  21.                 gc->setClearMask(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  22.         }else{
  23.                 std::cout<<"Graphics has not been created !"<<std::endl;
  24.         }

  25.         osg::Vec3 eye(scene->getBound().center().x(),scene->getBound().center().y()-scene->getBound().radius(),scene->getBound().center().z());
  26.         osg::Vec3 center(scene->getBound().center().x(),scene->getBound().center().y(),scene->getBound().center().z());
  27.         osg::Vec3 up(0.0,0.0,1.0);
  28.         {
  29.                 osg::ref_ptr<osgViewer::DepthPartitionSettings> dps=new osgViewer::DepthPartitionSettings;

  30.                 dps->_mode = osgViewer::DepthPartitionSettings::FIXED_RANGE;
  31.                 dps->_zNear=1.0;
  32.                 dps->_zMid=scene->getBound().radius()*0.7;
  33.                 dps->_zFar=scene->getBound().radius();

  34.                 viewer->setUpDepthPartition(dps);

  35.                 viewer->getCamera()->setGraphicsContext(gc);
  36.                 viewer->getCamera()->setViewport(0,0,traits->width,traits->height);

  37.                 viewer->getSlave(0)._camera->setGraphicsContext(gc);
  38.                 viewer->getSlave(0)._camera->setViewport(0,traits->height/2,traits->width/2,traits->height/2);
  39.                 viewer->getSlave(0)._camera->setAllowEventFocus(false);

  40.                 viewer->getSlave(1)._camera->setGraphicsContext(gc);
  41.                 viewer->getSlave(1)._camera->setViewport(0,0,traits->width/2,traits->height/2);
  42.                 viewer->getSlave(1)._camera->setAllowEventFocus(false);

  43.                 viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getSlave(1)._camera->getOrCreateStateSet()));

  44.                 std::cout<<viewer->getNumSlaves()<<std::endl;
  45.         }

  46.         root->addChild(node);
  47.         root->addChild(scene);

  48.         viewer->setSceneData(root);
  49.         viewer->setCameraManipulator(new osgGA::TrackballManipulator);
  50.         viewer->getCameraManipulator()->setHomePosition(eye,center,up,false);
  51.         viewer->home();
  52.         viewer->run();
  53.         return 0;
  54. }
复制代码
运行的结果很奇怪,只有最后一个加入的相机被渲染出来了,但是实际上的从属相机个数仍为2,此外当视点距离scene很远的时候,会造成天空球的裁剪,情况如下图。
关于从属相机与DepthPartition的冲突现象.jpg

该用户从未签到

 楼主| 发表于 2013-8-7 14:08:24 | 显示全部楼层
本帖最后由 Mooneast 于 2013-8-8 11:39 编辑

顶下,莫沉啊

该用户从未签到

 楼主| 发表于 2013-8-8 11:40:11 | 显示全部楼层
求指导啊

该用户从未签到

发表于 2013-8-12 09:46:04 | 显示全部楼层
我在另一个帖子里已经说过了,DepthPartition会建立多个Slave,这种方式我很不喜欢。如果您一定要用的话,就要考虑到场景会被多个Slave渲染多次的问题,而您的天空球应当只在最后一个Slave中被渲染
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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