查看: 2573|回复: 11

请教,我写的代码有哪些地方可以优化

[复制链接]

该用户从未签到

发表于 2009-2-22 19:51:32 | 显示全部楼层 |阅读模式
我绘制长方体(我绘制6个面拼成的),数量多了之后就变的很慢,内存变得很大,我想问问,在我写的代码中,有哪些方面的优化可以做。
代码见附件
再补一问,fps的显示需要自己写代码实现吗
附件的两个main是一样的,编辑的时候多传了一次

[ 本帖最后由 wozhaolala 于 2009-2-23 20:05 编辑 ]

main.rar

2.5 KB, 下载次数: 1, 下载积分: 威望 1

main.rar

2.5 KB, 下载次数: 2, 下载积分: 威望 1

axis.rar

2.47 KB, 下载次数: 2, 下载积分: 威望 1

该用户从未签到

发表于 2009-2-22 21:26:33 | 显示全部楼层
我没有看您的代码。不过绘制三角形的数量巨大时内存变大几乎是必然的事情,任何引擎或者硬件设备都无法承受无休止的增幅。通常的优化方式可以考虑这样几种:
1、LOD,对您的例子而言,可以考虑osgSim:: Imposter,这样距离视点较远的对象可以以图片的形式显示。
2、OpenGL draw instanced,这是OpenGL的最新特性之一,有可能您的显卡不支持。这是一种在显卡内部优化同一类型物体大量绘制的方法,可以参看osgdrawinstanced例子
3、优化您的osg代码,例如如果所有要绘制的都是长方体,只需要一个Geode节点就够了,然后用大量的MatrixTransform父节点指向它。

fps的显示可以从osg::Stats类中获取,这个类每帧都会更新一些时间数据,具体使用方法可以参看osgViewer::StatsHandler类的写法

该用户从未签到

 楼主| 发表于 2009-2-23 19:39:45 | 显示全部楼层
Fps可以显示了 Cull显示很大 我想问下 这个量说明了什么 论坛的流量还是比较大的 对手机来说 呵呵

该用户从未签到

发表于 2009-2-23 20:02:56 | 显示全部楼层
CULL的耗时很长说明场景中的对象太多,恐怕还是要考虑LOD,Imposter,VisibilityGroup等方法进行细节层次的优化

该用户从未签到

 楼主| 发表于 2009-2-23 20:06:49 | 显示全部楼层
谢谢array,我试试

该用户从未签到

 楼主| 发表于 2009-2-23 23:53:02 | 显示全部楼层
原来的FPS      LOD之后的FPS       MatrixTransform之后的FPS
Event      1.31                 1.34                            0.94
Update   0.33                 0.33                            0.24
Cull         71.72               65.69                          113.78
Draw       19.79               10.6                            22.08
GPU        13.37                2.23                           10.57
LOD之后是好了点,不过,其实,我没有将矩形隐藏的需求,因为,矩形只有400个,都看得清楚,
MatrixTransform节点,不知道是不是我用得不对,我是模仿《OSG编程入门指南》上写的,
至于OpenGL draw instanced我得再看看,我的例子里面还没有。
还有,多发一次的附件可以删掉吗?
main_matrix.cpp是MatrixTransform之后的
main_lod.cpp是LOD之后的
main_o.cpp只是在原来基础上加了个FPS显示

[ 本帖最后由 wozhaolala 于 2009-2-23 23:59 编辑 ]

main_matrix.rar

2.68 KB, 下载次数: 61, 下载积分: 威望 1

main_lod.rar

2.61 KB, 下载次数: 112, 下载积分: 威望 1

main_o.rar

2.55 KB, 下载次数: 102, 下载积分: 威望 1

该用户从未签到

发表于 2009-2-24 00:55:59 | 显示全部楼层
你那样用实际上是每次都重新添加了一个新长方体,,,pnode 应该是一个已经创建好的节点,你只要对matrix移动就可以了~~~~~~~~

该用户从未签到

发表于 2009-2-24 09:04:47 | 显示全部楼层
我还是没有看您的代码~~ 不过正如FlySky所说,如果您每次都重新建立了长方体,以至于场景中存在400个MatrixTransform和400个Geode,那效果当然比较差;只需要一个Geode作为子节点,它有400个MatrixTransform的父节点,这样场景中的负担自然会好很多,估计也没必要用draw instanced

该用户从未签到

 楼主| 发表于 2009-3-4 16:05:04 | 显示全部楼层
这事放下好久了,我先简单描述下我的代码,因为我觉得FlySky说的不对
首先一个生成长方体函数,
osg::Node* createCuboid(参数)
{
    osg::Group* cuboidGroup = new osg::Group;
    ......
    cuboidGroup->addChild(顶面页节点);
    cuboidGroup->addChild(底面页节点);
    cuboidGroup->addChild(左面页节点);
    cuboidGroup->addChild(右面页节点);
    cuboidGroup->addChild(前面页节点);
    cuboidGroup->addChild(后面页节点);
}
接着在main函数里有个循环
...
osg::Node* pNode = NULL;
for (i=0; i<20; i++)
{
    for (j=0; j<20; j++)
    {
        if (i==0 && j==0)
        {
            pNode = createCuboid();
        }
        mt...
        mt->addChild(pNode);
        root->addChild(mt.get());
    }
}
所以我觉得“你那样用实际上是每次都重新添加了一个新长方体”
我感觉不是新的啊,就一个长方体节点,还没加到root里面,root里面只有20×20个MatrixTransform页节点,不过我感觉,每个MatrixTransform页节点里面都有一个长方体节点。
不知道是不是我想错了。

该用户从未签到

 楼主| 发表于 2009-3-4 16:18:29 | 显示全部楼层
有个想法,突然冒出来的,我是不是可以做一个长方体组合,为一个页节点
root->addChild(Cuboids.get());
而不是用一个长方体为页节点,使用很多这样的页节点

该用户从未签到

 楼主| 发表于 2009-3-4 16:36:33 | 显示全部楼层
这个想法不错,cull比LOD之少些,不过Draw和GPU比LOD差些,比其他做法都好些
Event     1.10
Update  0.20
Cull        36.88
Draw      14.32
GPU        7.44
咋没人关注这些入门级的编程呢,除了array和flysky

该用户从未签到

发表于 2009-3-4 19:18:24 | 显示全部楼层
您可以看一看自己的程序总共分配了多少次new Geode,写一个累加的int全局量就可以;事实上我和FlySky的建议都是:分配新的Geode应该只有一次。而这个唯一的长方体节点的指针被反复addChild到所有的MT父节点上,如果您不是这样做的,那么内存占用量和系统负担肯定会增加不少~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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