查看: 3342|回复: 14

采用Pagedlod帧频率为什么这么低

[复制链接]

该用户从未签到

发表于 2009-5-18 17:22:30 | 显示全部楼层 |阅读模式
为了实现动态加载模型,我建立了该模型的多个LOD,由粗到精,采用Pagedlod,但是今天发现,帧频率一直很低,最粗模型时的帧频率与最精模型时的帧频率几乎相近,而且都在15以下,不知设么缘故,有谁也遇到类似的情况,还是我什么地方出错了,该如何解决呢?

通过调整节点层数,现在帧频率有上升,最高可以到达90多而且是在最精模型的时候,但是若是对模型进行拉近或拉远的操作(远处为粗模型,近处为精模型),内存并没有及时释放,而且在粗模型时绘制的帧频率反而下降了,而且下降的很多,很不解。

不解有二:
一,为什么内存没有及时释放,即当前显示为粗模型时,为什么程序占用的内存量仍为精模型时的数值,而且长期不变?
二,为什么粗模型绘制时间反而增长了,从而造成帧频率的下降,而且下降的非常明显?

请高手指教,谢谢!

[ 本帖最后由 ghczhaolei 于 2009-5-18 18:17 编辑 ]

该用户从未签到

发表于 2009-5-18 19:24:05 | 显示全部楼层
没有看到您的代码的话,的确不太好说,也许是动态调度之外的问题导致了这种情形的发生

该用户从未签到

 楼主| 发表于 2009-5-18 20:43:57 | 显示全部楼层
代码比较多不好贴出来,思想是,读取模型并显示,模型的结构是
                          root(switch节点)
                       /     /    ..... \     \
                   /      /            \      \
            pagedlod  pagedlod .....  pagedlod  pagedlod
             / . ...\            / .. \              /.....\           / .... \
            /         \   ......        ......      ....
         lod  .....    lod ....       ......       ....
         /    ......        .....     .....      .....
PossionAttitudeTransform ....       ...      ......

[ 本帖最后由 ghczhaolei 于 2009-5-18 20:51 编辑 ]

该用户从未签到

 楼主| 发表于 2009-5-18 20:44:57 | 显示全部楼层
我想模型结构复杂应该是造成绘制速度慢的一个主要原因,但是为什么简单模型比精细的慢就比较糊涂了

该用户从未签到

 楼主| 发表于 2009-5-18 21:32:39 | 显示全部楼层
我又试了一遍,发现问题并不是全是我上面描述的样子,当程序运行后,不进行任何操作(默认显示最精的模型),发现帧频率就在不停的减少到十几后稳定。
将部分代码简写如下:
osg::ref_ptr<osg::Switch> RootScenedata = new osg::Switch;

                                                       osg:agedLOD* part = new osg::PagedLOD;
                                                std::string temppartpath = partpath + firstName;
                                                std::string strSign = "\\";
                                                temppartpath += strSign;
                                                for (int h =0; h < 10; h++)
                                                {
                                                        char temp[64];
                                                        sprintf(temp,"%d",10 + h*10);
                                                        std::string LodName = temppartpath + firstName + underline + temp + underline +
                                                                lastName + partFormatOsg;
                                                        osg::Node* Lod = osgDB::readNodeFile(LodName);
                                                        part->addChild(Lod,float(9 - h), float(10 - h));
                                                        part->setFileName(h,LodName);
                                               
                                                }
                                                part->setName(tempPartName);
                                                RootScenedata->addChild((osg::Node*)part);


                     osgViewer::Viewer myviewer;
                osg::ref_ptr<osgGA::TrackballManipulator> trackball;
                osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator;
                trackball = new osgGA::TrackballManipulator();
                keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator();
                keyswitchManipulator->addMatrixManipulator(1,"trackball",trackball.get());
                keyswitchManipulator->selectMatrixManipulator(0);
                myviewer.setCameraManipulator(keyswitchManipulator.get());

                osg::CullFace* groupCullFace = new osg::CullFace;
                groupCullFace->setMode(osg::CullFace::BACK);
               
                osg::Group* ScenceData = new osg::Group;
                ScenceData->getOrCreateStateSet()->setAttributeAndModes                            (groupCullFace,osg::StateAttribute::ON);

       
                myviewer.setSceneData((osg::Node*)RootScenedata.get());
                myviewer.addEventHandler(new osgViewer::StatsHandler);

                myviewer.getCamera()->setCullingMode(osg::CullSettings::VIEW_FRUSTUM_SIDES_CULLING);
               
                while (!myviewer.done())
               
                  {
                myviewer.frame();
                 }

[ 本帖最后由 ghczhaolei 于 2009-5-18 21:42 编辑 ]

该用户从未签到

发表于 2009-5-19 09:21:22 | 显示全部楼层
从您的代码中我暂时看不出端倪来,不过您对PagedLOD的使用有误。PagedLOD本身就是LOD节点,因此没必要给它追加LOD子节点。此外如果您的模型是用addChild静态加载的,那么没必要使用动态调度数据的PagedLOD;要动态加载和卸载节点,可以直接使用setFileName,而非addChild

该用户从未签到

 楼主| 发表于 2009-5-19 09:31:37 | 显示全部楼层
其中的lod只是示意其实就是表示pagedlod的子节点,呵呵。若真是pagedlod的用法有误就好了,谢谢array

该用户从未签到

 楼主| 发表于 2009-5-19 09:34:23 | 显示全部楼层
原帖由 array 于 2009-5-19 09:21 发表
从您的代码中我暂时看不出端倪来,不过您对PagedLOD的使用有误。PagedLOD本身就是LOD节点,因此没必要给它追加LOD子节点。此外如果您的模型是用addChild静态加载的,那么没必要使用动态调度数据的PagedLOD;要动态加 ...

您的意思是,使用addChild,pagedlod会将所有的静态模型都加在进来,然后绘制吗?而setFileName,则可实现动态的读取和加载动态的模型?

该用户从未签到

 楼主| 发表于 2009-5-19 09:55:21 | 显示全部楼层
采用setFileName后,很好的实现了动态加载和卸载,内存明显的实时改变,但是在最粗模型时draw的时间依然很长,还要好好看看

该用户从未签到

发表于 2009-5-19 12:32:35 | 显示全部楼层
addChild会使得PagedLOD变得没有意义~~因为这样追加的子节点是不能动态调度的,而是一直被显示。所以我还是觉得您的用法恐怕有误~~

该用户从未签到

 楼主| 发表于 2009-5-19 13:50:22 | 显示全部楼层
已经按照您说的,并参照《最长的一帧》中关于pagedLod的相关内容调整了,而且在距离变化的时候能够看到模型的变化,而且内存也随之改变,由此看出是在进行动态调度,只是不明 白在一帧中绘制的时间为什么会不断增加,应该是代码还有地方没做好,寻找原因中:)

该用户从未签到

 楼主| 发表于 2009-5-20 10:06:05 | 显示全部楼层

回复 2楼 的帖子

araay,昨天后来忙别的事就没在管程序,尽早发现为什么draw的时间逐渐变长了,原因是Instance顶点数量逐渐增加,如下图所示,此时场景中每一个pagedlod下只有一个子模型,不知是什么原因造成这种情况,我找了一个多小时也没找到原因,您能看出什么蛛丝马迹吗?
图.jpg

该用户从未签到

发表于 2009-5-20 10:14:59 | 显示全部楼层
我猜想还是您的程序的什么地方有问题,因为我使用PagedLOD并未出现过这种问题。但是目前没有足够的“蛛丝马迹”能让我去查看

该用户从未签到

 楼主| 发表于 2009-5-20 10:34:01 | 显示全部楼层
呵呵问题解决了,原因是:因为还有其他数据节点,所以我在将子节点为pagedlod的switch节点传递给场景时,又加了一个根节点即root->group->switch->pagedLod1.....
                    ->pagedLod2.....
                     .
                     .
                     .
          ->group
           .
           .
,嗨为什么加了这样一层就会出现这样严重的问题呢,以后要小心添加节点层了

[ 本帖最后由 ghczhaolei 于 2009-5-20 14:39 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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