QDeclarativeItem 中的 OpenGL 绘图搞乱了其他 QML 绘图

Posted

技术标签:

【中文标题】QDeclarativeItem 中的 OpenGL 绘图搞乱了其他 QML 绘图【英文标题】:OpenGL drawing in QDeclarativeItem messes up other QML drawing 【发布时间】:2013-07-16 10:18:15 【问题描述】:

我正在做一个自定义的QDeclarativeItem QML 组件,它使用 OpenGL 调用呈现 3d 内容。我对 OpenGL 相当陌生,但经过多次测试和失败后,我已经能够进行绘图工作。不幸的是,我的组件似乎破坏了其他 QML 组件的绘图,例如一些组件根本没有上漆。原因可能是我没有正确重置QPainter 的状态。

这就是我现在的做法:

void CustomItem::paint(QPainter *painter, 
                       const QStyleOptionGraphicsItem *option, QWidget *widget)

    painter->save();
    painter->beginNativePainting();
        // Save all OpenGL states
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glPushAttrib(GL_ALL_ATTRIB_BITS);

        // Avoid overpainting the rest of the QML view.
        glEnable(GL_SCISSOR_TEST);
        int inverted_y = painter->viewport().height() - scenePos().y() - height();
        glScissor(scenePos().x(), inverted_y, width(), height());  

        // Painting is done at this point via our painting framework that
        // is shared by QGLWidgets and QDeclarativeItems.

        // Restore OpenGL states
        glPopAttrib();
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
    painter->endNativePainting();
    painter->restore();

这还不足以隔离 CustomItem 绘画吗?任何线索这里出了什么问题?

更新 1:

所有的绘制都是在 GUI 线程中完成的,所以活动的 OpenGL 上下文应该是正确的。绘画也使用 OpenGL 顶点缓冲区对象 - 可能会导致任何问题..?

更新 2:

好的,问题可能是由纹理处理引起的。如果我禁用自己的纹理处理,QML 会正确呈现。我仍然试图找出将 QML 纹理处理与我自己隔离的正确方法是什么。有什么建议吗?

【问题讨论】:

不,可能是您没有正确恢复的 OpenGL 状态。启用剪刀测试后尝试禁用它。 glPushAttrib(GL_ALL_ATTRIB_BITS) 和 glPopAttrib() 也应该保存和恢复剪刀测试。尽管如此,我也尝试使用 glDisable(GL_SCISSOR_TEST) 禁用剪刀测试,但没有帮助。 我用一些额外的信息更新了这个问题。 再次更新(参见“更新 2”)。 【参考方案1】:

问题是由将我们的纹理数据加载到默认纹理对象引起的,该对象也被 QML 框架使用。解决方案是在我们自己的纹理处理中生成和绑定独特的纹理。对于像我这样的 OpenGL 初学者来说,这是关于纹理处理的精彩课程。

要处理其他 OpenGL 状态更改,在我们的绘图周围添加 glPushAttrib(GL_ALL_ATTRIB_BITS)glPopAttrib() 就足够了。

【讨论】:

以上是关于QDeclarativeItem 中的 OpenGL 绘图搞乱了其他 QML 绘图的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenGL 将图像渲染到子类 QDeclarativeItem

为啥我的 QDeclarativeItem 没有得到任何鼠标/键盘事件?

高级openg 混合,一个完整程序

优化流媒体vbo openg

VIPM 2020 For Windows

Windows 中的声音效果