QT编程之OSG

OSG(OpenSceneGraph)与Qt的集成为开发3D可视化应用提供了一个强大的平台。Qt提供了图形用户界面(GUI)工具,而OSG负责高效的3D渲染和场景管理。通过将OSG嵌入Qt应用程序中,开发者可以实现丰富的用户界面与复杂的3D渲染效果的结合。

‌一**、OSGQt库的编译与集成**

  1. 获取osgQt源码

    • 从GitHub仓库(openscenegraph/osgQt)克隆代码,选择与Qt版本匹配的分支(如topic/Qt5)‌。
  2. CMake配置与编译

    • 使用CMake生成工程文件,指定Qt和OSG的安装路径。关键配置项包括:

      复制代码
      -DCMAKE_PREFIX_PATH="Qt安装路径"  
      -DOSG_LIBRARY_RELEASE="OSG库路径" 
    • 编译后,将生成的osgQt库文件(.lib/.dll)复制到OSG安装目录‌。

  3. QT版本兼容性
    推荐使用Qt 5及以上版本,需支持QOpenGLWidget(替代旧版QGLWidget)‌。

二、Qt项目配置

1‌、.pro文件设置

  • 添加OSG和osgQt的头文件路径及库文件依赖:

    复制代码
    INCLUDEPATH += $$OSG_ROOT/include  
    LIBS += -L$$OSG_ROOT/lib -losg -losgDB -losgGA -losgQt
  • 区分Debug/Release版本的库文件(如osgQtd.libosgQt.lib)‌。

2、OpenGL支持

  • 在Qt项目中启用OpenGL模块:

    复制代码
    QT += opengl widgets

三**、OSG嵌入Qt窗口**‌

  • 自定义QOpenGLWidget类

    • 继承QOpenGLWidget并集成osgViewer::Viewer,通过重写initializeGLpaintGL等方法实现OSG渲染循环‌。

      复制代码
      class QtOsgWidget : public QOpenGLWidget {
      protected:
          virtual void initializeGL() override {
              _viewer.setUpViewerAsEmbedded(0, 0, width(), height());
              _viewer.realize();
          }
          virtual void paintGL() override { _viewer.frame(); }
      };
  • 窗口提升与布局

    • 在Qt Designer中拖入QOpenGLWidget控件,右键提升为自定义的QtOsgWidget类‌。
  • 添加键盘事件控制

    • 通过重写 keyPressEvent 实现交互逻辑‌。

      复制代码
      // 在 MainWindow.h 中添加
      protected:
          void keyPressEvent(QKeyEvent *event) override;
      
      // 在 MainWindow.cpp 中实现
      void MainWindow::keyPressEvent(QKeyEvent *event) {
          if (event->key() == Qt::Key_Escape) {
              close(); // 按 ESC 关闭窗口
          }
      }

四、示例代码

复制代码
#pragma once

#include <QMainWindow>
#include <osgQOpenGL/osgQOpenGLWidget>
#include <osg/ref_ptr>
#include <osgGA/TrackballManipulator>

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override = default;

private:
    osgQOpenGLWidget *osgWidget;
};

#include "MainWindow.h"
#include <osgDB/ReadFile>
#include <osg/PositionAttitudeTransform>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
    // 初始化OSG渲染窗口
    osgWidget = new osgQOpenGLWidget(this);
    setCentralWidget(osgWidget);

    // 加载模型(路径支持绝对或相对路径)
    osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("models/cow.osg");
    if (!model) {
        qWarning("模型加载失败!请检查文件路径");
        return;
    }

    // 配置场景和相机
    osgViewer::Viewer *viewer = osgWidget->getOsgViewer();
    viewer->setSceneData(model);
    viewer->setCameraManipulator(new osgGA::TrackballManipulator);
    viewer->getCamera()->setClearColor(osg::Vec4(0.1, 0.1, 0.3, 1.0));  // 深蓝色背景

    // 设置初始视角
    viewer->getCamera()->setViewMatrixAsLookAt(
        osg::Vec3d(10, 10, 10),  // 相机位置
        osg::Vec3d(0, 0, 0),     // 观察点
        osg::Vec3d(0, 0, 1)      // 上方向
    );
}

#include <QApplication>
#include "MainWindow.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    MainWindow window;
    window.resize(1024, 768);
    window.show();
    return app.exec();
}

五、常见问题

  • 若渲染场景比例异常,需手动设置相机投影矩阵的宽高比。

    复制代码
    _viewer.getCamera()->setProjectionMatrixAsPerspective(30.0, static_cast<double>(width())/height(), 1.0, 1000.0);
  • 通过osgGA::EventQueue实现Qt事件(如鼠标、键盘)与OSG的交互‌。

  • 使用setRunFrameScheme控制帧率,避免占用过多CPU资源‌。

相关推荐
代码AC不AC10 分钟前
一篇博客搞定时间复杂度
c语言·开发语言·时间复杂度
月亮月亮要去太阳21 分钟前
python画图文字显示不全+VScode新建jupyter文件
开发语言·python
17´44 分钟前
Qt从入门到入土(十) -数据库操作--SQLITE
数据库·c++·qt·sqlite
邪恶的贝利亚1 小时前
prompt工程起步
开发语言·python·prompt
东雁西飞1 小时前
MATLAB 控制系统设计与仿真 - 26
开发语言·算法·matlab·工业机器人·智能机器人
知行电子-1 小时前
MATLAB R2024b 安装教程
开发语言·matlab·信息可视化
Clockwiseee1 小时前
js原型链污染
开发语言·javascript·原型模式
Biomamba生信基地1 小时前
R语言基础| 高级数据管理
开发语言·r语言
BBbila2 小时前
小程序主包方法迁移到分包-调用策略
开发语言·javascript·微信小程序