将OSG嵌入到QGraphicsView中,QGraphicsScene没有显示

时间:2018-05-23 01:59:45

标签: qgraphicsview openscenegraph

由于某些原因,我们软件的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中的项目无法显示。

1 个答案:

答案 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();
   }