查看: 2662|回复: 16

HUD动态更新,程序中断问题

[复制链接]

该用户从未签到

发表于 2011-5-27 18:34:46 | 显示全部楼层 |阅读模式
MFC框架程序中,在画面上动态更新当前时刻。采用动态更新回调方法,创建HUD代码如下:
osg::ref_ptr<osg::Node> cOSG::createHUD()
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
//设置字体,必须是汉字字体,这里是华文彩云
std::string heiti("fonts/SIMHEI.TTF");
//设置状态,关闭灯光
osg::ref_ptr<osg::StateSet> stateset=geode->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
osg::Vec3 position(5.0f,10.0f,0.0f);
//设置字体属性
text = new osgText::Text;
text->setDataVariance(osg::Object:YNAMIC);
geode->addDrawable(text);
//设置字体
text->setFont(heiti);
//设置字体颜色
text->setColor(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
//设置字体大小
text->setCharacterSize(20.0f);
text->setAutoRotateToScreen(true);
//设置位置
text->setPosition(position);
CTime tm = CTime::GetCurrentTime();
CString time = tm.Format("%d %B %Y %H:%M:%S");
text->setText(time);

//设置相机
osg::ref_ptr<osg::Camera> camera=new osg::CameraNode;
//设置透视矩阵
camera->setProjectionMatrix(osg::Matrix:rtho2D(0,1024,0,768));
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
//得到默认设置
camera->setViewMatrix(osg::Matrix::identity());
//设置背景为透明,否则的话可以设置ClearColor
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
//设置渲染顺序,必须在最后渲染
camera->setRenderOrder(osg::CameraNode:OST_RENDER);
camera->addChild(geode);  
return camera;
}

回调函数:
class TextCallBack : public osg::NodeCallback
{
public:
TextCallBack(osg::ref_ptr<osgText::Text> text):
   Text(text)
   {
   }
  virtual void operator()(osg::Node* node,osg::NodeVisitor* nv)
{
  CTime t;
  t=CTime::GetCurrentTime();//得到当前时间
  CString time = t.Format("%d %B %Y %H:%M:%S");
  Text->setText(time);
}
private:
osg::ref_ptr<osgText::Text> Text;
};

在MFC中启用定时器,1秒钟调用一次更新回调函数。在程序运行若干秒后就会中断,停在回调函数的Text->setText(time);这句,并弹出对话框,信息如下:
Unhandled exception at 0x014dded4 in CREAT_EARTH.exe: 0xC0000005: Access violation reading location 0xfeeeffe2.
请问问题出在什么地方?

该用户从未签到

发表于 2011-5-27 19:01:07 | 显示全部楼层
“在MFC中启用定时器,1秒钟调用一次更新回调函数。”
貌似您的方法有问题,可能产生冲突

该用户从未签到

发表于 2011-5-27 20:02:48 | 显示全部楼层
为什么要在Timer中调用回调函数呢,保留一个就好了

该用户从未签到

 楼主| 发表于 2011-5-27 20:26:07 | 显示全部楼层
不用Timer定时器的话,如何可以准确的定时?

该用户从未签到

发表于 2011-5-27 21:42:34 | 显示全部楼层
更新必须放到回调里,时间可以自己读取系统时间控制

该用户从未签到

发表于 2011-5-28 01:34:38 | 显示全部楼层
我也是采用搂注相似的方法!
也是出错,好像settext()积累到一定时间就崩溃了!

该用户从未签到

发表于 2011-5-28 01:47:17 | 显示全部楼层
text->setDataVariance(osg::Geometry:YNAMIC);
看了以前的帖子!设置这个参数。我的程序就好了!不包错了!!!哈哈哈!

该用户从未签到

发表于 2011-5-28 22:39:06 | 显示全部楼层
注意线程安全性就不会有问题了。。。

该用户从未签到

 楼主| 发表于 2011-6-2 13:29:20 | 显示全部楼层
回复 7# xairwolfcn


    我不用更新回调,只用定时器,加上你这句,还是会崩溃,但是只用更新回调就没问题

该用户从未签到

发表于 2011-6-2 15:43:30 | 显示全部楼层
osg里有时间的类和方法,不建议在Osg里混用Ctime这样的类,因为这些类可能是继承自CObject,不是比较纯正的c++的类(这句话有待斟酌),如果你想进行mfc与osg的交互,比较建议,采用句柄handle, ::等全局函数,
  CTime t;
  t=CTime::GetCurrentTime();/
可以改为:::GetCurrentTime( handle)之类,不知道是否表达清晰。

该用户从未签到

发表于 2011-6-3 08:14:46 | 显示全部楼层
不是这个问题,事实上mfc和osg多半可能是运行在两个不同的线程中的,在mfc线程中直接操作场景对象的话,没有人知道此时osg是不是正好在渲染它们——而一旦发生这种情况就是访问冲突,会造成崩溃。
最好的办法是使用command buffer的策略,mfc层传递一个指令到osg的回调中,然后在回调里解析并执行它——这个传递的指令同样需要加锁以避免多个线程同时访问

该用户从未签到

发表于 2011-6-3 16:27:10 | 显示全部楼层
回复 11# array

   哦,抱歉学艺不精。如果需要osg来更新mfc的线程数据呢?比如我想更新mfc的控件读取模型的时间,而读取模型的时间是由osg线程来决定的,应该如何去做呢?我是给mfc发送一个消息吗? 一直没有找到很好的mfc和osg一起工作的方式。

该用户从未签到

发表于 2011-6-7 08:27:49 | 显示全部楼层
最好的方法就是命令缓存的方式,mfc发送命令到缓存队列中,然后osg的更新回调来解析命令并执行

该用户从未签到

发表于 2011-6-7 12:30:32 | 显示全部楼层
你的这个实现,完全可以采用,把那个要显示的内容time抽取出来。。那样子就不会出问题了。。之前也碰到过类似的,但是我看你把那个Text设置成了DYNAMIC了。。
可以参照osg的示例程序!

该用户从未签到

发表于 2014-5-6 09:49:23 | 显示全部楼层
各位大神有没有完整的示例程序共享一个啊

该用户从未签到

发表于 2014-5-6 17:15:21 | 显示全部楼层
你好,这个回调函数,后面调用的话应该怎么写

该用户从未签到

发表于 2014-5-8 11:34:19 | 显示全部楼层
肯定是多线程的问题  100%
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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