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 在调用 paintGLresizeGLinitializeGL 之前自动使上下文处于当前状态(请参阅他们的文档)。

【讨论】:

我不敢相信这是问题所在。我假设上下文将保持最新,除非另一个被绑定。感谢您的快速回复,我会在足够的时间后立即标记为已回答。 @AnthonyQuinn 我不知道 Qt 如何处理 OpenGL 渲染,但在其他框架中使用单独的线程进行渲染是很常见的。如果是这种情况,您将不会在处理鼠标输入的 UI 线程中拥有当前的 OpenGL 上下文。 在这种情况下,Qt 中根本没有线程。一般来说,你不应该假设上下文一直被绑定——如果另一个库/子系统/等使另一个上下文成为当前的呢?在特定情况下,Qt 本身(至少)使 another 上下文绑定在该线程中,因此在mousePressEvent 中,您不知道哪个是当前上下文(如果有)。这就是 makeCurrent 存在的原因。 如何从主 GLWidget 类(我自己的继承自 QOpenGLWidget 和 QOpenGLFunctions 的类)外部调用 OpenGL 函数。我可以使用 QOpenGL::currentContext() 检索当前上下文(以及最后一个要成为当前的上下文),但 makeCurrent 现在需要一个表面参考。我需要一个静态方法来公开这个还是有更合适的方法? 如果你调用currentContext,根据定义,上下文已经是当前的,所以你不需要调用makeCurrent。只需确保当前有 一个 上下文,例如在调用此类 OpenGL 函数(外部)之前调用 yourGlWidget-&gt;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 显示图像的步骤

Qt 从 QOpenGLWidget 访问 MainWindow

如何让 qt 设计器自定义 QOpenGLWidget 小部件背景透明?

带有 QOpenGLWidget 的 Qt 5.5,核心配置文件中的不可见三角形

Qt 5.5 QOpenGLWidget链接错误未链接任何openGL调用