c/c++语言开发共享OSG嵌入QT的简明总结

[toc] 1.解决方案 不得不说关于OSG的资料实在太零散了,搜索了很多关于OSG在QT下的解决方案,都是各有各的说法,有的说的不是很清楚,有的已经过时了。这里提供一下自己的解决方案吧。 在远古的OSG里面,应该是提供对QT的支持的;不过应该是由于QT版本变动比较大,现在的OSG版本应该已经没有了 …

目录

1.解决方案

不得不说关于osg的资料实在太零散了,搜索了很多关于osg在qt下的解决方案,都是各有各的说法,有的说的不是很清楚,有的已经过时了。这里提供一下自己的解决方案吧。
在远古的osg里面,应该是提供对qt的支持的;不过应该是由于qt版本变动比较大,现在的osg版本应该已经没有了。但是在github上又有了新的osgqt项目(地址:https://github.com/openscenegraph/osgqt) 用来解决这个问题。
osgqt是个简单的小项目,其实没有必要额外的编译,最核心的是个名为graphicswindowqt的类,只需要复制graphicswindowqt.h和graphicswindowqt.cpp到qt工程里面就可以使用了。同时osgqt给出了一个名为osgviewerqt的样例,也仅仅只是个cpp文件。结合两者,一个简单的示例就出来了。
qt工程如下:
OSG嵌入QT的简明总结
编译运行后如下:
OSG嵌入QT的简明总结

2.存在问题

1) 警告提示

上述项目直接运行,会出现诸如“qopenglcontext::swapbuffers() called with non-exposed window, behavior is undefined”的警告。查阅网上的英文资料,大意说是因为opengl环境未初始化产生的。在osgviewerqt中绑定了一个定时器,每隔10ms就调用frame()来绘制一帧,而这个定时器是在构造函数的时候就开始调用了,没有等待qt中opengl环境的生成。在这里我把定时器的部分给改进了一下,等待osg的环境初始化完成在启动定时器,这个警告就没有了。osgviewerqt改进后的代码如下:

#include <qtimer> #include <qapplication> #include <qgridlayout>  #include <osgviewer/compositeviewer> #include <osgviewer/viewereventhandlers>  #include <osgga/multitouchtrackballmanipulator>  #include <osgdb/readfile>  #include "graphicswindowqt"  #include <iostream>  class viewerwidget : public qwidget, public osgviewer::compositeviewer { public:     viewerwidget(qwidget* parent = 0, qt::windowflags f = 0, osgviewer::viewerbase::threadingmodel threadingmodel=osgviewer::compositeviewer::singlethreaded) : qwidget(parent, f)     {         setthreadingmodel(threadingmodel);          // disable the default setting of viewer.done() by pressing escape.         setkeyeventsetsdone(0);          qwidget* widget1 = addviewwidget( creategraphicswindow(0,0,100,100), osgdb::readrefnodefile("d:/work/osgbuild/openscenegraph-data/cow.osgt") );         qwidget* widget2 = addviewwidget( creategraphicswindow(0,0,100,100), osgdb::readrefnodefile("d:/work/osgbuild/openscenegraph-data/glider.osgt") );         qwidget* widget3 = addviewwidget( creategraphicswindow(0,0,100,100), osgdb::readrefnodefile("d:/work/osgbuild/openscenegraph-data/axes.osgt") );         qwidget* widget4 = addviewwidget( creategraphicswindow(0,0,100,100), osgdb::readrefnodefile("d:/work/osgbuild/openscenegraph-data/fountain.osgt") ); //        qwidget* popupwidget = addviewwidget( creategraphicswindow(900,100,320,240,"popup window",true), osgdb::readrefnodefile("d:/work/osgbuild/openscenegraph-data/dumptruck.osgt") ); //        popupwidget->show();          qgridlayout* grid = new qgridlayout;         grid->addwidget( widget1, 0, 0 );         grid->addwidget( widget2, 0, 1 );         grid->addwidget( widget3, 1, 0 );         grid->addwidget( widget4, 1, 1 );         setlayout( grid );          //connect( &_timer, signal(timeout()), this, slot(update()) );         //_timer.start( 10 );     }      qwidget* addviewwidget( osgqt::graphicswindowqt* gw, osg::ref_ptr<osg::node> scene )     {         osgviewer::view* view = new osgviewer::view;         addview( view );          osg::camera* camera = view->getcamera();         camera->setgraphicscontext( gw );          const osg::graphicscontext::traits* traits = gw->gettraits();          camera->setclearcolor( osg::vec4(0.2, 0.2, 0.6, 1.0) );         camera->setviewport( new osg::viewport(0, 0, traits->width, traits->height) );          // set the draw and read buffers up for a double buffered window with rendering going to back buffer         camera->setdrawbuffer(gl_back);         camera->setreadbuffer(gl_back);          camera->setprojectionmatrixasperspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f );          view->setscenedata( scene );         view->addeventhandler( new osgviewer::statshandler );         view->setcameramanipulator( new osgga::multitouchtrackballmanipulator );         gw->settoucheventsenabled( true );         return gw->getglwidget();     }      osgqt::graphicswindowqt* creategraphicswindow( int x, int y, int w, int h, const std::string& name="", bool windowdecoration=false )     {         osg::displaysettings* ds = osg::displaysettings::instance().get();         osg::ref_ptr<osg::graphicscontext::traits> traits = new osg::graphicscontext::traits;         traits->windowname = name;         traits->windowdecoration = windowdecoration;         traits->x = x;         traits->y = y;         traits->width = w;         traits->height = h;         traits->doublebuffer = true;         traits->alpha = ds->getminimumnumalphabits();         traits->stencil = ds->getminimumnumstencilbits();         traits->samplebuffers = ds->getmultisamples();         traits->samples = ds->getnummultisamples();          return new osgqt::graphicswindowqt(traits.get());     }  //    virtual void paintevent( qpaintevent* /*event*/ ) //    { frame(); }      //定时器事件     void timerevent(qtimerevent* )     {         frame();     }      //启动定时器绘制     void show()     {         qwidget::show();         _timerid = starttimer(10);     }   protected:      //qtimer _timer;     int _timerid;               //定时器id };  int main( int argc, char** argv ) {     osg::argumentparser arguments(&argc, argv);  #if qt_version >= 0x050000     // qt5 is currently crashing and reporting "cannot make qopenglcontext current in a different thread" when the viewer is run multi-threaded, this is regression from qt4     osgviewer::viewerbase::threadingmodel threadingmodel = osgviewer::viewerbase::singlethreaded; #else     osgviewer::viewerbase::threadingmodel threadingmodel = osgviewer::viewerbase::culldrawthreadpercontext; #endif      while (arguments.read("--singlethreaded")) threadingmodel = osgviewer::viewerbase::singlethreaded;     while (arguments.read("--culldrawthreadpercontext")) threadingmodel = osgviewer::viewerbase::culldrawthreadpercontext;     while (arguments.read("--drawthreadpercontext")) threadingmodel = osgviewer::viewerbase::drawthreadpercontext;     while (arguments.read("--cullthreadpercameradrawthreadpercontext")) threadingmodel = osgviewer::viewerbase::cullthreadpercameradrawthreadpercontext;  #if qt_version >= 0x040800     // required for multithreaded qglwidget on linux/x11, see https://blog.qt.io/blog/2011/06/03/threaded-opengl-in-4-8/     if (threadingmodel != osgviewer::viewerbase::singlethreaded)         qapplication::setattribute(qt::aa_x11initthreads); #endif      qapplication app(argc, argv);     viewerwidget* viewwidget = new viewerwidget(0, qt::widget, threadingmodel);     viewwidget->setgeometry( 100, 100, 800, 600 );     viewwidget->show();     return app.exec(); }

2) 多线程问题

在osg中提供了诸如culldrawthreadpercontext等多线程模式,但是在这里是没办法支持这些多线程模式的,只能支持单线程。在网上查阅了一些解决方案,但是最后都不是很完美,有空再把其解决方案写出来。

3) 其他

graphicswindowqt最终继承的还是qt中的qglwidget类,提供opengl功能。而在新版本的qt中,这个类已经被废弃了,取而代之的是一个叫做qopenglwidget的类。所以这里面问题还是不少的,好在内容相对较少,以后有空可以自己改进。

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/603005.html

(0)
上一篇 2021年5月11日
下一篇 2021年5月11日

精彩推荐