• Windows下osg+Qt搭建三维开发环境


          本博文讲述利用Visual Studio 2019、Osg、Qt搭建三维开发环境。本次Qt版本为5.14.1,Window为Windows 10。osg可以去osg下载,截至2022年8月21日,osg最新版本已经到3.6.5版本,考虑到最新版本的往往有些许的bug,故本文采用的是3.4.1版本,其下载地址为:OpenSceneGraph-3.4.1 release download

     1.osg编译安装

         osg在Windows下的 编译安装参见《windows平台下用CMake编译osg》。

    注意:在利用CMake生成OpenSceneGraph.sln时,该解决方案的OSG Core文件夹下有的电脑会有osgQt工程 ,有的则没有,如:我公司电脑有osgQt工程,而我自己笔记本则没有,环境都一样,原因至今不知道。编译完成后,我的目录结构如下:

     2.利用Qt创建osg工程

    在Visual Studio 2019下创建一个osg的Qt工程,cpp代码代码如下:

    1. #include "QtWidgetsApplication2.h"
    2. #include
    3. QtWidgetsApplication2::QtWidgetsApplication2(QWidget *parent)
    4. : QWidget(parent)
    5. {
    6. ui.setupUi(this);
    7. initOsg();
    8. }
    9. QtWidgetsApplication2::~QtWidgetsApplication2()
    10. {}
    11. void QtWidgetsApplication2::initOsg()
    12. {
    13. // 步骤一:初始化qt窗口系统
    14. osgQt::initQtWindowingSystem();
    15. // 步骤二:创建视口
    16. m_pViewer = new osgViewer::Viewer;
    17. // 步骤三:视口设为单线程(Qt5必须)
    18. m_pViewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
    19. // 步骤四:对视图的操作,必须,否则无法显示黑屏
    20. m_pViewer->setCameraManipulator(new osgGA::TrackballManipulator);
    21. // 步骤五:视口操作
    22. // 步骤六:设置osgQt视口(一个应用程序用opgQt同一时刻只能设置一个视口)
    23. osgQt::setViewer(m_pViewer.get());
    24. // 步骤七:创建窗口(2个都要,只创建osgQt::GLWidget会挂掉)
    25. m_pGLWidget = new osgQt::GLWidget(this);
    26. m_pGraphicsWindowQt = new osgQt::GraphicsWindowQt(m_pGLWidget);
    27. // 步骤八:设置视口
    28. m_pViewport = new osg::Viewport(0, 0, m_pGLWidget->width(), m_pGLWidget->height());
    29. //m_pViewport = new osg::Viewport();
    30. // 步骤九:设置摄像机视口范围,未设置不会显示,即窗口一片黑(刷新窗口但没有内容显示)
    31. m_pViewer->getCamera()->setViewport(m_pViewport);
    32. m_pViewer->getCamera()->setClearColor(osg::Vec4f(0.0235, 0.45, 0.67, 1.0));
    33. // 步骤十:设置刷新显示内容,未设置不会显示,即一片白(不会刷新窗口)
    34. m_pViewer->getCamera()->setGraphicsContext(m_pGraphicsWindowQt);
    35. auto spCowNode = osgDB::readNodeFile("cow.osg");
    36. m_pViewer->setSceneData(spCowNode );
    37. }
    38. void QtWidgetsApplication2::resizeEvent(QResizeEvent* event)
    39. {
    40. m_pGLWidget->move(0, 0);
    41. m_pGLWidget->resize(event->size());
    42. }

     .h代码如下:

    1. #pragma once
    2. #include
    3. #include "ui_QtWidgetsApplication2.h"
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. class QtWidgetsApplication2 : public QWidget
    16. {
    17. Q_OBJECT
    18. public:
    19. QtWidgetsApplication2(QWidget *parent = nullptr);
    20. ~QtWidgetsApplication2();
    21. void initOsg();
    22. void resizeEvent(QResizeEvent* event) override;
    23. private:
    24. Ui::QtWidgetsApplication2Class ui;
    25. // osg about
    26. osg::ref_ptr m_pViewer{ nullptr };
    27. osg::ref_ptr m_pViewport{ nullptr };
    28. osgQt::GLWidget* m_pGLWidget{ nullptr };
    29. osg::ref_ptr < osgQt::GraphicsWindowQt> m_pGraphicsWindowQt{ nullptr };
    30. };

    生成目录、包含目录、库目录、链接库设置如下:

     

    图1:生成目录 

    图2:包含目录、库目录

      图3:链接库设置

    为了保证链接设置完全,我们把osg的核心库都加入,如下:

    1. OpenThreadsd.lib
    2. osgd.lib
    3. osgDBd.lib
    4. osgGAd.lib
    5. osgManipulatord.lib
    6. osgTextd.lib
    7. osgUId.lib
    8. osgUtild.lib
    9. osgViewerd.lib
    10. osgWidgetd.lib
    11. osgQtd.lib

     注意:这是debug版的lib,release版的去掉文件名的最后一个d即可。

     3.遇到的问题解决

    当编译2节的工程时,会出现很多问题。

    问题1:报如下找不到头文件的错误:

     解决方法:将E:\osg\build\include下子目录下的文件拷贝到

                    E:\osg\OpenSceneGraph-3.4.1\include目录下与其子目录名相同的目录中。

    无法打开包括文件: “osgQt/Version”: No such file or directory

    找到E:\osg\OpenSceneGraph-3.4.1\src\osgQt目录下的Version.in文件拷贝到E:\osg\OpenSceneGraph-3.4.1\include\osgQt并重命名为Version,用记事本打开该文件并将下面删除:

    1. #if (QT_VERSION < QT_VERSION_CHECK(OSGQT_QT_VERSION,0,0))
    2. #error "Qt version mismatch detected! Make sure to compile applications using osgQt with the same major Qt version that osgQt has been compiled against."
    3. #endif

    否则会报: error C2018: 未知字符“0x40”。

    问题2:osgQt工程问题

           解决方案的OSG Core文件夹下有osgQt工程,则直接链接osgQt,QtWidgetsApplication2工程启动,但立马崩溃,崩溃于:osg\State.cpp的第229行,如下:

       _glExtensions->glGetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS_ARB, &bits);
    

    发现_glExtensions的glGetQueryiv函数指针没初始化,是随机值。解决方案的OSG Core文件夹下没有osgQt工程,则不会生成osgQtd.lib,则会报找不到osgQtd.lib。

    4.自己创建osgQt工程

          从3节遇到的问题我们知道,osg自带的osgQt工程会导致主程序崩溃;没有osgQt工程,则会报找不到osgQtd.lib。那么我们手动创建osgQt工程,以生成osgQtd.lib。

         打开Visual Studio 2019,选择创建Qt Class Library,工程名为osgQt,工程保存目录为:

    E:\osg\build\src ,从工程中移除osgQt.h、osgQt.cpp。将E:\osg\OpenSceneGraph-3.4.1\src\osgQt目录下的所有cpp文件和E:\osg\OpenSceneGraph-3.4.1\include\osgQt目录下的所有文件拷贝到刚新建的E:\osg\build\src\osgQt目录下,并在VS2019中将这些文件添加到工程中(Export、Version可以不添加)。之后将QFontImplementation.cpp头部的

    #include 改为#include "QFontImplementation"。同理,只要是本工程中的文件,都将头文件的包含改为:

    #include 改为#include "XXXX",其中XXXX为本目录的文件,如:QFontImplementation。

    。     按2节描述的那样为该工程添加包含目录、库目录、链接库(注意:osgQtd.lib就不要添加了)。设置Qt的模块如下:

     图4 

     设置生成的debug版本的文件名带一个d且设置输出目录,如下:

    图5 

     编译osgQt,报如下错误:

    即 “graphicswindow_Qt”: 不允许 dllimport 函数 的定义。找到Export文件,在文件顶部加入如下宏定义: #define OSGQT_LIBRARY,如下:

    ,如果还不行,将该Export的所有行都注释,加入:

    #define OSGQT_EXPORT __declspec(dllexport)

    再次编译,报如下链接错误:

    产生这些错误的原因是QGraphicsViewAdapter类没生成元对象有关的cpp文件,也就是如下红色方框的属性节点在编译时消失导致不能生成moc文件,原因费解 。

    打开cmd或power shell,cd到当前目录,执行如下命令:

     即:

    C:\Qt\Qt5.14.1\5.14.1\msvc2017_64\bin\moc.exe QGraphicsViewAdapter -o moc_GraphicsViewAdapter.cpp

           其中C:\Qt\Qt5.14.1\5.14.1是你Qt在本机的安装目录,此时会在当期目录下生成moc_GraphicsViewAdapter.cpp,将该文件添加到osgQt工程,再次编译就成功了,此时在E:\osg\build\bin目录下就有osgQtd.dll、osgQtd.lib。将osgQtd.lib复制到E:\osg\build\lib目录。将从Osg官网下载的cow.osg、reflect.rgb文件拷贝到QtWidgetsApplication2工程,并启动该工程,效果如下:

     注意:reflect.rgb也要拷贝,否则牛是白色的,不会是彩色的。

    至此,Windows下的osg和Qt开发环境配置完成。

    5.后记

           现在osg使用QT做窗口系统的工程剥离出去了,在 https://github.com/openscenegraph/osgQt 我们可以下载到osg使用QT窗口的工程,其中osgQt/examples/osgQtWidgets/osgQtWidgets.cpp中对使用Qt创建窗口使用OSG进行绘制有详细的示例。
     

  • 相关阅读:
    基于进化思想的聚类算法及其类簇融合算法(Matlab代码实现)
    基于JavaWeb的药品进销存管理系统(JSP)
    深入浅出Dart》函数
    Flink CDC介绍和个人理解
    Docker 的常用指令学习以及使用
    数据结构基础--栈和队列
    ant-design的Select组件采用自定义后缀图标(suffixIcon属性)时,点击该自定义图标没有反应,不会展示下拉菜单的问题
    HDU - 2859 Phalanx(DP)
    js:对dom元素class属性进行读取、更新、移除操作
    CSAPP 之 BombLab 详解
  • 原文地址:https://blog.csdn.net/danshiming/article/details/126447067