OSG uses lazy state updating mesans that the OSG will not reset the opengl state after frame. see this forum http://forum.openscenegraph.org/viewtopic.php?t=6976
so we can push and pop the opengl state between viewer->frame()
. But The solution is to use glPushClientAttrib
rather than glPushAttrib
, as opengl use client/server mode, the client and server matins different types of state see this forum: http://www.glprogramming.com/red/chapter07.html. The code now become like this
void OsgQGraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
{
if(painter->paintEngine()->type() != QPaintEgin::OpenGL2)
{
// error manage
}
painter->save();
painter->beginNativePainting();
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
viewer_->frame();
glPopClientAttrib();
painter->endNativePainting();
painter->restore();
}
but this is not enough, as we restore clear the opengl state for qt to draw graphics items, but the opengl state for osg is dirty after the qt items's drawed. So we still have to reset the opengl state for osg, Thaks to Sean Spicer http://forum.openscenegraph.org/viewtopic.php?t=2308 give the solution(It works on osg3.4 with qt5.6.3. I tried osg3.6, it will crash):
void OsgQGraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
{
if(painter->paintEngine()->type() != QPaintEgin::OpenGL2)
{
// error manage
}
painter->save();
painter->beginNativePainting();
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
osg::State *state = viewer_->getCamera()->getGraphicsContext()->getState();
state->reset();
state->apply(last_stateset);
viewer_->frame();
viewer_->getCamera()->getGraphicsContext()->getState()->captureCurrentState(*last_stateset);
// Pop matricies.
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_TEXTURE);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
glPopClientAttrib();
painter->endNativePainting(); // reset opengl state for qt
painter->restore();
}