在QT中搭建OSG开发环境

本文介绍了如何在QT环境中配置OpenSceneGraph(OSG)的开发环境,特别是使用osgQt的方式。内容包括概述OSG的基本功能,解析集成到QT的两种方式,并详细讲解了通过源码修改和集成GraphicsWindowQt的方法,以及在QT项目中引入相关依赖和文件的步骤。
摘要由CSDN通过智能技术生成

一、概述

        OpenSceneGraph(简称OSG)使用OpenGL技术开发,是一套基于C++平台的应用程序接口(API),它让程序员能够更加快速、便捷地创建高性能、跨平台的交互式图形程序。它作为中间件(middleware)为应用软件提供了各种高级渲染特性,IO,以及空间结构组织函数;而更低层次的OpenGL 硬件抽象层(HAL)实现了底层硬件显示的驱动。

        网上关于编译osg的资料太多,关于OSG的编译在此不过多赘述,本人使用的是vs2015+osg365,本篇将详细讲解一下如何在QT中搭建OSG开发环境。

        无论是集成到QT还是MFC还是其他开发环境,归根到底是显示方式的不同,就好比看视频,可以投屏、可以投影,只要找到显示的窗体类,借助窗体类完成显示即可,这是问题的思路。

        OSG集成到QT中有两种方式:

  • osgQt。在较老版本的osg中自带osgQt源码包,主要适配的是QT4,网址:osgQt
  • osgQOpenGL。需要自行编译适配的osg版本,主要适配QT5。

        本文采用的是第一种方式,采用osgQt的方式,源码集成。为什么采用源码集成而不采用原有的lib文件,是因为方便做二次开发,这在后面用到会逐渐讲到。


二、准备 GraphicsWindowQt

        首先是文件GraphicsWindowQt源码,这里拿到源码需要修改一下,修改项目如下:

  • GraphicsWindowQt.h:
    • #include <QMutex>改为#include <QtCore/QMutex>;
    • 删除 #include <osgQt/Export>;
    • 删除 OSGQT_EXPORT 关键字。
  •  GraphicsWindowQt.cpp:
    • #include <QMutex>改为#include <QtCore/QMutex>;
    • 删除 OSGQT_EXPORT 关键字;
    • 578行:
      getEventQueue()->syncWindowRectangleWithGraphicsContext();

      改为:

      getEventQueue()->getCurrentEventState()->getGraphicsContext();

         如果不想改,我改好的地址:osgQt修改版,提取码:0501。


三、代码集成

  • 新建空白Qt Widgets  Application 项目,新建osgwidget QT设计师类,pro文件中引入opengl:
    QT       += core gui opengl

  • 引入osg相关外部依赖: 
    win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losg
    else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losgd
    else:unix: LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losg
    
    INCLUDEPATH += $$PWD/../../osg/denpendency/osg/include
    DEPENDPATH += $$PWD/../../osg/denpendency/osg/include
    
    win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -lOpenThreads
    else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -lOpenThreadsd
    else:unix: LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -lOpenThreads
    
    INCLUDEPATH += $$PWD/../../osg/denpendency/osg/include
    DEPENDPATH += $$PWD/../../osg/denpendency/osg/include
    
    win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losgGA
    else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losgGAd
    else:unix: LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losgGA
    
    INCLUDEPATH += $$PWD/../../osg/denpendency/osg/include
    DEPENDPATH += $$PWD/../../osg/denpendency/osg/include
    
    win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losgViewer
    else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losgViewerd
    else:unix: LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losgViewer
    
    INCLUDEPATH += $$PWD/../../osg/denpendency/osg/include
    DEPENDPATH += $$PWD/../../osg/denpendency/osg/include
    
    
    win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losgDB
    else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losgDBd
    else:unix: LIBS += -L$$PWD/../../osg/denpendency/osg/lib/ -losgDB
    
    INCLUDEPATH += $$PWD/../../osg/denpendency/osg/include
    DEPENDPATH += $$PWD/../../osg/denpendency/osg/include
    

    这里文件路径替换成你自己的osg文件路径。

  • main.h:

    #include "osgwidget.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        OSGWidget w;
        w.show();
    
        return a.exec();
    }
    

  • osgwidget.h: 
    #ifndef OSGWIDGET_H
    #define OSGWIDGET_H
    
    #include <QWidget>
    #include <QTimer>
    #include <osgDB/ReadFile>
    #include <osg/Group>
    #include <osg/Node>
    #include <osg/Camera>
    #include <osgGA/TrackballManipulator>
    #include <osgGA/StateSetManipulator>
    #include <osgViewer/ViewerEventHandlers>
    
    #include "GraphicsWindowQt.h"	// 这个是本地自己建的。所以用双引号
    #include <QDebug>
    namespace Ui {
    class OSGWidget;
    }
    
    class OSGWidget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit OSGWidget(QWidget *parent = nullptr);
        ~OSGWidget();
    
    private:
        Ui::OSGWidget *ui;
    
    
    public:
        QTimer* m_timer;
        osgViewer::Viewer* viewer;
    
    
    public:
        void initEarth();
    
    public slots:
        void updateFrame();
    
    };
    
    #endif // OSGWIDGET_H
    

  • osgwidget.cpp:
    #include "osgwidget.h"
    #include "ui_osgwidget.h"
    
    OSGWidget::OSGWidget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::OSGWidget)
    {
        ui->setupUi(this);
        m_timer = new QTimer;
        viewer = new osgViewer::Viewer;
        initEarth();
    
    }
    
    OSGWidget::~OSGWidget()
    {
        delete ui;
        //    delete m_timer;
    }
    
    void OSGWidget::initEarth(){
    
        // 设置模型
        osg::ref_ptr<osg::Group> root = new osg::Group;
        // 显示cow.osg 模型
        root->addChild(osgDB::readNodeFile("cow.osg"));
        // 显示 .earth 文件中的地球模型
    //    root->addChild(osgDB::readNodeFile("china-simple-3d.earth"));
    
    
        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
        traits->windowDecoration = false;//声明是否显示窗口的描述
        traits->x = 50;
        traits->y = 50;
        traits->width = 800;
        traits->height = 600;
        traits->doubleBuffer = true;//创建图形窗口是否使用双缓存
    
        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
        camera->setGraphicsContext(new osgQt::GraphicsWindowQt(traits.get()));
        camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.6f, 1.0));
        camera->setViewport(new osg::Viewport(0, 0, 800, 600));
        camera->setProjectionMatrixAsPerspective(30.0, 800.0/600.0, 1.0, 10000.0);
    
    
        //设置渲染器
        viewer->setCamera(camera);
        viewer->setSceneData(root);
        viewer->setCameraManipulator(new osgGA::TrackballManipulator);
        viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);//创建为单线程
        viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
        viewer->addEventHandler(new osgViewer::WindowSizeHandler);
        viewer->addEventHandler(new osgViewer::StatsHandler);
    
    
        osgQt::GraphicsWindowQt* gw = dynamic_cast<osgQt::GraphicsWindowQt*>(camera->getGraphicsContext());
    
        // 这里是直接在ui文件中添加了一个布局,重命名成了horizontalLayoutOSG
        ui->horizontalLayoutOSG->addWidget((QWidget*)(gw->getGLWidget()));
        QObject::connect(m_timer, SIGNAL(timeout()), this, SLOT(updateFrame()));
        m_timer->start(5);	// 每5ms触发一次帧的刷新
    
    
    
    }
    void OSGWidget::updateFrame(){
            viewer->frame();
    }
    
     
  • 将之前修改好的GraphicsWindowQt.h,GraphicsWindowQt.cpp文件引入到项目中即可,如图:

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值