当前位置: 首页 > article >正文

Qt OpenGL编程常用类

Qt提供了丰富的类来支持OpenGL编程,以下是常用的Qt OpenGL相关类:

一、QOpenGLWidget

功能:用于在 Qt 应用程序中嵌入 OpenGL 渲染的窗口部件。替代了旧版的QGLWidget。提供了OpenGL上下文和渲染表面。
继承关系:QWidget → QOpenGLWidget
属性与方法:

QOpenGLWidget 属性表

属性类型可读可写说明
formatQSurfaceFormat✔️✔️控制 OpenGL 上下文和表面的格式(如版本、采样数等)
textureFormatGLenum✔️✔️在 grabFramebuffer() 中使用的纹理格式(默认为 GL_RGBA
isValidbool✔️检查 OpenGL 上下文和资源是否初始化成功

QOpenGLWidget 核心方法表

1. 初始化与状态控制
方法参数返回值说明
initializeGL()void虚函数,首次显示时调用,用于初始化 OpenGL 资源
paintGL()void虚函数,执行实际的 OpenGL 绘制操作
resizeGL(int w, int h)w: 新宽度
h: 新高度
void虚函数,窗口大小变化时调用,调整视口等
makeCurrent()void将 OpenGL 上下文绑定到当前线程
doneCurrent()void释放当前线程的 OpenGL 上下文
2. 上下文与表面
方法参数返回值说明
context()QOpenGLContext*返回关联的 OpenGL 上下文对象
defaultFramebufferObject()GLuint返回默认帧缓冲对象的 ID
isValid()bool检查上下文和表面是否有效
3. 帧缓冲操作
方法参数返回值说明
grabFramebuffer()QImage捕获当前帧缓冲内容为 QImage
grabFramebuffer(const QRect& rect)rect: 截取区域QImage捕获指定区域的帧缓冲内容
4. 格式设置
方法参数返回值说明
setFormat(const QSurfaceFormat& format)format: 表面格式void设置 OpenGL 上下文和表面的格式
format()QSurfaceFormat返回当前的表面格式
5. 事件处理(覆盖自 QWidget)
方法参数返回值说明
paintEvent(QPaintEvent* e)e: 绘制事件void内部调用 paintGL(),通常不需要直接重写
resizeEvent(QResizeEvent* e)e: 大小事件void内部调用 resizeGL(),通常不需要直接重写

QSurfaceFormat 常用设置(用于 setFormat()

方法参数说明
setVersion(int major, int minor)major: 主版本号
minor: 次版本号
设置 OpenGL 版本(如 3.3)
setProfile(QSurfaceFormat::OpenGLContextProfile profile)CoreProfile/CompatibilityProfile设置核心或兼容模式
setSamples(int numSamples)numSamples: 采样数设置多重采样抗锯齿(MSAA)
setDepthBufferSize(int size)size: 深度缓冲位数设置深度缓冲精度(如 24)

用法示例

// 设置 OpenGL 版本和格式
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setSamples(4); // 4x MSAAQOpenGLWidget widget;
widget.setFormat(format);// 重写虚函数实现渲染
class MyGLWidget : public QOpenGLWidget {
protected:void initializeGL() override {// 初始化 OpenGL 状态和资源initializeOpenGLFunctions();glClearColor(0.2f, 0.3f, 0.3f, 1.0f);}void paintGL() override {// 执行绘制操作glClear(GL_COLOR_BUFFER_BIT);// 绘制代码...}void resizeGL(int w, int h) override {// 调整视口等glViewport(0, 0, w, h);}
};

注意事项

  1. 线程安全:OpenGL 调用必须在拥有上下文的线程中执行(通常为主线程)。

  2. 资源释放:在析构前需调用 doneCurrent() 释放上下文。

  3. 多平台兼容:不同平台对 OpenGL 特性的支持可能不同,需检查 format() 的实际结果。

 

二、QOpenGLWindow

功能:基于窗口的 OpenGL 渲染,比 QOpenGLWidget 更轻量级。适合全屏OpenGL应用。

继承关系:QWindow → QOpenGLWindow
关键特性:

  • 没有 Qt 窗口部件的开销

  • 适合全屏 OpenGL 应用

  • 支持多线程渲染

属性与方法:

QOpenGLWindow 属性表

属性类型可读可写说明
formatQSurfaceFormat✔️✔️控制 OpenGL 上下文和表面的格式(版本、采样等)
isValidbool✔️检查 OpenGL 上下文是否有效
textureFormatGLenum✔️✔️grabFramebuffer() 使用的纹理格式(默认为 GL_RGBA

QOpenGLWindow 核心方法表

1. 初始化与渲染控制
方法参数返回值说明
initializeGL()void虚函数,初始化 OpenGL 资源(首次显示时调用)
paintGL()void虚函数,执行 OpenGL 绘制操作
resizeGL(int w, int h)w: 新宽度
h: 新高度
void虚函数,响应窗口大小变化
makeCurrent()void绑定 OpenGL 上下文到当前线程
doneCurrent()void释放当前线程的上下文
2. 上下文与表面
方法参数返回值说明
context()QOpenGLContext*返回关联的 OpenGL 上下文
defaultFramebufferObject()GLuint返回默认帧缓冲对象的 ID
isValid()bool检查上下文和表面是否有效
3. 帧缓冲操作
方法参数返回值说明
grabFramebuffer()QImage捕获当前帧缓冲为 QImage
grabFramebuffer(const QRect& rect)rect: 截取区域QImage捕获指定区域的帧缓冲
4. 信号
方法参数返回值说明
frameSwapped()void信号,帧交换完成时触发(用于同步)
5. 格式设置
方法参数返回值说明
setFormat(const QSurfaceFormat& format)format: 表面格式void设置 OpenGL 上下文格式
format()QSurfaceFormat返回当前格式

与 QOpenGLWidget 的关键区别

特性QOpenGLWindowQOpenGLWidget
继承关系直接继承 QWindow继承 QWidget
使用场景更适合全屏/独立窗口应用适合嵌入 Qt 部件树的 UI
性能开销更低(无 Qt 部件树开销)略高(需要处理 Qt 事件系统)
多线程支持更友好(可与 QOpenGLContext 灵活配合)需谨慎处理线程绑定
事件处理直接接收原生窗口事件通过 Qt 事件系统处理

用法示例:

class MyGLWindow : public QOpenGLWindow {
protected:void initializeGL() override {initializeOpenGLFunctions();glClearColor(0.1f, 0.2f, 0.4f, 1.0f);}void paintGL() override {glClear(GL_COLOR_BUFFER_BIT);// 绘制代码...}void resizeGL(int w, int h) override {glViewport(0, 0, w, h);}
};int main(int argc, char **argv) {QGuiApplication app(argc, argv);QSurfaceFormat format;format.setVersion(4, 1);format.setProfile(QSurfaceFormat::CoreProfile);MyGLWindow window;window.setFormat(format);window.resize(800, 600);window.show();return app.exec();
}

注意事项

  1. 线程安全:OpenGL 调用必须在拥有上下文的线程中(通常为主线程)。

  2. 资源管理:在析构前需调用 doneCurrent() 释放上下文。

  3. 平台差异:某些 OpenGL 特性可能在不同平台上表现不同,需测试实际支持情况。

三、QOpenGLFunctions

功能:提供跨平台的 OpenGL ES 2.0+ / OpenGL 1.5+ 函数访问(避免直接使用平台相关的函数指针)。

继承关系:无基类(通常通过 多重继承 或 组合 方式使用)。

关键特性:

  • 确保正确的函数指针在不同平台上可用

  • 通常通过继承或组合方式使用

属性与方法: 

QOpenGLFunctions 核心方法表

1. 初始化
方法参数返回值说明
initializeOpenGLFunctions()bool初始化函数指针,必须调用后才能使用其他方法
2. 上下文检查
方法参数返回值说明
hasOpenGLFeature(QOpenGLFunctions::OpenGLFeature feature)feature: 要检查的特性(如Multitexturebool检查当前上下文是否支持特定功能
3. OpenGL 函数封装(常用示例)
方法等效 OpenGL 函数参数说明
glClear(GLbitfield mask)glClearmask: 如 GL_COLOR_BUFFER_BIT
glDrawArrays(GLenum mode, GLint first, GLsizei count)glDrawArraysmodeGL_TRIANGLES 等
glBindBuffer(GLenum target, GLuint buffer)glBindBuffertargetGL_ARRAY_BUFFER 等
glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)glUniformMatrix4fv设置 4x4 矩阵统一变量
glGenTextures(GLsizei n, GLuint* textures)glGenTextures生成纹理 ID
glGetError()glGetError返回 OpenGL 错误代码
4. 扩展功能检查
方法参数返回值说明
isInitialized()bool检查是否已初始化函数指针

OpenGLFeature 枚举(用于功能检查)

枚举值说明
Multitexture是否支持多纹理
Shaders是否支持着色器
Buffers是否支持 VBO
Framebuffers是否支持 FBO
BlendColor是否支持混合颜色

用法示例:

方式1:多重继承
class MyRenderer : public QObject, protected QOpenGLFunctions {
public:MyRenderer() {initializeOpenGLFunctions(); // 必须初始化}void render() {glClear(GL_COLOR_BUFFER_BIT); // 直接调用封装的OpenGL函数glDrawArrays(GL_TRIANGLES, 0, 3);}
};
方式2:组合模式
class MyRenderer {
public:MyRenderer(QOpenGLContext* context) {m_funcs = context->functions();m_funcs->initializeOpenGLFunctions();}void render() {m_funcs->glClear(GL_COLOR_BUFFER_BIT);}private:QOpenGLFunctions* m_funcs;
};

与原生 OpenGL 的对比

场景QOpenGLFunctions
http://www.lryc.cn/news/2395895.html

相关文章:

  • 数据结构 --- 顺序表
  • MySQL高级查询技巧:分组、聚合、子查询与分页【MySQL系列】
  • 无人机多旋翼倾转动力测试系统-适用于(eVTOL开发、缩比模型测试、科研教育)
  • .NET8入门:14.ASP.NET Core MVC进阶——Model
  • latex figure Missing number, treated as zero. <to be read again>
  • java CompletableFuture创建异步任务(Completable异步+ExecutorService线程池)
  • LeetCode 高频 SQL 50 题(基础版)之 【聚合函数】部分
  • 【AI学习】检索增强生成(Retrieval Augmented Generation,RAG)
  • 低成本高效图像生成:GPUGeek和ComfyUI的强强联合
  • 基于Matlab实现卫星轨道模拟仿真
  • 前端使用 spark-md5 实现大文件切片上传
  • 《操作系统真相还原》——进入内核
  • 【QQ音乐】sign签名| data参数 | AES-GCM加密 | webpack(上)
  • 【STM32】按键控制LED 光敏传感器控制蜂鸣器
  • M-OFDM模糊函数原理及仿真
  • 【MySQL】MVCC与Read View
  • 相机--双目立体相机
  • 多目标粒子群优化算法(MOPSO),用于解决无人机三维路径规划问题,Matlab代码实现
  • 工厂模式 vs 策略模式:设计模式中的 “创建者” 与 “决策者”
  • 23、Swift框架微调实战(3)-Qwen2.5-VL-7B LORA微调OCR数据集
  • 37. Sudoku Solver
  • C# Renci.SshNet 登陆 suse配置一粒
  • RV1126-OPENCV 图像叠加
  • 修改 vscode 左侧导航栏的文字大小 (更新版)
  • 从C++编程入手设计模式2——工厂模式
  • 云原生 Cloud Native Build (CNB)使用初体验
  • 格式工厂 FormatFactory v5.20.便携版 ——多功能媒体文件转换工具 长期更新
  • 数据可视化--使用matplotlib绘制高级图表
  • 卷积神经网络(CNN)完全指南:从原理到实战
  • 如何做好一个决策:基于 Excel的决策树+敏感性分析应用