查看: 2976|回复: 9

osg::CompositeViewer动态删除views程序中断

[复制链接]

该用户从未签到

发表于 2013-4-8 20:46:32 | 显示全部楼层 |阅读模式
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/CompositeViewer>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Geometry>
#include <osg/Camera>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgGA/TrackballManipulator>
#include <osgUtil/Optimizer>
#include <iostream>
//动态删除视图窗口事件
class DeletSlaveView:public osgGA::GUIEventHandler
{
public:
DeletSlaveView(osg::ref_ptr<osgViewer::CompositeViewer>compositeViewer,osg::ref_ptr<osgViewer::View>view):m_compositeviewer(compositeViewer),m_view(view){}
     bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&aa )
     {
         switch(ea.getEventType())
         {
         case osgGA::GUIEventAdapter::KEYDOWN:
              {
                   if (ea.getKey()=='q')
                   {
                       m_compositeviewer->stopThreading();//使用是否正确?
                       m_compositeviewer->removeView(m_view);
                       m_compositeviewer->startThreading();//使用是否正确?
                   }
              }
              break;
         default:
              break;
         }
         return false;
     }
public:
     osg::ref_ptr<osgViewer::CompositeViewer>m_compositeviewer;
     osg::ref_ptr<osgViewer::View>m_view;
};
int main()
{
     //创建CompositeViewer对象
     osg::ref_ptr<osgViewer::CompositeViewer> viewer = new osgViewer::CompositeViewer() ;
     //读取牛的模型
     osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile("cow.osg") ;
     //读取飞机模型
     osg::ref_ptr<osg::Node> cessna = osgDB::readNodeFile("cessna.osg");
     //优化场景数据
     osgUtil::Optimizer optimizer ;
     optimizer.optimize(cow.get());
     optimizer.optimize(cessna.get());
     //设置图形环境特性
     osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits();
     traits->x = 100;
     traits->y = 100;
     traits->width = 900;
     traits->height = 700;
     traits->windowDecoration = true;
     traits->doubleBuffer = true;
     traits->sharedContext = 0;
     //创建图形环境特性
          osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
     if (gc->valid())
     {
         osg::notify(osg::INFO)<<"  GraphicsWindow has been created successfully."<<std::endl;
         //清除窗口颜色及清除颜色和深度缓冲
         gc->setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f));
         gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     }
     else
     {
         osg::notify(osg::NOTICE)<<"  GraphicsWindow has not been created successfully."<<std::endl;
     }
     //视图一
     {
         //创建视图一
         osg::ref_ptr<osgViewer::View> view = new osgViewer::View;
         viewer->addView(view.get());
         //设置视图场景数据
         view->setSceneData(cow);
         //设置相机视口及图形环境
         view->getCamera()->setViewport(new osg::Viewport(0,0, traits->width/2, traits->width/2));
         view->getCamera()->setGraphicsContext(gc.get());
         //设置操作器
         view->setCameraManipulator(new osgGA::TrackballManipulator);
         
         //添加事件处理
         view->addEventHandler( new osgViewer::StatsHandler );
         view->addEventHandler( new osgViewer::WindowSizeHandler );
         view->addEventHandler( new osgViewer::ThreadingHandler );
         view->addEventHandler( new osgViewer::RecordCameraPathHandler );
         view->addEventHandler(new ModelMoveHandler);
     }
     //视图二
     
         osg::ref_ptr<osgViewer::View> view2 = new osgViewer::View;
         viewer->addView(view2.get());
         view2->setSceneData(cessna.get());
         view2->getCamera()->setViewport(new osg::Viewport(traits->width/2,0, traits->width/2, traits->height/2));
         view2->getCamera()->setGraphicsContext(gc.get());
         view2->setCameraManipulator(new osgGA::TrackballManipulator);
     //视图三
     
         osg::ref_ptr<osgViewer::View> view3 = new osgViewer::View;
         viewer->addView(view3.get());
         view3->setSceneData(cessna.get());
         //根据分辨率来确定合适的投影来保证显示的图形不变形
         double fovy, aspectRatio, zNear, zFar;
         view3->getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
         double newAspectRatio = double(traits->width) / double(traits->height/2);
         double aspectRatioChange = newAspectRatio / aspectRatio;
         if (aspectRatioChange != 1.0)
         {
              view3->getCamera()->getProjectionMatrix() *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0);
         }
         view3->getCamera()->setViewport(new osg::Viewport(0,traits->height/2, traits->width, traits->height/2));
         view3->getCamera()->setGraphicsContext(gc.get());
         view3->setCameraManipulator(new osgGA::TrackballManipulator);
//视图二调用动态删除事件,删除视图三
     view2->addEventHandler(new DeletSlaveView(viewer,view3));
     
     viewer->realize();
     //viewer->setThreadingModel(osgViewer::CompositeViewer:rawThreadPerContext);
     viewer->setThreadingModel(osgViewer::CompositeViewer::SingleThreaded);
     viewer->run() ;
     return 0 ;
}
以上程序添加了三个视图,之后程序运行后添加事件处理,在视图二上按键删除视图三,但是程序失败是怎么回事?

该用户从未签到

发表于 2013-4-9 08:11:41 | 显示全部楼层
哪里出错?

该用户从未签到

 楼主| 发表于 2013-4-9 11:21:10 | 显示全部楼层
liuzhiyu123 发表于 2013-4-9 08:11
哪里出错?

出错位置指向 return 0;

该用户从未签到

发表于 2013-4-12 10:23:25 | 显示全部楼层
  1. m_compositeviewer->stopThreading();//使用是否正确?
  2. m_compositeviewer->removeView(m_view);
  3. m_compositeviewer->startThreading();//使用是否正确?
复制代码
理论上这样是可以的,不过实际中我个人始终不建议这么做,不如直接找到底层的GraphicsWindowWin32然后直接隐藏掉HWND

该用户从未签到

 楼主| 发表于 2013-4-12 11:42:08 | 显示全部楼层
array 发表于 2013-4-12 10:23
理论上这样是可以的,不过实际中我个人始终不建议这么做,不如直接找到底层的GraphicsWindowWin32然后直接隐 ...

你好,怎样从CompsiteViewer找到底层的GraphicsWindowWin32?谢谢

该用户从未签到

发表于 2013-4-12 11:55:32 | 显示全部楼层
view camera GraphicContext GraphicsWindowWin32

该用户从未签到

 楼主| 发表于 2013-4-12 12:44:57 | 显示全部楼层
liuzhiyu123 发表于 2013-4-12 11:55
view camera GraphicContext GraphicsWindowWin32

你好,view->getcamera->getGraphicContext->.....后面获取不到GraphicsWindowWin32对象,查看了一下GraphicsWindowWin32对象它继承自osgViewer::GraphicWindow,osgViewer::GraphicWindow继承自osg::GraphicsContext、osgGA::GUIActionAdapter类,从compsiteviewer类该怎么获取到?谢谢

该用户从未签到

发表于 2013-4-12 13:10:25 | 显示全部楼层
dynamic_cast

该用户从未签到

 楼主| 发表于 2013-4-12 18:34:34 | 显示全部楼层
liuzhiyu123 发表于 2013-4-12 13:10
dynamic_cast

你好,我在去掉视图事件响应里这么做的:
if (ea.getKey()=='q')
{
osgViewer::GraphicsWindowWin32* G32 =dynamic_cast<osgViewer::GraphicsWindowWin32*>(m_view->getCamera()-        >getGraphicsContext());                                                                       
HWND hwnd=G32->getHWND();
::ShowWindow(hwnd,SW_HIDE);
}
结构将整个窗口都删除掉了,我原来的目的是只是删除视图三,该怎么做?谢谢

该用户从未签到

发表于 2013-4-15 07:42:57 | 显示全部楼层
您的所有camera都共用了一个gc  您说 它是属于谁的?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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