查看: 2194|回复: 10

MFC下添加节点出错

[复制链接]

该用户从未签到

发表于 2010-5-24 18:59:43 | 显示全部楼层 |阅读模式
本人基于MFC框架写了一个osg程序,其中有一个功能是要在点击工具栏按钮后,在场景中增加一个节点,比如点击绘球,就可以在场景的指定位置处绘制一个球体。

我的大致步骤是这样的:
点击工具栏按钮时,创建一个叶节点,并将此叶节点添加到场景的根节点:
    osg::ref_ptr<osg::Geode> geode = new osg::Geode();
    Root->addChild(geode.get());

然后使用addDrawable添加一个预定义的球体。程序调试中发现,到Root->addChild(geode.get())执行完,还未添加几何体时,就会出错:file:///F:/编程备忘/论坛发帖/错误.jpg
但是,这种错误并不是每次调试都会发生,差不多有60%的几率,而直接运行可执行文件,这种错误出现的频率就更低了,请教大家,可能是什么问题呢?

该用户从未签到

 楼主| 发表于 2010-5-24 19:06:53 | 显示全部楼层
补充,因为帖子里图片不能正常显示,我把调试断言的错误提示写在下面:
Debug Assertion Failed!

Program: e:\3DGIS\debug\3DGIS.exe
File: D:\VC80\VC\include\vector
Line: 117

Expression ("this->_MyCont != NULL", 0)

For information on how your program can cause an asserstion  failed,......

该用户从未签到

发表于 2010-5-25 08:28:43 | 显示全部楼层
您可以设置Root的setDataVariance(DYNAMIC)看一看。还有关注一下您的OSG版本,新版本的OSG在稳定性上大幅度提高,动态的添加删除节点几乎不会有什么问题

该用户从未签到

 楼主| 发表于 2010-5-25 15:13:02 | 显示全部楼层
我按照您的说法添加了        Root->setDataVariance(osg::Object:YNAMIC);错误还是会出现,另外我OSG用的是2.8.2的版本,在这方面不知道稳定性如何。

该用户从未签到

发表于 2010-5-25 15:45:59 | 显示全部楼层
希望能够在回调或者事件处理器中添加   不要直接添加  这样能够保证线程的安全性

该用户从未签到

发表于 2010-5-25 16:52:13 | 显示全部楼层
希望能够在回调或者事件处理器中添加   不要直接添加  这样能够保证线程的安全性
zhufu0208 发表于 2010-5-25 15:45


是的,zhufu所说的才是重点;您必须把场景操作相关的工作放在回调中进行

该用户从未签到

 楼主| 发表于 2010-5-25 19:17:58 | 显示全部楼层
好的 谢谢 我再尝试下

该用户从未签到

 楼主| 发表于 2010-5-25 21:50:59 | 显示全部楼层
按照您和zhufu0208 的建议,我将场景节点的增加写在了回调函数中,并且也设置了DYNAMIC标识,调试后发现,出现stl的vector断言错误的频率要小很多,但是偶尔也还是会出现。以下是回调函数及使用回调函数处的代码,不知道有误没。初学OSG,对回调函数的理解还不够,这些代码也是参考论坛上一个帖子修改的,希望给予指点。
回调函数:

  1. class CMyTransformCallback:public osg::NodeCallback
  2. {
  3. public:
  4. CMyTransformCallback(){};

  5. ~CMyTransformCallback(void);
  6. virtual void operator()(osg::Node *node,osg::NodeVisitor *nv)
  7. {
  8.   osg::Group *root = new osg::Group;
  9.   root->setDataVariance(osg::Object::DYNAMIC);
  10.   root->addChild(osgDB::readNodeFile("glider.osg"));
  11.   traverse(node,nv);
  12. }

  13. };
复制代码


外部调用:
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
osg::ref_ptr<osg::MatrixTransform> transform =new osg::MatrixTransform();
  transform->setUpdateCallback(new CMyTransformCallback());
  transform->addChild(geode.get());
  MFCOSG->GetSceneRoot()->addChild(transform.get());

该用户从未签到

发表于 2010-5-26 08:24:26 | 显示全部楼层
  1. root->setDataVariance(osg::Object::DYNAMIC);
复制代码
这一行的位置显然不能够放在回调中。而是在新建节点之后立即设置的

该用户从未签到

 楼主| 发表于 2010-5-27 09:55:55 | 显示全部楼层
按照您的建议,我修改了回调函数,在新建根节点后,设置为DYNAMIC,但是问题依然存在,只不过变得不那么频繁,是不是我的回调函数写得不对。此外,对于每个新添加的节点,是否也需要设置为DYNAMIC标识呢?

该用户从未签到

发表于 2010-5-27 13:29:18 | 显示全部楼层
根据现有的信息我已经无法判断什么了。只能说我自己的程序在动态添加和删除的时候十分稳定,只需要给动态变更节点的父节点设置DYNAMIC即可,OSG现有的垃圾每帧收集机制与ref_ptr的结合已经很完美了~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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