0

我正在做一个QDeclarativeItem使用 OpenGL 调用呈现 3d 内容的自定义 QML 组件。我对 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 纹理处理与我自己隔离的正确方法是什么。有什么建议么?

4

1 回答 1

1

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

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

于 2013-08-23T06:10:34.827 回答