查看: 2365|回复: 17

关于重复调用OSG指针

[复制链接]

该用户从未签到

发表于 2011-4-19 14:13:17 | 显示全部楼层 |阅读模式
一个是控制台工程,一个是MFC下的.

遇到了同样的问题.

控制台工程:定义了一组指针并将其初始化,但之后会给它重新赋值,但一旦重新调用这组指针原来的状态时,就会跳出OSG,并提示有错误:
Unhandled exception at 0x781473d0 in MainVRSimu.exe: 0xC0000005: Access violation writing location 0x00000000.
MFC中调用OSG代码,第一次完整流畅的显示,之后退出OSG,回到MFC界面,想再一次进入OSG界面,就会自动退出MFC工程,并提示有错误:
Unhandled exception at 0x781473d0 in MainVRSimu.exe: 0xC0000005: Access violation writing location 0x00000000.
这是内存泄露问题吗?

该用户从未签到

发表于 2011-4-20 08:26:50 | 显示全部楼层
很明显两个问题中您都调用了空的指针,这只是您自己程序代码的问题

该用户从未签到

 楼主| 发表于 2011-4-20 12:10:03 | 显示全部楼层
谢谢array,我看一下我的程序。

该用户从未签到

 楼主| 发表于 2011-4-20 12:10:16 | 显示全部楼层
谢谢array,我看一下我的程序。

该用户从未签到

 楼主| 发表于 2011-4-20 21:25:02 | 显示全部楼层
你好,array。
我的那个问题解决了,将那些个指针变成了智能指针。
之后又遇到了一个问题是,MFC中调用OSG代码,第一次完整流畅的显示,之后退出OSG,回到MFC界面,想再一次进入OSG界面。就不会显示OSG界面,停留在了MFC的界面上,也不会提示有错误。
但观察CFU的利用率,发现第二次进入OSG时有一段时间超过了50%。
这是第二次根本就没加截模型呢,还是加截了没显示出来?

该用户从未签到

发表于 2011-4-21 08:45:48 | 显示全部楼层
没有什么代码信息的话,我判断不了什么

该用户从未签到

 楼主| 发表于 2011-4-22 12:25:01 | 显示全部楼层
谢谢array
不好意思,我总是回答比较晚。我发现我的程序中运行到最后各个变量值没回到初始值,所以到第二次不会运行了。
虽然这个解决了,然后我弄了个循环,只能重复运行四或五次,就会直接退出系统,然后会有错误提示:
Unhandled exception at 0x7c812afb in MainVRSimu.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0012e4ec..
之后我点continue,又会出现如下错误:
MainVRSimu.exe has triggered a breakpoint
Windows has triggered a breakpoint in MainVRSimu.exe.
This may be due to a corruption of the heap, and indicates a bug in MainVRSimu.exe or any of the DLLs it has loaded.
The output window may have more diagnostic information
Unhandled exception at 0x781970e8 in MainVRSimu.exe: 0xC000001D: Illegal Instruction.
这个错误会指向如下函数的红色字体的位置:

  1. void TrInterfaceVedio::loadVedios()
  2. {
  3.         osg::Image* image = osgDB::readImageFile(_vediosPath);
  4.         [color=Red]imageStream = dynamic_cast<osg::ImageStream*>(image);[/color]
  5.         if (imageStream) imageStream->play();
  6.         if (image)
  7.         {
  8.                 geode->addDrawable(myCreateTexturedQuadGeometry(pos,image->s(),image->t(),image));
  9.         }
  10.         else
  11.         {
  12.                 std::cout<<"Unable to read file "<<"arguments[i]"<<std::endl;
  13.         }
  14.         _camera->addChild(geode);
  15. }
复制代码

该用户从未签到

 楼主| 发表于 2011-4-22 12:26:25 | 显示全部楼层
追加一句,上面的红色没显示出来,是函数体的第二句话

该用户从未签到

发表于 2011-4-25 08:57:19 | 显示全部楼层
我想我依然判断不了什么,您给出的只是自己程序的很小一部分,这一部分对全局会有什么影响我无法得知

该用户从未签到

 楼主| 发表于 2011-4-25 18:14:12 | 显示全部楼层
我不会上传附件,所以分文件粘贴了一下代码:
FuncDemo.cpp 与FuncDemo.h是实现GIF的显示
如下为FuncDemo.h:
  1. #include <osgDB/ReadFile>
  2. #include <osg/Geode>
  3. #include <osg/Camera>
  4. #include <osg/ImageStream>
  5. #include <osgAnimation/UpdateCallback>
  6. #include<osgViewer/Viewer>
  7. #include<osg/Image>
  8. #include<osg/Texture2D>
  9. #include<osgViewer/ViewerEventHandlers>
  10. #include<windows.h>
  11. using namespace std;

  12. class TrInterfaceVedio:        public osg::Group
  13. {

  14.     public:

  15.            /* 播放一段或多段视频*/
  16.                 TrInterfaceVedio(std::string VediosPath);
  17.                 //读出视频后,得到名字,帧等信息
  18.                 ~TrInterfaceVedio(void);
  19.                 // 显示视频序列
  20.                 void loadVedios();
  21.                 // 创建四边形几何面片,为了纹理贴图
  22.                 osg::Geometry* myCreateTexturedQuadGeometry(const osg::Vec3& pos,float width,float height, osg::Image* image);
  23.                 // 返回 geode, 不作抬头显示
  24.                 osg::Geode* getGeode();
  25.                 // 作抬头显示,返回相机
  26.                 osg::Camera* getCamera();
  27.                 bool setVedioPath(string _VedioPath);
  28.         private:

  29.                 std::string _vediosPath;                // 存储视频序列中每段视频的存储路径
  30.                 osg::ref_ptr<osg::Geode> geode;// 图片可作为一个 geode 节点显示
  31.                 osg::ref_ptr<osg::ImageStream> imageStream;// 动画作为一个图片序列
  32.                 osg::ref_ptr<osg::Camera> _camera;// 要作为最外显示时需要一个post render 相机
  33.                 osg::Vec3 pos;// 视频位置

  34. };

复制代码
下面是FuncDemo.cpp


  1. #include "FuncDemo.h"

  2. unsigned int Width,Height;
  3. TrInterfaceVedio::TrInterfaceVedio(std::string vediosPath)
  4. {
  5.         //获取分辨率
  6.         osg::GraphicsContext::WindowingSystemInterface*wsi=osg::GraphicsContext::getWindowingSystemInterface();
  7.         if(!wsi)
  8.         {
  9.                 //return 0;
  10.         }
  11.        
  12.         wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0),Width,Height);

  13.         //设置图形环境特性
  14.         osg::ref_ptr<osg::GraphicsContext::Traits> traits=new osg::GraphicsContext::Traits();
  15.         traits->x=0;
  16.         traits->y=0;
  17.         traits->width=Width;
  18.         traits->height=Height;
  19.         traits->windowDecoration=false;
  20.         traits->doubleBuffer=true;
  21.         traits->sharedContext=0;
  22.         _vediosPath=vediosPath;

  23.         //GIf路径存储
  24.         geode = new osg::Geode;
  25.         _camera=new osg::Camera;

  26.         _camera->setProjectionMatrixAsOrtho2D(0,Width, 0, Height);
  27.         // set the view matrix   
  28.         _camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
  29.         _camera->setViewMatrix(osg::Matrix::identity());

  30.         // only clear the depth buffer
  31.         _camera->setClearMask(GL_DEPTH_BUFFER_BIT);

  32.         // draw subgraph after main camera view.
  33.         _camera->setRenderOrder(osg::Camera::POST_RENDER);

  34.         // we don't want the camera to grab event focus from the viewers main camera(s).
  35.         _camera->setAllowEventFocus(false);

  36.         _camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );

  37. }

  38. TrInterfaceVedio::~TrInterfaceVedio()
  39. {

  40. }


  41. bool TrInterfaceVedio::setVedioPath(string _VedioPath)
  42. {
  43.         return true;

  44. }
  45. osg::Geometry* TrInterfaceVedio::myCreateTexturedQuadGeometry(const osg::Vec3& pos,float width,float height, osg::Image* image)
  46. {
  47.         osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(pos,osg::Vec3(width,0.0f,0.0f),osg::Vec3(0.0f,height,0.0f),0.0f, 0.0f , 1.0f, 1.0f);

  48.         osg::Texture2D* texture = new osg::Texture2D(image);
  49.         texture->setResizeNonPowerOfTwoHint(false);
  50.         texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
  51.         texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
  52.         texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);

  53.         pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);

  54.         return pictureQuad;
  55.        
  56. }

  57. void TrInterfaceVedio::loadVedios()
  58. {
  59.         osg::Image* image = osgDB::readImageFile(_vediosPath);
  60.         imageStream = dynamic_cast<osg::ImageStream*>(image);
  61.         if (imageStream) imageStream->play();
  62.         if (image)
  63.         {
  64.                 geode->addDrawable(myCreateTexturedQuadGeometry(pos, Width, Height, image));
  65.         }
  66.         else
  67.         {
  68.                 std::cout<<"Unable to read file "<<"arguments[i]"<<std::endl;
  69.         }
  70.         _camera->addChild(geode);
  71. }
  72. osg::Camera* TrInterfaceVedio::getCamera()
  73. {
  74.         return _camera;
  75. }
  76. osg::Geode* TrInterfaceVedio::getGeode()
  77. {
  78.         return geode;
  79. }

  80. int main()
  81. {
  82.         /**开始动画*/
  83.     osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
  84.         osg::ref_ptr<osg::Group> group = new osg::Group;

  85.         int _timegif = 0;
  86.         //计算帧速
  87.         int counts = 0;
  88.         //控制帧速使用的睡眠时间
  89.         float sleep_time = 0.0;
  90.         float last_sleep = 0.0001;
  91.         //每帧的实际使用时间
  92.         float current_time = 0.0;
  93.         //每帧控制法
  94.         float per_str_time = 0.0;
  95.         float per_end_time = 0.0;

  96.         //申请一个定时器类
  97.         osg::Timer* timer = new osg::Timer;
  98.         osg::Timer_t start_frame_time = 0;
  99.         osg::Timer_t end_frame_time = 0;

  100.        
  101.         TrInterfaceVedio* gifReader = new TrInterfaceVedio("FuncDemo.gif");
  102.         gifReader->loadVedios();
  103.         group->addChild(gifReader->getCamera());
  104.         viewer->setSceneData(group);
  105.         while(!viewer->done())
  106.         {
  107.                 per_str_time = timer->tick();

  108.                 if(counts == 0)
  109.                 {
  110.                         start_frame_time = timer->tick();
  111.                 }
  112.                 counts++;
  113.                 viewer->frame();

  114.                 per_end_time = timer->tick();

  115.                 sleep_time = 0.1 - timer->delta_s(per_str_time, per_end_time);

  116.                 if(sleep_time < 0)
  117.                 {
  118.                         sleep_time = last_sleep * 0.8;
  119.                 }
  120.                 last_sleep = sleep_time;

  121.                 OpenThreads::Thread::microSleep(sleep_time*1000000);
  122.                 last_sleep = sleep_time;

  123.                 if(counts == 3)
  124.                 {
  125.                         //限制帧速为10,每帧绘制0.1s
  126.                         counts = 0;
  127.                         end_frame_time = timer->tick();
  128.                         std::cout<<"当前帧速为:"<<3/(timer->delta_s(start_frame_time, end_frame_time))<<std::endl;
  129.                         _timegif++;
  130.                         if(_timegif == 14)
  131.                         {
  132.                                 break;
  133.                         }
  134.                 }
  135.         }
  136. }
复制代码

该用户从未签到

 楼主| 发表于 2011-4-25 18:15:28 | 显示全部楼层
非常期待您的解决

该用户从未签到

发表于 2011-4-26 08:55:06 | 显示全部楼层
我在控制台下运行了您的程序,没有任何问题

该用户从未签到

 楼主| 发表于 2011-4-26 12:40:43 | 显示全部楼层
是运行一次没问题,但来个循环的话,就会出现问题。我用MFC试的。

该用户从未签到

发表于 2011-4-26 13:19:54 | 显示全部楼层
如何循环?这么重要的信息您并没有给出,我当然无法帮助判断什么

该用户从未签到

 楼主| 发表于 2011-4-27 12:21:04 | 显示全部楼层
我建了一个MFC的单文档工程,View类中声明了一个函数叫void play();
它的定义如下:

  1. void CtestView::play()
  2. {
  3.         /**开始动画*/
  4.     osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
  5.         osg::ref_ptr<osg::Group> group = new osg::Group;

  6.         int _timegif = 0;
  7.         //计算帧速
  8.         int counts = 0;
  9.         //控制帧速使用的睡眠时间
  10.         float sleep_time = 0.0;
  11.         float last_sleep = 0.0001;
  12.         //每帧的实际使用时间
  13.         float current_time = 0.0;
  14.         //每帧控制法
  15.         float per_str_time = 0.0;
  16.         float per_end_time = 0.0;

  17.         //申请一个定时器类
  18.         osg::Timer* timer = new osg::Timer;
  19.         osg::Timer_t start_frame_time = 0;
  20.         osg::Timer_t end_frame_time = 0;

  21.        
  22.         TrInterfaceVedio* gifReader = new TrInterfaceVedio("FuncDemo.gif");
  23.         gifReader->loadVedios();
  24.         group->addChild(gifReader->getCamera());
  25.         viewer->setSceneData(group);
  26.         while(!viewer->done())
  27.         {
  28.                 per_str_time = timer->tick();

  29.                 if(counts == 0)
  30.                 {
  31.                         start_frame_time = timer->tick();
  32.                 }
  33.                 counts++;
  34.                 viewer->frame();

  35.                 per_end_time = timer->tick();

  36.                 sleep_time = 0.1 - timer->delta_s(per_str_time, per_end_time);

  37.                 if(sleep_time < 0)
  38.                 {
  39.                         sleep_time = last_sleep * 0.8;
  40.                 }
  41.                 last_sleep = sleep_time;

  42.                 OpenThreads::Thread::microSleep(sleep_time*1000000);
  43.                 last_sleep = sleep_time;

  44.                 if(counts == 3)
  45.                 {
  46.                         //限制帧速为10,每帧绘制0.1s
  47.                         counts = 0;
  48.                         end_frame_time = timer->tick();
  49.                         std::cout<<"当前帧速为:"<<3/(timer->delta_s(start_frame_time, end_frame_time))<<std::endl;
  50.                         _timegif++;
  51.                         if(_timegif == 14)
  52.                         {
  53.                                 play();
  54.                         }
  55.                 }
  56.         }
  57. }
复制代码
然后在菜单栏上建了一个按钮,当点击它时,就会执行上面的play().
本来想上传整个程序,可是我不会弄。

该用户从未签到

 楼主| 发表于 2011-4-27 12:21:49 | 显示全部楼层
不知这次的表述是不是很清楚

该用户从未签到

发表于 2011-4-28 08:20:53 | 显示全部楼层
您的做法有些疯狂……每次play都直接构建一个新的viewer然后执行一个死循环?我想您还是好好整理一下自己程序的结构为好,参考osgviewerMFC的做法,但不要全盘照抄

该用户从未签到

 楼主| 发表于 2011-4-28 10:19:47 | 显示全部楼层
好的,谢谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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