1

For some reasons, our software's QWidget items are put into a QGraphicsScene, and render by QGraphicsView. Now I tring to embed open scenegraph into this QFraphicsView, Reimplemented the QGraphicsView's drawbackground function like this

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

when osg's scene data is not empty, the items in QGraphicsScene unable to display.

1 Answers1

2

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();
   }
  • That helped, thank you! We are using QQuickFramebufferObject. We already had the "last_stateset" stuff but still random crashes. Now it seams to run stable with the additional push/pop calls. – palfi Aug 20 '19 at 13:51