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资源‌。

相关推荐
傻啦嘿哟2 小时前
某招聘平台爬虫:爬取招聘岗位数据,分析各城市薪资水平
开发语言·爬虫·python
2501_933670792 小时前
2026秋招量化分析岗技能栈:Python、SQL、统计建模、回测项目怎么准备
开发语言·python·sql
李少兄3 小时前
JavaScript 数据类型完全指南
开发语言·javascript·ecmascript
Seoyoneh3 小时前
Agentic Workflow编排架构:云客服从“被动响应”迈向“主动执行”的技术实现
java·开发语言·架构
Tangyuewei3 小时前
Java 写 Agent:模型只是组件
java·开发语言
小玮看世界4 小时前
[Python]从合并区间到传感器融合区:合并区间在传感器区域融合的实际落地
开发语言·python
繁星蓝雨5 小时前
C++的设计与演进大纲(如何从C语言一步步成长为C++)
c语言·开发语言·c++·c++历史·c++演进
Evand J5 小时前
【MATLAB例程,图像降噪滤波9】自适应维纳滑动窗口滤波(Wiener)图像降噪、方法对比,有中文注释
开发语言·图像处理·计算机视觉·matlab·滑动窗口·滤波·降噪
杜大哥5 小时前
python程序:如何查看电脑【电池电量的剩余百分比】 和 【是否插入连接着充电器】?
开发语言·python
wuyk5555 小时前
Python网络爬虫入门到实战 第01章:爬虫到底是什么?原理、流程、合法性、风险全解析(零基础必看)
开发语言·爬虫·python