Qt QOpenGLWidget glClearColor 无法正常工作
Posted
技术标签:
【中文标题】Qt QOpenGLWidget glClearColor 无法正常工作【英文标题】:Qt QOpenGLWidget glClearColor not functioning correctly 【发布时间】:2015-10-25 15:52:42 【问题描述】:从paintGL() 之外的各个地方调用glClearColor 时我遇到了一个小问题。目的是使用户能够即时设置清除颜色,但这不会按计划工作,除非在paintGL中的每一帧都调用glClearColor。
目标:
void GLWidget::mousePressEvent(QMouseEvent *event)
m_lastPos = event->pos();
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); //<-- Doesn't change clear colour
非最佳解决方法:
void GLWidget::mousePressEvent(QMouseEvent *event)
m_lastPos = event->pos();
r = 1.0f;
g = 0.0f;
b = 0.0f;
a = 1.0f;
void GLWidget::paintGL()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glClearColor(r, g, b, a);
...
我认为这与 Qt 如何交换缓冲区和更新屏幕有关,但尚不清楚究竟是什么原因造成的。任何想法都会很棒,谢谢。
【问题讨论】:
【参考方案1】:我认为这与 Qt 如何交换缓冲区和更新屏幕有关,但尚不清楚究竟是什么原因造成的。任何想法都会很棒,谢谢。
错了,它与在没有 OpenGL 上下文绑定的情况下进行 OpenGL 调用有关。 在进行任何 OpenGL 调用之前,您必须调用 makeCurrent
。
那为什么它在paintGL
中有效呢?因为 Qt 在调用 paintGL
、resizeGL
和 initializeGL
之前自动使上下文处于当前状态(请参阅他们的文档)。
【讨论】:
我不敢相信这是问题所在。我假设上下文将保持最新,除非另一个被绑定。感谢您的快速回复,我会在足够的时间后立即标记为已回答。 @AnthonyQuinn 我不知道 Qt 如何处理 OpenGL 渲染,但在其他框架中使用单独的线程进行渲染是很常见的。如果是这种情况,您将不会在处理鼠标输入的 UI 线程中拥有当前的 OpenGL 上下文。 在这种情况下,Qt 中根本没有线程。一般来说,你不应该假设上下文一直被绑定——如果另一个库/子系统/等使另一个上下文成为当前的呢?在特定情况下,Qt 本身(至少)使 another 上下文绑定在该线程中,因此在mousePressEvent
中,您不知道哪个是当前上下文(如果有)。这就是 makeCurrent
存在的原因。
如何从主 GLWidget 类(我自己的继承自 QOpenGLWidget 和 QOpenGLFunctions 的类)外部调用 OpenGL 函数。我可以使用 QOpenGL::currentContext() 检索当前上下文(以及最后一个要成为当前的上下文),但 makeCurrent 现在需要一个表面参考。我需要一个静态方法来公开这个还是有更合适的方法?
如果你调用currentContext
,根据定义,上下文已经是当前的,所以你不需要调用makeCurrent
。只需确保当前有 一个 上下文,例如在调用此类 OpenGL 函数(外部)之前调用 yourGlWidget->makeCurrent()
。【参考方案2】:
我不认为@peppe 回答正确,因为 You don't need to call makeCurrent() since Qt have already to
在我看来,您真正需要的只是在mousePressEvent
中拨打update()
。
If you wan't to call paintGL() to update, what you need is just to call update()
另外,您应该知道,在glClearColor()
中,您只在 OpenGL 状态机上设置了 clearColor 属性。 glClear(GL_COLOR_BUFFER_BIT)
是真正清除颜色缓冲区的函数。所以你应该在调用glClear()
之前通过glClearColor()
设置clearColor。
如果我是你,代码会是这样的:
void GLWidget::mousePressEvent(QMouseEvent *event)
m_lastPos = event->pos();
r = 1.0f;
g = 0.0f;
b = 0.0f;
a = 1.0f;
update();
void GLWidget::paintGL()
glClearColor(r, g, b, a);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
【讨论】:
以上是关于Qt QOpenGLWidget glClearColor 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
Qt OpenGL (QOpenGLWidget) - 简单三角形
Qt 从 QOpenGLWidget 访问 MainWindow
如何让 qt 设计器自定义 QOpenGLWidget 小部件背景透明?