OSG嵌入Qt的第二种方式:使用QOpenGLWidget/QGLWidget
2015-07-18 21:00
651 查看
几天前有朋友问OSG嵌入Qt的思路。我说整体思路就是用OpenGL的方式来进行OSG的绘制,而正好Qt已经整合了OpenGL的功能,我们可以以此为依托来进行OSG的渲染绘制工作。而在Qt中却有QWidget和QGraphicsView两种不同的体系框架,于是我们也就有了两种不同的嵌入方式,关于QGraphicsView的嵌入方式我前面的博客OSGEarth嵌入Qt的QGraphicsView框架已经完成了,本篇是增加对QWidget体系的讲解。
Qt中具有OpenGL功能的是一个继承自QWidget的widget,叫做QGLWidget,但是在Qt5.5的版本中此类已被废弃,取而代之的是一个叫做QOpenGLWidget的类。在此,我用的是5.5版本的QOpenGLWidget,若是您用的之前的Qt版本请使用QGLWidget。
首先,我们需要处理一下按键、鼠标事件,处理的方式与QGraphicsView体系中使用的方式是相同的,代码也没太大变化,可参看OSGEarth嵌入Qt的QGraphicsView框架变化的地方在于继承的对象变了,在QGraphicsView体系中EventAdapter 继承自QGraphicsView,现在我们需要EventAdapter 继承自QOpenGLWidget。
完成事件处理后,我们来进行OSG的嵌入工作。
首先是头文件:
注意我们的Widget3D直接从osgViewer::Viewer继承了,而在QGraphicsView体系中是设置的视口(setViewPort)。
Qt中具有OpenGL功能的是一个继承自QWidget的widget,叫做QGLWidget,但是在Qt5.5的版本中此类已被废弃,取而代之的是一个叫做QOpenGLWidget的类。在此,我用的是5.5版本的QOpenGLWidget,若是您用的之前的Qt版本请使用QGLWidget。
首先,我们需要处理一下按键、鼠标事件,处理的方式与QGraphicsView体系中使用的方式是相同的,代码也没太大变化,可参看OSGEarth嵌入Qt的QGraphicsView框架变化的地方在于继承的对象变了,在QGraphicsView体系中EventAdapter 继承自QGraphicsView,现在我们需要EventAdapter 继承自QOpenGLWidget。
完成事件处理后,我们来进行OSG的嵌入工作。
首先是头文件:
class Widget3D : public EventAdapter, public osgViewer::Viewer { Q_OBJECT public: Widget3D(QWidget *parent = 0); ~Widget3D(); osgViewer::Viewer* getOSGViewer(){ return this; } osg::Group* getRoot(){ return m_pRoot; } protected: // 看这里,这是关键,即每帧刷新的操作有这里来完成,使用的思路和QGraphicsView体系中是一样的,控制定时器进行更新 virtual void paintGL(){ frame(); } virtual void timerEvent(QTimerEvent *event){ update(); } private: void init3D(); osg::ref_ptr<osg::Camera> createCamera(int x, int y, int w, int h); private: osg::ref_ptr<osg::Group> m_pRoot; };
注意我们的Widget3D直接从osgViewer::Viewer继承了,而在QGraphicsView体系中是设置的视口(setViewPort)。
Widget3D::Widget3D(QWidget *parent) : EventAdapter(parent) { init3D(); this->setMouseTracking(true); } Widget3D::~Widget3D() { } void Widget3D::init3D() { m_pRoot = new osg::Group; m_pRoot->setName("Root"); this->setCamera(createCamera(0, 0, width(), height())); osg::ref_ptr<osgGA::TrackballManipulator> pManipulator = new osgGA::TrackballManipulator; this->setCameraManipulator(pManipulator); this->addEventHandler(new osgViewer::StatsHandler); this->addEventHandler(new osgViewer::ThreadingHandler()); this->addEventHandler(new osgViewer::HelpHandler); this->addEventHandler(new osgGA::StateSetManipulator(this->getCamera()->getOrCreateStateSet())); this->setThreadingModel(osgViewer::Viewer::SingleThreaded); m_pRoot->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON); m_pRoot->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); this->setSceneData(m_pRoot); // 添加cow.osg作为测试 osg::ref_ptr<osg::Node> pNode = osgDB::readNodeFile("cow.osg"); osg::ref_ptr<osg::MatrixTransform> matTrans = new osg::MatrixTransform; matTrans->addChild(pNode); matTrans->setMatrix(osg::Matrix::translate(osg::Vec3d(0, -15, 0))); m_pRoot->addChild(matTrans); startTimer(10); } osg::ref_ptr<osg::Camera> Widget3D::createCamera(int x, int y, int w, int h) { m_pGraphicsWindow = new osgViewer::GraphicsWindowEmbedded(x, y, w, h); osg::DisplaySettings* ds = osg::DisplaySettings::instance().get(); osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; traits->windowDecoration = true; traits->x = x; traits->y = y; traits->width = w; traits->height = h; traits->doubleBuffer = true; traits->sharedContext = 0; osg::ref_ptr<osg::Camera> camera = new osg::Camera; camera->setGraphicsContext(m_pGraphicsWindow); camera->setClearColor(osg::Vec4(0.3, 0.3, 0.6, 0.8)); camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height)); camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); camera->setProjectionMatrixAsPerspective( 30.0f, static_cast<double>(traits->width) / static_cast<double>(traits->height), 1.0f, 10000.0f); return camera.release(); }
相关文章推荐
- 自学Qt_2,第一个应用程序
- qt- thread —— 关于槽函数所在线程的问题
- Qt中 抽象列表模型类 的使用
- qtcreator快捷键总结
- qt中设置菜单高度
- Qt界面编程之多窗口切换
- qtp 参数类 VBS 利用Default 关键字来 实现构造函数的功能
- VS2010配置QT5.5.0开发环境
- 利用QTP TextUtil对象获取图片验证码
- ubuntu Qt连接MySQL
- QT:QDir中文件路径的问题“\” “\\” “/"
- Qt中PostgreSQL数据库驱动插件的编译
- QTP 中class 类的应用(一)
- QTP 应该DOM ,web测试不再困难
- JScript在QTP中的终极探究(二)
- JScript在QTP中的应用探究(一)
- QTP/UFT 11中EmbedScript 和 RunScript 的区别
- 各种小部件的垂直布局
- 自学QT,第一部分,信号与槽
- Qt笔记一