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.lib与osgQt.lib)‌。

2、OpenGL支持‌

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

    复制代码
    QT += opengl widgets

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

  • 自定义QOpenGLWidget类 ‌

    • 继承QOpenGLWidget并集成osgViewer::Viewer,通过重写initializeGL、paintGL等方法实现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资源‌。

相关推荐
Easyhood4 分钟前
Android 开发入门实践(十四):Compose 副作用入门与四个常用 API
android·开发语言·kotlin·android jetpack·compose
白杨尚青1 小时前
C++进阶篇(六):map 和 set 的模拟实现——用红黑树封装 mymap/myset(迭代器 + operator[])
开发语言·c++·迭代器·stl·set·map·红黑树
饮水桶_T4 小时前
JAVA IO流笔记
开发语言·数据结构·算法
Felven7 小时前
C. Brr Brrr Patapim
c语言·开发语言
路溪非溪8 小时前
python标准库使用总结
开发语言·python
SomeOtherTime10 小时前
Rust 面向对象介绍(AI回答)
开发语言·python·rust
zh_xuan10 小时前
kotlin常见面试题
开发语言·kotlin·面试题
草莓熊Lotso12 小时前
【C++ 基于微服务的即时通讯系统】文件存储子服务实战:UUID生成、文件IO封装与全接口单元测试
开发语言·网络·数据库·c++·微服务·架构·单元测试
huaqianzkh13 小时前
WinForm C#:循环修改控件UI闪烁卡顿?SuspendLayout / ResumeLayout 与 BeginUpdate 优化
开发语言·ui·c#
沐晓时光1 天前
C语言入门,内存函数知识讲解
c语言·开发语言