Qt 3D Render

img

QOpenGLWidget

比如我们想要显示一张 QImage

我们可以用 QLabel 直接 setPixmap

也可以用 QGraphicsView 里设置一个 QGraphicsPixmapItem

但假如我们这张图需要不停刷新(30fps)并能随着控件大小缩放时

特别是 4K 分辨率下,性能 就出现了瓶颈

究其原因,还是 CPU 渲染慢,所以我们改用 GPU 来渲染

自然,我们首先想到的是 QOpenGLWidget

下面是个保持图像 400x640 比例的类,m_x、m_y 代表横纵黑边的长度

glwidget.h

我们可以在 Qt Creator 的 UI 设计器里拖出一个 QWidget

然后提升为这个自定义的类 GLWidget 来显示图像


glfw 转 QOpenGLWidget

很多算法相关的同学喜欢用 glfw 去做科研

如果用 QOpenGLWidget 重构下的话

就能获得 Qt 事件、Qt 信号槽等特性,更 方便使用

GLFW 的渲染代码迁到 Qt 的 QOpenGLWidget,核心思路是:

GLFW 负责的“创建窗口/创建上下文/事件循环/交换缓冲”

在 Qt 里分别由 QOpenGLWidget + Qt 事件系统接管;

你只保留 OpenGL 初始化与绘制逻辑

然后搬到 initializeGL() / paintGL() / resizeGL() 里。


1) GLFW 代码里哪些东西要删/替换

A. GLFW 初始化与窗口

GLFW:

Qt:

如果你需要设置 OpenGL 版本/核心模式/多重采样等,用:

(在 QApplication 创建后、创建任何 OpenGL widget 之前设置最好)

B. 主循环 & swap buffers

GLFW:

Qt:

C. 输入回调(键鼠)

GLFW 的 glfwSetKeyCallbackglfwSetCursorPosCallback → Qt 重写事件函数:


2) 你要把 OpenGL 逻辑放进这三个函数


3) 最小可跑的 QOpenGLWidget 模板(等价 GLFW 的结构)

假设你原来用的是现代 OpenGL(VAO/VBO/Shader),建议让类继承 QOpenGLFunctions 来拿到函数指针。

main.cpp 里:


4) 迁移时最容易踩的坑(很重要)

  1. 不要在构造函数里调用 OpenGL API 构造时上下文还没就绪;必须在 initializeGL() 之后才安全。

  2. QOpenGLWidget 默认是“渲染到内部 FBO”再显示 如果你用到 glBindFramebuffer(0) 这类假设“0 就是屏幕”,在 QOpenGLWidget 里可能不成立(因为它在绘制时绑定了自己的 FBO)。

  1. 函数加载器的替换

  1. 线程问题 QOpenGLWidget 的 OpenGL 上下文一般只在 GUI 线程使用;别在别的线程直接调用 GL(除非你很清楚 Qt 的共享上下文/离屏渲染方案)。


5) 你原来的 GLFW 渲染函数怎么“拆”到 Qt

假设你原来:

迁到 Qt:

示例(释放资源):