OpenGL drawing in QDeclarativeItem messes up other QML drawing
I'm doing a custom QDeclarativeItem
QML component that renders 3d content using OpenGL calls. I'm rather new to OpenGL but after many tests and fails I've been able to get the drawing work. Unfortunately my component seems to break the drawing of the other QML components, eg some components do not get painted at all. The reason is probably that I don't reset QPainter
's state correctly.
This is how I do it now:
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();
}
Shouldn't this be enough to isolate CustomItem painting..? Any clues what is going wrong here?
Update 1:
All painting is done in GUI thread, so the active OpenGL context should be the correct one. Painting uses also OpenGL vertex buffer objects - might that cause any problems..?
Update 2:
OK, the problem is probably caused by texture handling. If I disable my own texture handling, QML is rendered correctly. I still try to find out, what is the correct way to isolate QML texture handling from my own. Any suggestions?
The problem was caused from loading our texture data to the default texture object, which was also used by QML framework. Solution was to generate and bind unique textures in our own texture handling. For a OpenGL beginner like me this was a great lesson about texture handling.
To handle other OpenGL state changes, it was sufficient to add glPushAttrib(GL_ALL_ATTRIB_BITS)
and glPopAttrib()
around our drawing.
上一篇: 我的场景颠倒了