【发布时间】: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”)。