我正在做一个使用OpenGL调用渲染3d内容的自定义QDeclarativeItem
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纹理处理与我自己隔离的正确方法是什么。有什么建议吗?
答案 0 :(得分:1)
问题是由于我们将纹理数据加载到默认纹理对象(QML框架也使用)。解决方案是在我们自己的纹理处理中生成并绑定唯一纹理。对于像我这样的OpenGL初学者来说,这是关于纹理处理的一个很好的教训。
要处理其他OpenGL状态更改,只需在我们的绘图周围添加glPushAttrib(GL_ALL_ATTRIB_BITS)
和glPopAttrib()
即可。