OSG开发笔记(三):OSG使用osgQt嵌入Qt应用程序

若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/94609088

目录

前言

效果

代码

头文件OsgWidget.h

源文件OsgWidget.cpp

入坑

入坑一:“Cannot make QOpenGLContext current in a different thread”

入坑二:加载.osg模型失败

入坑三:显示黑屏、或无法显示模型

工程模板:对应版本号1.2.0


OSG三维开发专栏

OSG开发笔记(一):OSG介绍、编译

OSG开发笔记(二):OSG帮助文档编译

OSG开发笔记(三):OSG使用osgQt嵌入Qt应用程序

OSG开发笔记(四):OSG不使用osgQt重写类嵌入Qt应用程序》:

OSG开发笔记(五):OSG场景理解与基础类概述

OSG开发笔记(六):OSG内存管理

OSG开发笔记(七):OSG复现OpenGL入门示例和OSG坐标系

OSG开发笔记(八):OSG模型文件存储与读取

OSG开发笔记(九):OSG模型的基本操作之添加/删除、显示/隐藏、开关节点开/》:

OSG开发笔记(十):OSG模型的变换之平移、旋转和缩放

OSG开发笔记(十一):OSG渲染状态与2D纹理映射

OSG开发笔记(十二):OSG基本几何图形、内置几何类型

OSG开发笔记(十三):OSG三维纹理映射(体渲染)

OSG开发笔记(十四):OSG交互

OSG开发笔记(十五):OSG光照

OSG开发笔记(十六):OSG视口、相机和视点

OSG开发笔记(十七):OSG中的相机移动

OSG开发笔记(十八):OSG鼠标拾取pick、拽托球体以及多光源

OSG开发笔记(十九):OSG文字显示

OSG开发笔记(二十):OSG使用HUD显示文字

OSG开发笔记(二十一):OSG使用HUD绘制图形以及纹理混合模式

OSG开发笔记(二十二):OSG场景背景

OSG开发笔记(二十三):Qt使用QOpenGLWidget渲染OSG地球仪

OSG开发笔记(二十四):OSG漫游之平移、转向和低抬头

OSG开发笔记(二十五):OSG漫游之CS移动、碰撞检测与跳跃

OSG开发笔记(二十六):OSG漫游之上下楼梯

《OSG开发笔记(二十七):OSG路径漫游之录制播放固定路径动画

《OSG开发笔记(二十八):OSG模型固定路径动画

  持续补充中…

 

        OSG开发笔记(三):OSG使用osgQt嵌入Qt应用程序

 

前言

       前面编译了osg库(没有带任何插件),本章节建立在上一节OSG库基础上(编译了osgQt模块)。

       使用osgQt的弊端是每次不能自定义消息,若要自定义消息则需求修改osgQt中源码,重新编译。

 

效果

       OSG开发笔记(三):OSG使用osgQt嵌入Qt应用程序_第1张图片

       OSG开发笔记(三):OSG使用osgQt嵌入Qt应用程序_第2张图片

       OSG开发笔记(三):OSG使用osgQt嵌入Qt应用程序_第3张图片

 

代码

      OSG开发笔记(三):OSG使用osgQt嵌入Qt应用程序_第4张图片

头文件OsgWidget.h

#ifndef OSGWIDGET_H
#define OSGWIDGET_H

#include 
#include 
#include 

namespace Ui {
class OsgWidget;
}

class OsgWidget : public QWidget
{
    Q_OBJECT

public:
    explicit OsgWidget(QWidget *parent = 0);

protected:
    void resizeEvent(QResizeEvent *event);

protected:
    void initOsg();
    void loadOsg(QString osgFilePath);

private slots:
    void on_pushButton_open_clicked();

private:
    Ui::OsgWidget *ui;

private:
    osg::ref_ptr _pViewer;
    osg::ref_ptr _pViewport;
    osgQt::GLWidget * _pGLWidget;
    osgQt::GraphicsWindowQt* _pGraphicsWindowQt;
};

#endif // OSGWIDGET_H

源文件OsgWidget.cpp

#include "OsgWidget.h"
#include "ui_OsgWidget.h"

#include 
#include 
#include 
#include 
#include 
#include 

#include "define.h"
#include 

OsgWidget::OsgWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::OsgWidget),
    _pViewer(0),
    _pGLWidget(0),
    _pGraphicsWindowQt(0)
{
    ui->setupUi(this);
    QString version = "V1.2.0";
    setWindowTitle(QString("OsgDemo %1(作者:红模仿 QQ21497936 博客地址: blog.csdn.net/qq21497936)").arg(version));
    initOsg();
}

void OsgWidget::resizeEvent(QResizeEvent *event)
{
    if(_pGLWidget != 0)
    {
        _pGLWidget->move(0,0);
        _pGLWidget->resize(rect().size());
    }
}

void OsgWidget::initOsg()
{
    // 使用osgQt步骤示例
    // 定义
//    osg::ref_ptr _pViewer;
//    osg::ref_ptr _pViewport;
//    osgQt::GLWidget * _pGLWidget;
//    osgQt::GraphicsWindowQt* _pGraphicsWindowQt;
    // 步骤一:初始化qt窗口系统
    osgQt::initQtWindowingSystem();
    // 步骤二:创建视口
    _pViewer = new osgViewer::Viewer;
    // 步骤三:视口设为单线程(Qt5必须)
    _pViewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
    // 步骤四:对视图的操作,必须,否则无法显示黑屏
    _pViewer->setCameraManipulator(new osgGA::TrackballManipulator);
    // 步骤五:视口操作
    _pViewer->setSceneData(osgDB::readNodeFile("glider.osg"));
    // 步骤六:设置osgQt视口(一个应用程序用opgQt同一时刻只能设置一个视口)
    osgQt::setViewer(_pViewer.get());
    // 步骤七:创建窗口(2个都要,只创建osgQt::GLWidget会挂掉)
//    _pGLWidget = new osgQt::GLWidget();
    _pGLWidget = new osgQt::GLWidget(this);
    _pGraphicsWindowQt = new osgQt::GraphicsWindowQt(_pGLWidget);
    // 步骤八:设置视口
    _pViewport = new osg::Viewport(0, 0, _pGLWidget->width(), _pGLWidget->height());
    // 步骤九:设置摄像机视口范围,未设置不会显示,即窗口一片黑(刷新窗口但没有内容显示)
    _pViewer->getCamera()->setViewport(_pViewport);
    // 步骤十:设置刷新显示内容,未设置不会显示,即一片白(不会刷新窗口)
    _pViewer->getCamera()->setGraphicsContext(_pGraphicsWindowQt);
    // 步骤十一:显示
    _pGLWidget->show();
    _pGLWidget->lower();
}

void OsgWidget::loadOsg(QString osgFilePath)
{
    _pViewer->setSceneData(osgDB::readNodeFile(osgFilePath.toStdString()));
}

void OsgWidget::on_pushButton_open_clicked()
{
    QString filePath = QFileDialog::getOpenFileName(0, "打开...");
    if(!filePath.isEmpty())
    {
        _pViewer->setSceneData(osgDB::readNodeFile(filePath.toStdString()));
    }
}

 

入坑

入坑一:“Cannot make QOpenGLContext current in a different thread”

        

解决方法:

         渲染qt5限制线程必须为单线程,添加代码

// 步骤三:视口设为单线程(Qt5必须)

_pViewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);

入坑二:加载.osg模型失败

解决方法:

         不仅仅要拷贝dll到运行目录,还需要将插件也要拷贝过去。

入坑三:显示黑屏、或无法显示模型

// 步骤四:对视图的操作,必须,否则无法显示黑屏
_pViewer->setCameraManipulator(new osgGA::TrackballManipulator);
// 步骤九:设置摄像机视口范围,未设置不会显示,即窗口一片黑(刷新窗口但没有内容显示)
_pViewer->getCamera()->setViewport(_pViewport);
// 步骤十:设置刷新显示内容,未设置不会显示,即一片白(不会刷新窗口)
_pViewer->getCamera()->setGraphicsContext(_pGraphicsWindowQt);

 

工程模板:对应版本号1.2.0

        对应版本号v1.2.0

 

原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/94609088

你可能感兴趣的:(Qt开发专栏,OSG,OSG三维开发专栏)