查看: 2513|回复: 15

跳动的面画出来了,但是到了200*200个面变的很慢,有兴趣帮我看看代码哪里可以优化吗

[复制链接]

该用户从未签到

发表于 2011-2-19 10:45:01 | 显示全部楼层 |阅读模式
  1. class DynamicLineCallback : public osg::Drawable::UpdateCallback
  2. {
  3. public:
  4.         DynamicLineCallback(){}

  5.         virtual void update( osg::NodeVisitor* nv, osg::Drawable* drawable )
  6.         {
  7.                 osg::Geometry* geom = dynamic_cast<osg::Geometry*>( drawable );
  8.                 if ( !geom )
  9.                 {
  10.                         return;
  11.                 }

  12.                 osg::Vec4Array* colors = dynamic_cast<osg::Vec4Array*>(geom->getColorArray());
  13.                 if (colors)
  14.                 {
  15.                         osg::Vec4Array::iterator itrd;
  16.                         itrd = colors->begin();
  17.                         osg::Vec4f* ptt = &(*itrd);
  18.                         ptt->_v[0] = rand() % 255 / 255.0;
  19.                         ptt->_v[1] = rand() % 255 / 255.0;
  20.                         ptt->_v[2] = rand() % 255 / 255.0;
  21.                 }

  22.                 osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>( geom->getVertexArray() );
  23.                 if ( vertices )
  24.                 {
  25.                         double dddd = rand() % 100;

  26.                         for ( osg::Vec3Array::iterator itr=vertices->begin(); itr!=vertices->end(); ++itr )
  27.                         {
  28.                                 osg::Vec3f* pt = &(*itr);

  29.                                 itr->set(pt->_v[0], pt->_v[1], dddd);
  30.                         }

  31.                         vertices->dirty();
  32.                 }
  33.         }
  34. };

  35. void createCuboid(const double& x, const double& y, const double& z,
  36.                                   const double& xw, const double& yw,
  37.                                   const osg::Vec4& color,
  38.                                   osg::Group* pCuboidGroups)
  39. {
  40.         //  先计算点
  41.         double points[1][4][3];
  42.         //  上面四点
  43.         points[0][0][0] = x - 0.5 * xw;
  44.         points[0][0][1] = y - 0.5 * yw;
  45.         points[0][0][2] = z;
  46.         points[0][1][0] = x + 0.5 * xw;
  47.         points[0][1][1] = y - 0.5 * yw;
  48.         points[0][1][2] = z;
  49.         points[0][2][0] = x + 0.5 * xw;
  50.         points[0][2][1] = y + 0.5 * yw;
  51.         points[0][2][2] = z;
  52.         points[0][3][0] = x - 0.5 * xw;
  53.         points[0][3][1] = y + 0.5 * yw;
  54.         points[0][3][2] = z;

  55.         //  上面
  56.         osg::ref_ptr<osg::Geode> topGeode = new osg::Geode;
  57.         osg::ref_ptr<osg::Geometry> topGeom = new osg::Geometry;
  58.         osg::ref_ptr<osg::Vec3Array> topVec = new osg::Vec3Array;
  59.         topVec->push_back(osg::Vec3(points[0][0][0], points[0][0][1], points[0][0][2]));
  60.         topVec->push_back(osg::Vec3(points[0][1][0], points[0][1][1], points[0][1][2]));
  61.         topVec->push_back(osg::Vec3(points[0][2][0], points[0][2][1], points[0][2][2]));
  62.         topVec->push_back(osg::Vec3(points[0][3][0], points[0][3][1], points[0][3][2]));
  63.         topGeom->setVertexArray(topVec.get());
  64.         osg::ref_ptr<osg::Vec4Array> topColor = new osg::Vec4Array;
  65.         topColor->push_back(color);
  66.         topGeom->setColorArray(topColor.get());
  67.         osg::ref_ptr<osg::Vec3Array> topNormal = new osg::Vec3Array;
  68.         topNormal->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
  69.         topGeom->setNormalArray(topNormal.get());
  70.         topGeom->setNormalBinding(osg::Geometry::BIND_OVERALL);
  71.         topGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, topVec->size()));
  72.         topGeode->addDrawable(topGeom.get());
  73.         {
  74.                 //topGeom->setInitialBound( osg::BoundingBox(osg::Vec3(-100.0,-100.0,-100.0), osg::Vec3(100.0,100.0,100.0)) );
  75.                 topGeom->setUpdateCallback( new DynamicLineCallback );
  76.                 topGeom->setUseDisplayList( false );
  77.                 topGeom->setUseVertexBufferObjects( true );
  78.         }

  79.         pCuboidGroups->addChild(topGeode.get());
  80. }


  81. osg::Node* createCuboids(void)
  82. {
  83.         osg::Group* cuboidGroups = new osg::Group;
  84.         long ni = 20;//  这里设置大小,设置大了就慢了,比如200,我的机器fps只有1
  85.         long nj = 20;//  这里设置大小,设置大了就慢了,比如200,我的机器fps只有1
  86.         double xw = 100;//  每个矩形面的大小
  87.         double yw = 100;//  每个矩形面的大小
  88.         long i = 0;
  89.         long j = 0;
  90.         double x = 0.0f;
  91.         double y = 0.0f;
  92.         double z = 0.0f;

  93.         for (i=0; i<ni; i++)
  94.         {
  95.                 for (j=0; j<nj; j++)
  96.                 {
  97.                         x = xw * 0.5 + i * xw;//  矩形面的中心位置x
  98.                         y = yw * 0.5 + j * yw;//  矩形面的中心位置y
  99.                         z = 0.0f;

  100.                         createCuboid(x, y, z,
  101.                                 xw, yw,
  102.                                 osg::Vec4(1.0f, 0.5f, 1.0f, 1.0f), cuboidGroups);
  103.                 }
  104.         }
  105.         return cuboidGroups;
  106. }

  107. int main()
  108. {
  109.         //  创建Viewer对象,场景浏览器
  110.         osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;

  111.         //  添加显示fps内容
  112.         viewer->addEventHandler(new osgViewer::StatsHandler);

  113.         //  创建场景组节点
  114.         osg::ref_ptr<osg::Group> root = new osg::Group;

  115.         //  添加shape
  116.         root->addChild(createCuboids());

  117.         //优化场景数据
  118.         osgUtil::Optimizer optimizer;
  119.         optimizer.optimize(root.get());

  120.         //设置场景数据
  121.         viewer->setSceneData(root.get());

  122.         //初始化并创建窗口
  123.         viewer->realize();

  124.         //开始渲染
  125.         viewer->run();

  126.         return 0;
  127. }
复制代码

该用户从未签到

发表于 2011-2-19 15:57:18 | 显示全部楼层
测试了一下,速度还可以,60FPS   CPU 20%

该用户从未签到

 楼主| 发表于 2011-2-19 16:04:11 | 显示全部楼层
回复 2# aaa696 有没有用200*200测试,不过你的机器的确不错,我的机器20*20才20帧多点

该用户从未签到

发表于 2011-2-19 16:05:58 | 显示全部楼层
如果说有什么问题的话,就是创建了太多的面。呵呵!

其实这些面都是一样的,完全可以CLONE,把它作为子节点赋给多个位置节点,或许会快些!

该用户从未签到

 楼主| 发表于 2011-2-19 16:09:14 | 显示全部楼层
回复 4# aaa696 每个面有点区别,颜色不一样,

该用户从未签到

发表于 2011-2-19 16:21:14 | 显示全部楼层
颜色当然要调整了,外形可以复制。
主要是看你想到达什么目的?

该用户从未签到

发表于 2011-2-19 16:29:04 | 显示全部楼层
其实没有必要每次回调都更新,可以尝试减少次数,提高帧率。
当然,也可以在多线程中完成。

该用户从未签到

 楼主| 发表于 2011-2-19 16:34:01 | 显示全部楼层
回复 6# aaa696 我想要这样的效果:每个面根据输入的值动态更新位置(高度),同时也修改颜色,自己学着使用osg时就用随机值填了,

该用户从未签到

 楼主| 发表于 2011-2-19 16:35:52 | 显示全部楼层
回复 7# aaa696 更新的回调函数对速度影响不大,主要还是面多,面的大小倒是固定的,就是高度和颜色会变,

该用户从未签到

发表于 2011-2-19 16:45:16 | 显示全部楼层
其实200*200只有80000个三角,不算多。
还是那句话,该复制的就要复制。 不要无止境的创建几何体Geometry

该用户从未签到

发表于 2011-2-21 08:55:20 | 显示全部楼层
每创建一个Geometry,就会在OpenGL端创建一个DisplayList或者VBO对象(除非您使用slow path)。因此您最好将自己的几何体对象尽量合并起来。我测试过:同样是100万个顶点,8万个geoemtry的渲染速度可能只有10帧,而2千个则可以顺利达到60帧

该用户从未签到

发表于 2011-2-21 09:11:23 | 显示全部楼层
array所说的“把几何体尽量合并起来”,具体是些怎样的操作呢?请简单阐述一下。

该用户从未签到

发表于 2011-2-21 11:12:52 | 显示全部楼层
多半是VBO没起作用,可以查询一下fastpath的值是不是true

该用户从未签到

发表于 2011-2-21 13:21:12 | 显示全部楼层
“把几何体尽量合并起来”,具体是些怎样的操作呢
没有什么具体的操作,这应该是您自己设计的

该用户从未签到

发表于 2011-2-21 13:32:01 | 显示全部楼层
我想我明白了,尽量减少几何体就对了!

该用户从未签到

发表于 2011-2-22 13:52:45 | 显示全部楼层
了解啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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