C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > Qt QOpenGLWindow

Qt QOpenGLWindow 类详解

作者:华丽的周遭

本文主要介绍了Qt QOpenGLWindow 类详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1. 类概述​

QOpenGLWindow是 Qt 5 引入的一个轻量级窗口类,专门用于基于 OpenGL(或 OpenGL ES)的离屏/屏幕渲染。它继承自 QWindow(Qt 的底层窗口抽象)和 QOpenGLFunctions(提供 OpenGL 核心函数接口),结合了窗口管理与 OpenGL 渲染能力,适合需要高性能图形渲染的场景(如流媒体显示、3D 可视化、游戏等)。

在嵌入式Linux项目中,QOpenGLWindow可用于高效渲染视频流(如 YUV/RGB 纹理)、叠加 OSD 信息或实现动态图形效果,尤其适合 ZynqMP 平台的 GPU 加速场景。

2. 继承关系​

QObject → QSurface → QWindow → QOpenGLWindow  
                ↳ QOpenGLFunctions (提供 OpenGL 函数)

3. 核心特性​

3.1 自动管理 OpenGL 上下文​

QOpenGLWindow会自动创建并管理一个 OpenGL 上下文(QOpenGLContext),无需手动调用 QOpenGLContext::create()。上下文的配置(如版本、属性)可通过 setFormat()或构造函数参数指定(例如强制使用 OpenGL ES 3.0 适配嵌入式 GPU)。

// 示例:设置 OpenGL ES 3.0 上下文
QSurfaceFormat format;
format.setVersion(3, 0);
format.setProfile(QSurfaceFormat::CoreProfile); // 核心模式(无兼容旧特性)
format.setRenderableType(QSurfaceFormat::OpenGLES); // 针对嵌入式 GPU
setFormat(format);

3.2 内置渲染循环与双缓冲​

QOpenGLWindow采用双缓冲机制(前缓冲显示、后缓冲渲染),避免画面闪烁。渲染流程由 Qt 的事件循环驱动,通过重写以下虚函数自定义渲染逻辑:

虚函数

作用

initializeGL()

首次显示时调用,初始化 OpenGL 资源(如着色器、缓冲区、纹理)。

resizeGL(int w, int h)

窗口大小变化时调用,调整视口(Viewport)和投影矩阵。

paintGL()

每次需要重绘时调用(如 update()触发),执行实际渲染逻辑。

调用顺序:initializeGL()→ resizeGL(w, h)→ paintGL()(首次显示);后续仅 resizeGL()(窗口缩放)和 paintGL()(重绘)被调用。

3.3 与 QOpenGLWidget 的区别​

QOpenGLWidgetQWidget的子类,适合嵌入传统 Widget 界面;而 QOpenGLWindowQWindow的子类,更轻量、性能更高,适合全屏或独立窗口场景(如主显示窗口)。

特性

QOpenGLWindow

QOpenGLWidget

基类

QWindow

QWidget

适用场景

独立窗口、全屏渲染

嵌入传统 Widget 界面

性能

更高(无 QWidget 额外开销)

略低(需处理 Widget 事件)

多窗口支持

原生支持

需通过 QStackedWidget 等嵌套

4. 关键成员函数​

4.1 上下文与格式​

4.2 渲染控制​

4.3 其他​

5. 使用步骤​

Step 1:继承 QOpenGLWindow 并重写虚函数​

#include <QOpenGLWindow>
#include <QOpenGLFunctions>

class VideoWindow : public QOpenGLWindow, protected QOpenGLFunctions {
    Q_OBJECT
public:
    using QOpenGLWindow::QOpenGLWindow;

protected:
    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;
};

Step 2:初始化 OpenGL 资源(initializeGL)​

在此处加载着色器、创建缓冲区/纹理等。需先调用 initializeOpenGLFunctions()初始化 QOpenGLFunctions的函数指针。

void VideoWindow::initializeGL() {
    initializeOpenGLFunctions(); // 必须调用,绑定 OpenGL 函数
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // 设置清屏颜色

    // 示例:创建纹理(用于显示视频帧)
    glGenTextures(1, &m_textureId);
    glBindTexture(GL_TEXTURE_2D, m_textureId);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

Step 3:处理窗口大小变化(resizeGL)​

调整视口(Viewport)和投影矩阵(如正交投影用于 2D 渲染)。

void VideoWindow::resizeGL(int w, int h) {
    glViewport(0, 0, w, h); // 设置视口为窗口大小
    // 可选:更新投影矩阵(如 2D 坐标映射)
    m_projMatrix.setToIdentity();
    m_projMatrix.ortho(0, w, h, 0, -1, 1); // 正交投影,原点在左上角
}

Step 4:实现渲染逻辑(paintGL)​

在此处绘制图形、纹理或视频帧。

void VideoWindow::paintGL() {
    glClear(GL_COLOR_BUFFER_BIT); // 清屏

    // 示例:绘制一个红色三角形(使用 VBO/VAO)
    glUseProgram(m_shaderProgram);
    glBindVertexArray(m_vao);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    // 示例:绘制视频纹理(假设 m_videoFrame 是 RGB 数据)
    glBindTexture(GL_TEXTURE_2D, m_textureId);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width(), height(), 0, GL_RGB, GL_UNSIGNED_BYTE, m_videoFrame.data());
    // ... 绘制纹理四边形 ...
}

Step 5:更新视频帧(外部调用)​

在流媒体解码线程中,将新的视频帧数据传递给 VideoWindow,并调用 update()触发重绘。

// 外部线程(如 FFmpeg 解码线程)
void DecoderThread::onNewFrame(const QVideoFrame& frame) {
    m_window->updateFrame(frame); // 将帧数据拷贝到 m_videoFrame
    m_window->update(); // 请求重绘
}

6. 注意事项​

6.1 线程安全​

OpenGL 上下文是线程相关的,QOpenGLWindow的渲染操作(如 paintGL()makeCurrent())默认在主线程执行。若需多线程渲染(如后台解码+前台渲染),需通过 QOpenGLContext::create()创建共享上下文,并确保所有 OpenGL 操作在拥有上下文的线程中执行。

6.2 嵌入式平台适配​

6.3 资源释放​

在析构函数中释放 OpenGL 资源(如纹理、缓冲区、着色器程序):

VideoWindow::~VideoWindow() {
    makeCurrent(); // 确保上下文可用
    glDeleteTextures(1, &m_textureId);
    glDeleteProgram(m_shaderProgram);
    doneCurrent();
}

7. 实际应用:视频流显示​

在流媒体项目中,QOpenGLWindow可高效渲染视频流:

8. 总结​

QOpenGLWindow是 Qt 中轻量高效的 OpenGL 渲染窗口类,适合嵌入式场景下的高性能图形需求。通过重写 initializeGL/resizeGL/paintGL,可灵活控制渲染流程,结合 ZynqMP 的 GPU 加速能力,能高效实现流媒体显示、OSD 叠加等功能。

到此这篇关于Qt QOpenGLWindow 类详解的文章就介绍到这了,更多相关Qt QOpenGLWindow 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文