Qt中opengl使用swapBuffers()函数报错解决办法

swapBuffers():qt文档中方的翻译:用屏幕外缓冲区交换屏幕内容。 仅当窗口小部件的格式指定双缓冲模式时,此方法才有效。
通常,不需要显式调用此函数,因为它是在每个小部件重新绘制后(即每次执行paintGL()之后)自动完成的。

我是在线程中使用swapBuffers时候报下面这个错。
报错:QOpenGLContext::swapBuffers() called with non-exposed window,behavior is undefined;
翻译一下:QOpenGLContext :: swapBuffers()用未暴露的窗口调用,行为未定义;
我的理解是,在要使用opengl绘制图像时,需要的环境还没准备好。经过各种资料查询后。使用下面的方法可以解决。先获取关联的QWindow,判断是否可视进入。

auto *w = openglWidget->windowHandle();
if(w->isExposed())
   openglWidget->swapBuffers();`

windowHandle()函数:如果这是本机窗口小部件,则返回关联的QWindow。 否则返回null。本机窗口小部件包括顶级窗口小部件,QGLWidget和在其上调用winId()的子窗口小部件。
isExposed()函数:返回此窗口是否在窗口系统中公开。
当窗口未显示时,应用程序将显示该窗口,但窗口系统中仍未显示该窗口,因此应用程序应尽量减少渲染和其他图形活动。
我的理解是:这个窗口是否已经可视,可视就表明环境已经准备好,此时调用swapBuffers()就不会报错

### 在 Qt使用 OpenGL 进行图形编程 在 Qt 中集成 OpenGL 可以为开发者提供一种高效的方式来进行复杂的图形渲染[^1]。为了利用这种组合的优势,开发者通常会遵循特定的方法来设置项目并编写代码。 #### 创建 QOpenGLWidget 子类 对于希望在其应用程序中嵌入 OpenGL 渲染的应用程序来说,继承 `QOpenGLWidget` 是最常用的做法之一。这个类提供了用于初始化、绘制以及清理资源的虚函数重载接口。通过子类化此组件,可以轻松地将自定义绘图逻辑融入到基于 Qt 的界面框架之中。 ```cpp class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT public: explicit MyGLWidget(QWidget *parent = nullptr); protected: void initializeGL() override; void resizeGL(int w, int h) override; void paintGL() override; }; ``` #### 初始化 OpenGL 上下文与资源 当创建了一个新的窗口部件实例时,系统会调用 `initializeGL()` 方法,在这里应该完成所有必要的初始化工作,比如加载着色器程序或者配置缓冲区对象等操作。这一步骤确保每次新场景启动前都处于已知状态,并准备好执行后续的任务。 ```cpp void MyGLWidget::initializeGL() { initializeOpenGLFunctions(); // 设置清除颜色和其他初始参数... } ``` #### 处理视口调整事件 每当窗口大小发生变化时都会触发 `resizeGL()` 函数;因此可以在该处更新投影矩阵或其他依赖于屏幕尺寸的数据结构以适应不同的显示比例或分辨率变化情况下的正确呈现效果。 ```cpp void MyGLWidget::resizeGL(int width, int height) { glViewport(0, 0, width, qMax(height, 1)); } ``` #### 实现核心渲染循环 最后也是最重要的部分就是实现 `paintGL()` ,它负责所有的实际绘画指令——从简单的几何形状到复杂的纹理映射都可以在此阶段完成。这一过程可能涉及到多个步骤,例如绑定顶点数组、激活纹理单元或是提交变换后的坐标给 GPU 去处理等等。 ```cpp void MyGLWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 绘制命令... swapBuffers(); // 如果不是双缓存模式则不需要显式交换 } ``` 上述内容展示了如何在 Qt 应用程序内部有效地运用 OpenGL 技术进行图形开发的基础流程。当然还有许多高级特性等待探索,如多线程优化、阴影贴图技术等,这些都需要更深入的学习和实践才能掌握。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值