由于某些原因,我们软件的QWidget项目被放入QGraphicsScene,并由QGraphicsView渲染。现在我想把open scene嵌入到这个QFraphicsView中,重新实现了QGraphicsView的这个缺陷函数
void OsgQGraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
{
if(painter->paintEngine()->type() != QPaintEgin::OpenGL2)
{
// error manage
}
painter->save();
painter->beginNativePainting();
viewer_->frame();
painter->endNativePainting();
painter->restore();
}
当osg的场景数据不为空时,QGraphicsScene中的项目无法显示。
答案 0 :(得分:1)
OSG使用延迟状态更新消息,OSG不会在帧后重置opengl状态。看到这个论坛http://forum.openscenegraph.org/viewtopic.php?t=6976
所以我们可以在viewer->frame()
之间推送和弹出opengl状态。但解决方案是使用glPushClientAttrib
而不是glPushAttrib
,因为opengl使用客户端/服务器模式,客户端和服务器匹配不同类型的状态,请参阅此论坛:http://www.glprogramming.com/red/chapter07.html。代码现在变成了这样的
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();
}
但这还不够,因为我们恢复了清除qt绘制图形项的opengl状态,但是在qt项目绘制之后osg的opengl状态是脏的。所以我们仍然需要重置osg的opengl状态,Thaks给Sean Spicer http://forum.openscenegraph.org/viewtopic.php?t=2308给出解决方案(它适用于osg3.4和qt5.6.3。我试过osg3.6,它会崩溃):
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();
}