osg和Qt结合,记录一下环境搭建,测试及遇到的问题

项目需要用到osg,Qt和vs2010结合,这几天一直在搞这个事情,遇到了很多困难,在这里记录一下

以我的经历强调几个重点,这几个点最好在编译之前就解决了,不然太浪费时间。都是个人意见仅供参考。


1. 把osg嵌入Qt最好用Qt4,推荐选择Qt4.8。两个原因,一是Qt5据说是支持单线程的,我先前觉得Qt4太旧了,选择了几个Qt5的版本,好不容易编译成功了,最后使用的时候遇到线程的问题“Cannot make QOpenGLContext current in a different thread.”,始终没找到解决方法,放弃了。二是Qt4.6(好像是的)以前的版本需要编译,直接用Qt4.8版本有编译好的适用于vs2010的版本。


2. 如果真的要编译osg+Qt5的话一定要检查这个文件:/src/osgQt/CMakeLists.txt ,具体原因链接里面看:http://blog.csdn.net/BenBenDeYiZhi/article/details/78847441


3.在vs2010+Qt4环境下编译osg的过程需要注意两个很重要的点:

一是开始编译之前一定不要忘记 修改osg根目录下的Cmakelist.txt文件,在末尾添加如下两句:

    set(DESIRED_QT_VERSION "4.8.6" CACHE STRING "") 

    set(CMAKE_PREFIX_PATH "D:\qt\4.8.6" CACHE PATH "")   (注意把D:\qt\4.8.6换成你自己的qt路径

二是用vs2010生成osg文件的时候一定要记得打开vs2010的方式是“以管理员的身份打开”,并且一旦生成在D盘,就不能再把生成的osg文件移到C盘使用(我的是这样,不知道为什么,我试着把编译生成的库,头文件啥的移动到C盘,最后命令行运行osgversion命令的时候出错“无法找到ot13-OpenThreads.dll入口点”啥的,记不清了)


4.经常遇到的错类型:

一是编译时无法打开某个头文件,如QGLwidget头文件,基本上是需要吧头文件所在的路径加入到项目属性-->VC++目录-->包含文件下,QGLWidget在Qt\Qt4.8.6\include\QtOpenGL里面。

二是编译时出现“error LNK2019: 无法解析的外部符号 "__declspec(dllimport) ”错误,一般都是因为缺少相关的库文件,仔细查看错误,看看错误跟哪个函数或类有关,继而找到这个函数所在的头文件,从而可以推断出这个类所在的库文件(.lib文件),把库文件名添加到项目属性-->连接器-->输入 里面就好了(但是有一个前提,这个库的路径一定得在环境变量path里面)。


5.osg的第三方库可以直接选用已经编译好的,无需自己编译,节省时间。第一次编译的时候可以不用勾选编译osg自带的例子,毕竟不一定成功,等真的编译成功了可以再挑选个晚上的时间重新编译带例子的,个人习惯呀,大家自便了这个。


下面贴一下qt+osg+vs2010环境搭建的具体步骤的参考链接:

Qt5.5+osg3.2+vs2010环境搭建参考链接1:http://blog.csdn.net/bbppbb/article/details/45697731

                                                         参考链接2:http://blog.sina.com.cn/s/blog_89a45b020102whh8.html

Qt4.8.6+osg3.2+vs2010环境搭建参考链接:http://blog.sciencenet.cn/blog-419883-955964.html


最后的测试:

先检测osg的有没有安装成功,打开命令行,输入osgversion,输出osg版本信息,输入osgviewer cow.osg出现牛。然后打开vs,新建一个QtApplication(直接点击完成就好),配置好项目属性里面的包含目录和库目录,配置好附加依赖项,把如下代码复制到主函数,覆盖原来的主函数即可,如果出现错误提示,把错误排除(比如包含目录错误,打开文件错误等等),完成后如果程序运行成功(参考最后给出的链接),一切完事了,恭喜~

代码:

  1. #include <QTimer>  
  2. #include <QApplication>  
  3. #include <QGridLayout>  
  4. #include <QWidget>  
  5.   
  6. #include <osgViewer/CompositeViewer>  
  7. #include <osgViewer/ViewerEventHandlers>  
  8.   
  9. #include <osgGA/TrackballManipulator>  
  10.   
  11. #include <osgDB/ReadFile>  
  12.   
  13. #include <osgQt/GraphicsWindowQt>  
  14.   
  15. #include <iostream>  
  16.   
  17. class ViewerWidget : public QWidget, public osgViewer::CompositeViewer  
  18. {  
  19. public:  
  20.     ViewerWidget(osgViewer::ViewerBase::ThreadingModel threadingModel=osgViewer::CompositeViewer::SingleThreaded) : QWidget()  
  21.     {  
  22.         setThreadingModel(threadingModel);  
  23.   
  24.         // disable the default setting of viewer.done() by pressing Escape.  
  25.         setKeyEventSetsDone(0);  
  26.   
  27.         QWidget* widget1 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readNodeFile("cow.osgt") );  
  28.         QWidget* widget2 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readNodeFile("glider.osgt") );  
  29.         QWidget* widget3 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readNodeFile("axes.osgt") );  
  30.         QWidget* widget4 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readNodeFile("fountain.osgt") );  
  31.         QWidget* popupWidget = addViewWidget( createGraphicsWindow(900,100,320,240,"Popup window",true), osgDB::readNodeFile("dumptruck.osgt") );  
  32.         popupWidget->show();  
  33.   
  34.         QGridLayout* grid = new QGridLayout;  
  35.         grid->addWidget( widget1, 0, 0 );  
  36.         grid->addWidget( widget2, 0, 1 );  
  37.         grid->addWidget( widget3, 1, 0 );  
  38.         grid->addWidget( widget4, 1, 1 );  
  39.         setLayout( grid );  
  40.   
  41.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  42.         _timer.start( 10 );  
  43.     }  
  44.   
  45.     QWidget* addViewWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  46.     {  
  47.         osgViewer::View* view = new osgViewer::View;  
  48.         addView( view );  
  49.   
  50.         osg::Camera* camera = view->getCamera();  
  51.         camera->setGraphicsContext( gw );  
  52.   
  53.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  54.   
  55.         camera->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 1.0) );  
  56.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  57.         camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f );  
  58.   
  59.         view->setSceneData( scene );  
  60.         view->addEventHandler( new osgViewer::StatsHandler );  
  61.         view->setCameraManipulator( new osgGA::TrackballManipulator );  
  62.   
  63.         return gw->getGLWidget();  
  64.     }  
  65.   
  66.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  67.     {  
  68.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  69.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  70.         traits->windowName = name;  
  71.         traits->windowDecoration = windowDecoration;  
  72.         traits->x = x;  
  73.         traits->y = y;  
  74.         traits->width = w;  
  75.         traits->height = h;  
  76.         traits->doubleBuffer = true;  
  77.         traits->alpha = ds->getMinimumNumAlphaBits();  
  78.         traits->stencil = ds->getMinimumNumStencilBits();  
  79.         traits->sampleBuffers = ds->getMultiSamples();  
  80.         traits->samples = ds->getNumMultiSamples();  
  81.   
  82.         return new osgQt::GraphicsWindowQt(traits.get());  
  83.     }  
  84.   
  85.     virtual void paintEvent( QPaintEvent* event )  
  86.     { frame(); }  
  87.   
  88. protected:  
  89.   
  90.     QTimer _timer;  
  91. };  
  92.   
  93. int main( int argc, char** argv )  
  94. {  
  95.     osg::ArgumentParser arguments(&argc, argv);  
  96.   
  97.     osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::CullDrawThreadPerContext;  
  98.     while (arguments.read("--SingleThreaded")) threadingModel = osgViewer::ViewerBase::SingleThreaded;  
  99.     while (arguments.read("--CullDrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::CullDrawThreadPerContext;  
  100.     while (arguments.read("--DrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::DrawThreadPerContext;  
  101.     while (arguments.read("--CullThreadPerCameraDrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::CullThreadPerCameraDrawThreadPerContext;  
  102.   
  103.     QApplication app(argc, argv);  
  104.     ViewerWidget* viewWidget = new ViewerWidget(threadingModel);  
  105.     viewWidget->setGeometry( 100, 100, 800, 600 );  
  106.     viewWidget->show();  
  107.     return app.exec();  
  108. }  
代码参考链接:http://blog.csdn.net/zhaohsww/article/details/19085211

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值