查看: 1181|回复: 1

请问关于纹理共享的问题,内有代码

[复制链接]

该用户从未签到

发表于 2014-6-7 11:34:15 | 显示全部楼层 |阅读模式
      大家好,我想做一个纹理共享的例子,我参照了flysky的纹理访问器的例子,在此向他表示感谢!相应代码如下:

  1. #include <osgViewer/Viewer>
  2. #include <osgDB/ReadFile>
  3. #include <osg/PagedLOD>
  4. #include <osg/Node>
  5. #include <osg/Group>
  6. #include <osgViewer\ViewerEventHandlers>
  7. #include <iostream>
  8. #include <stdio.h>
  9. #include <osg/Texture2D>


  10. //节点纹理访问器
  11. class TextureVisitor : public osg::NodeVisitor
  12. {
  13. public:

  14.         //构造函数,遍历所有子节点
  15.         TextureVisitor( ):
  16.           osg::NodeVisitor( osg::NodeVisitor::TRAVERSE_ALL_CHILDREN )
  17.           {
  18.                   //
  19.           }


  20.           //重载apply方法
  21.           virtual void apply( osg::PagedLOD& pagedLOD )
  22.           {
  23.                   if( pagedLOD.getStateSet() )
  24.                   {
  25.                           apply( pagedLOD.getStateSet() );
  26.                   }

  27.                   //实现继续遍历节点
  28.                   traverse(pagedLOD);
  29.           }

  30.           //重载apply方法
  31.           virtual void apply( osg::Node& node )
  32.           {
  33.                   if( node.getStateSet() )
  34.                   {
  35.                           apply( node.getStateSet() );
  36.                   }

  37.                   //实现继续遍历节点
  38.                   traverse(node);
  39.           }

  40.           //重载apply方法
  41.           virtual void apply( osg::Geode& geode )
  42.           {
  43.                   if( geode.getStateSet() )
  44.                   {
  45.                           apply( geode.getStateSet() );
  46.                   }

  47.                   unsigned int cnt = geode.getNumDrawables();

  48.                   for( unsigned int i = 0; i < cnt; i++ )
  49.                   {
  50.                           apply(geode.getDrawable(i)->getStateSet());
  51.                   }

  52.                   traverse(geode);
  53.           }

  54.           //得到贴图列表
  55.           void apply( osg::StateSet* state )
  56.           {
  57.                   std::cout<<"in"<<std::endl;

  58.                  
  59.                 osg::Texture2D* tex2D = NULL;
  60.                 tex2D = dynamic_cast<osg::Texture2D*>(state->getTextureAttribute(0, osg::StateAttribute::TEXTURE));
  61.                 if( tex2D->getImage() )
  62.                 {
  63.                                  
  64.                                 //对比映射表里的tex2D是否有一致的,有的话,用映射表里的tex2D取代
  65.                                 std::map<std::string,osg::Texture2D*>::iterator iter=_texList.find(tex2D->getImage()->getFileName());
  66.                                 if (iter !=_texList.end())//如果有一致的
  67.                                 {
  68.                                         state->removeAttribute(osg::StateAttribute::TEXTURE,0U);
  69.                                         state->setTextureAttribute(0,iter->second,0U);//共享纹理

  70.                                         std::cout<<"share"<<std::endl;  
  71.                                 }

  72.                                 else //否则,写入映射表
  73.                                 {
  74.                                                
  75.                                         _texList.insert(std::make_pair(tex2D->getImage()->getFileName(), tex2D)); //写入映射表
  76.                                 }
  77.                                        

  78.                 }
  79.           }

  80.           //得到贴图
  81.           std::map<std::string, osg::Image*>& getImages( void )
  82.           {
  83.                   return _imageList;
  84.           }

  85. protected:

  86.         //贴图映射表,用来保存贴图名和贴图
  87.         std::map<std::string, osg::Image*>        _imageList;
  88.         std::map<std::string,osg::Texture2D*> _texList;//状态映射表
  89. };




  90. int main()
  91. {
  92.        
  93.         osg::ref_ptr<osgViewer::Viewer> viewer=new osgViewer::Viewer;
  94.         osg::ref_ptr<osg::Group> root=new osg::Group;
  95.         osg::ref_ptr<osg::Group> rootlod=new osg::Group;

  96.           TextureVisitor textureTV;
  97.           osg::ref_ptr<osg::Node> node= osgDB::readNodeFile("cow.osg");
  98.           osg::ref_ptr<osg::Node> node2= osgDB::readNodeFile("D:\\Models\\8-8_0.ive");
  99.           osg::ref_ptr<osg::Node> node3= osgDB::readNodeFile("D:\\Models\\8-9_0.ive");
  100.           osg::ref_ptr<osg::Node> node4= osgDB::readNodeFile("D:\\Models\\8-10_0.ive");
  101.        
  102.          root->addChild(node);
  103.          root->addChild(node2);
  104.          root->addChild(node3);
  105.          root->addChild(node4);
  106.        
  107.         root->accept( textureTV );

  108.         viewer->setSceneData(root);
  109.         viewer->addEventHandler(new osgViewer::StatsHandler);
  110.         viewer->run();
  111.        

  112.         return 0;

  113. }
复制代码



其中,node2、node3、node4分别是有相同纹理的不同模型,程序可以运行。每当导入一个纹理,控制台将会打印“in”,如果有纹理可以共享,控制台将会打印出“share”,并提取映射表里的相应纹理进行共享。
我有两个问题请教:
1.程序可以运行,控制台的截图如下,但请问,这表示纹理共享成功了吗?这段代码能正确的共享纹理吗?

11PNG.PNG

2.我将node2、node3、node4换成了PageLOD的类型,结果发现控制台什么字符也没有输出,也就是说PageLOD肯定没有正确的共享纹理,请问怎么设置才能让PageLOD类型也能正确的共享纹理呢?



谢谢大家!

该用户从未签到

发表于 2014-6-25 17:05:48 | 显示全部楼层
PLOD的模型是动态加载的,此时您可以把自己的texture visitor放在ReadCallback里使用,即接管osg读取文件的回调接口并添加自己的行为
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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