查看: 2450|回复: 20

悬赏解决

[复制链接]

该用户从未签到

发表于 2014-4-9 11:16:17 | 显示全部楼层 |阅读模式
MFC+MFC_OSG开发出activex,场景漫游过程中退出系统,系统会提示MFC_OSG.cpp中void cOSG::Render(void* ptr)函数代码viewer->frame()有异常。
另外,场景正在旋转中系统退出,也有同样问题。
如果在SDI下 没有这样的问题

我发过帖子,没有人回答,。
谁解决,给适当小费

该用户从未签到

发表于 2014-4-9 11:45:44 | 显示全部楼层
把代码放出来!不然谁能解决啊

该用户从未签到

 楼主| 发表于 2014-4-9 13:50:06 | 显示全部楼层
代码很多,MFC_OSG是例子里面的, 使用的漫游器是基于osgGA::TrackballManipulator
在osg::Matrixd Manipulator::getInverseMatrix() const
{
         
        if(_beginAnimation&&_animationPath.valid())
        {
                return _animationMatrix;
        }
}
实现漫游飞行功能,控件里面就是直接调用MFC_OSG的功能实现。

该用户从未签到

发表于 2014-4-9 14:01:55 | 显示全部楼层
很显然,你上面的函数,if()条件下才返回!
如果不满足呢?是不是逻辑漏洞?你的矩阵就不返回了?

该用户从未签到

 楼主| 发表于 2014-4-9 14:57:23 | 显示全部楼层
osg::Matrixd Manipulator::getInverseMatrix() const
{
         
        if(_beginAnimation&&_animationPath.valid())
        {
                return _animationMatrix;
        }
        else
        {
                osg::Matrix _viewMatrix=osgGA::TrackballManipulator::getInverseMatrix();
                                       
                return _viewMatrix;
        }
         
}

该用户从未签到

发表于 2014-4-9 15:55:57 | 显示全部楼层
放出
OSG渲染线程
activex构造函数、析构函数、初始化函数
来看看

该用户从未签到

发表于 2014-4-9 16:44:04 | 显示全部楼层
abc-osg 发表于 2014-4-9 14:57
osg::Matrixd Manipulator::getInverseMatrix() const
{
         

还是一样,如果条件不满足,就无限期的迭代,进入死循环!

该用户从未签到

发表于 2014-4-9 18:04:56 | 显示全部楼层
本帖最后由 VR_user_happy 于 2014-4-9 18:09 编辑

首先如果你这个控制器是自己写的类!那么,你的矩阵就应该设成成员变量,初始化的时候,传入一个已有控制器的矩阵作为初始值;
1如果满足if条件,就将成员变量值更新;
2.否则,返回成员变量!
你上面的
   osg::Matrix _viewMatrix=osgGA::TrackballManipulator::getInverseMatrix();
   调用的是个你自己改写的控制类(或者是抽象类)的函数
如过是改写类的函数就是死循环;如果没改写,应该是抽象的类函数,是不能通过编译的吧!

该用户从未签到

 楼主| 发表于 2014-4-10 10:05:36 | 显示全部楼层
osg::Matrixd Manipulator::getInverseMatrix() const
{
         
        if(_beginAnimation&&_animationPath.valid())
        {
                return _animationMatrix; //handle函数里面漫游时时时更新
        }
        else
        {
                osg::Matrix _viewMatrix=osgGA::TrackballManipulator::getInverseMatrix();
                 //修改过程略去                    
                return _viewMatrix;
        }
         
}

该用户从未签到

发表于 2014-4-10 15:03:17 | 显示全部楼层
其它的你啥都没提供,没法猜!
只能估计:
viewer->frame()有异常,一种可能性是:
   出现死循环!

该用户从未签到

 楼主| 发表于 2014-4-11 08:54:11 | 显示全部楼层
就是场景还在产生 return _animationMatrix,要求系统去渲染,这个时候退出系统,出现异常。

该用户从未签到

发表于 2014-4-11 09:56:49 | 显示全部楼层
与你说的无关

该用户从未签到

发表于 2014-4-11 10:36:24 | 显示全部楼层
本帖最后由 VR_user_happy 于 2014-4-11 10:41 编辑

我想说的是:
估计还是你这个函数ELSE返回的矩阵问题!
如果矩阵还是要调用本身控制器的矩阵,那就是死循环
不防做以下简单:

函数体内给个有初值的矩阵如:
osgGA::TrackballManipulator的默认返回矩阵
函数如下:
getInverseMatrix()
{
   osg::Matrixd Mt;
Mt=osg::Matrixd::translate(-_center)*osg::Matrixd::rotate(_rotation.inverse())*osg::Matrixd::translate(0.0,0.0,-_distance);


  //
  if(_beginAnimation&&_animationPath.valid())
        {
                return _animationMatrix; //handle函数里面漫游时时时更新
        }

   //
   retunr MT;
}

1.先看是否有问题,没问题就是你的ELSE分支出错;

2.有问题再看:
   再把if()条件块注销,恢复TrackballManipulator的默认返回矩阵,如果还有问题,就说明问题不出在此函数体内!是其他原因!

该用户从未签到

发表于 2014-4-11 13:33:51 | 显示全部楼层
VR_user_happy 发表于 2014-4-11 10:36
我想说的是:
估计还是你这个函数ELSE返回的矩阵问题!
如果矩阵还是要调用本身控制器的矩阵,那就是死循 ...

我觉得问题不会是这里!
人家说的很明白了,编译运行是没问题的,只是在关闭退出时frame()出了问题。

问题应该是OSG相关指针的释放先于渲染线程了
所以要看看其渲染线程里干了啥,退出机制是怎样的。

该用户从未签到

 楼主| 发表于 2014-4-11 13:46:02 | 显示全部楼层
本帖最后由 abc-osg 于 2014-4-11 13:48 编辑

MFC_OSG是例子中的 构造函数和析构函数都没有修改,函数有补充修改。
我仔细测试了下 有时出现问题,有时没有问题,我再换个机器试下,大家也可以写个简单的控件 来验证下 。
我的环境是vc2008+osg3.0

该用户从未签到

发表于 2014-4-11 14:09:54 | 显示全部楼层
你连定位问题都不会!
别复杂化,重建一个MFC的osg例子,用最简单的加载个牛显示!然后调用MFC控件,看退出会不会异常,不会,就说明是你的整体新添加进来功能的结构有问题!
然后逐项添加功能,看到底在哪一个类或是函数调用后出现此中现象!
你不给出你的整体代码,别人无法猜测,只能靠你自己去一步步的找问题!

该用户从未签到

发表于 2014-4-11 14:16:01 | 显示全部楼层
经常会遇到崩溃在frame()里的问题。
多半是场景节点的动态修改造成。
帧前或帧后处理比较安全。

该用户从未签到

 楼主| 发表于 2014-4-11 17:10:14 | 显示全部楼层
漫游时候 数据没有任何变化,也没有修改场景,找不到原因,在SDI下没有任何问题,就是退出的时候,场景还在渲染,引起的错误异常。

该用户从未签到

 楼主| 发表于 2014-4-14 10:50:25 | 显示全部楼层
本帖最后由 abc-osg 于 2014-4-14 11:16 编辑

cOSG::cOSG(HWND hWnd) :
   m_hWnd(hWnd)
{...}
cOSG::~cOSG()
{
    mViewer->stopThreading();
    mViewer->setDone(true);       
       
    //Sleep(1);  

    delete mViewer;
}
void cOSG::Render(void* ptr)
{
    cOSG* osg = (cOSG*)ptr;
    osgViewer::Viewer* viewer = osg->getViewer();
     
    while(!viewer->done())
    {
        osg->PreFrameUpdate();
        viewer->frame();
                //viewer->
        osg->PostFrameUpdate();
        //Sleep(10);         // Use this command if you need to allow other processes to have cpu time
    }
        _endthread();
}
oid cOSG::InitOSG()//std::string modelname)
{
   
    InitCameraConfig();
}
void cOSG::InitCameraConfig(void)
{
   没有做任何修改 拷贝例子的代码
}
控件里面:
int CMyCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
        if (COleControl::OnCreate(lpCreateStruct) == -1)
                return -1;

        // TODO:  在此添加您专用的创建代码
    mOSG = new cOSG(m_hWnd);
        mOSG->InitOSG();          
        mThreadHandle = (HANDLE)_beginthread(&cOSG::Render, 0, mOSG);
        return 0;
}
void CMyCtrl::OnDestroy()
{
         
         if(mOSG != NULL) delete mOSG;
        WaitForSingleObject(mThreadHandle, 10);
       
        COleControl::OnDestroy();
       

        // TODO: 在此处添加消息处理程序代码
}
cenfer  你qq多少?我们私聊。

该用户从未签到

发表于 2014-4-14 21:06:40 | 显示全部楼层
abc-osg 发表于 2014-4-14 10:50
cOSG::cOSG(HWND hWnd) :
   m_hWnd(hWnd)
{...}

其实array老师发过ActiveX的例子。
咱也是借鉴人家的,
按照人家的框架,我的建议如下:
不行再私聊吧

cOSG::~cOSG()
{
        //delete mViewer; //Viewer怎么能delete呢。
        //这里面啥也别干了
}


void CMyCtrl::OnDestroy()
{
        if(mOSG)
        {
        //mOSG::getViewer()//写个接口开放Viewer成员
        mOSG->getViewer()->setDone( true );//先退出自定义的渲染线程
        Sleep(1000);//延迟足够的时间,以保证自定义线程已退出
        mOSG->getViewer()->stopThreading();//停止Viewer
        delete mOSG;//释放自定义OSG管理类,依附于它的智能指针会跟着一起释放
     }  
         COleControl::OnDestroy();
         // TODO: 在此处添加消息处理程序代码
}

该用户从未签到

 楼主| 发表于 2014-4-15 08:58:48 | 显示全部楼层
谢谢cenfer大师,问题解决了 我在漫游过程中随意退出,测试好几次,暂时还没有问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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