Hi Robert,

Sorry, I didn't want to just fire a lot of code at you but I guess it would
actually be quite helpful to see the whole thing ;) I've attached the main
viewer code at the end of this email.

At the moment, when mouse moves cause the camera to change the update()
method is called, triggering a paintEvent. Additionally, if the window is
resized a paintEvent will be triggered by QT.

Cheers,

Pete.

P.S. I think you met one of my work collegues (Paul Fotheringham) at the
last Highland Gathering :)

main.cpp

int main( int argc, char **argv )
{
   QApplication a( argc, argv );

   Viewer viewer( 0 );
   viewer.setMaximumSize( 500, 500 );
   viewer.show();

   for ( int i = 1; i < argc; ++i )
   {
      viewer.loadMesh( argv[ i ] );
   }

   return a.exec();
}

Viewer.h

class Viewer : public QGLWidget
{
   Q_OBJECT

public:
   Viewer( QWidget* parent );

   void loadMesh( const QString& );

         osgUtil::SceneView* sceneView()       { return m_scene.get(); }
   const osgUtil::SceneView* sceneView() const { return m_scene.get(); }

protected:
   virtual void initializeGL();
   virtual void resizeGL( int, int );
   //virtual void paintGL();

   virtual void paintEvent            ( QPaintEvent * );
   virtual void keyPressEvent         ( QKeyEvent   * );
   virtual void mousePressEvent       ( QMouseEvent * );
   virtual void mouseReleaseEvent     ( QMouseEvent * );
   virtual void mouseDoubleClickEvent ( QMouseEvent * );
   virtual void mouseMoveEvent        ( QMouseEvent * );

private:
   void updateCamera();
   void zoom  (         int dy );
   void rotate( int dx, int dy );
   void pan   ( int dx, int dy );

   // Data

   // Mouse
   QPoint  m_prevMouse;

   // Camera
   osg::Quat  m_cameraR;
   osg::Vec3  m_orbitCentre;
   float      m_dolly;

   // OSG scene
   osg::ref_ptr< osgUtil::SceneView > m_scene;
};

Viewer.cpp

QGLFormat getPixelFormat()
{
   QGLFormat fmt;
   fmt.setStencil(true);
   return fmt;
}

Viewer::Viewer( QWidget* parent )
   : QGLWidget( getPixelFormat(), parent )
   , m_dolly( 0.2 )
{
   setFocusPolicy( Qt::StrongFocus );
   setAttribute( Qt::WA_NoSystemBackground );
}

void Viewer::loadMesh( const QString& fileName )
{
   qDebug() << "Attempting to load: " << fileName;

   osg::Node*const mesh = osgDB::readNodeFile( fileName.toStdString() );
   if ( !mesh )
   {
       qWarning( "Mesh not loaded!" );
   }

   m_scene->getSceneData()->asGroup()->addChild( mesh );
}

void Viewer::initializeGL()
{
   m_scene = new osgUtil::SceneView;

   m_scene->setDefaults();
   m_scene->setClearColor( osg::Vec4( 247.0 / 255.0, 150.0 / 255.0, 150.0 /
255.0, 1.0) );
   m_scene->getState()->setContextID(
osg::GraphicsContext::createNewContextID() );

   m_scene->setNearFarRatio( 0.02f );

   m_scene->setSceneData( new osg::Group );

   updateCamera();
}

void Viewer::resizeGL( int w, int h)
{
   qDebug() << "ResizeGL: " << w << " " << h;

   m_scene->setViewport( 0, 0, w, h );

   const float VFOV = 30.f;
   const float ASPECT_RATIO = static_cast< float >( w ) /
                              static_cast< float >( h );
   const float Z_N = 0.002f;
   const float Z_F = 1.000f;

   osg::Matrix projection;
   projection.makePerspective( VFOV, ASPECT_RATIO, Z_N, Z_F );

   m_scene->setProjectionMatrix( projection );
}


void Viewer::paintEvent( QPaintEvent * )
{
   qDebug() << "PaintEvent";

   QPainter painter;
   painter.begin(this);
   painter.setRenderHint(QPainter::Antialiasing);
   painter.setBrush( Qt::red );

   // Preserve the current GL state.
   glPushAttrib( GL_ALL_ATTRIB_BITS );
   glMatrixMode(GL_PROJECTION);
   glPushMatrix();
   glMatrixMode(GL_TEXTURE);
   glPushMatrix();
   glMatrixMode(GL_MODELVIEW);
   glPushMatrix();

   // Do our OSG stuff...
   resizeGL( width(), height() );
   updateCamera();

   m_scene->update();
   m_scene->cull();
   m_scene->draw();

   // Restore the old GL state.
   glMatrixMode(GL_TEXTURE);
   glPopMatrix();
   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
   glMatrixMode(GL_MODELVIEW);
   glPopMatrix();
   glPopAttrib();

   // Comment out the following line to make everything work.
   painter.drawLine( 0, 0, width(), height() );

   painter.end();

}

void Viewer::keyPressEvent ( QKeyEvent * k )
{
   switch ( k->key() )
   {
       case Qt::Key_Q:
           QApplication::exit();
           break;
   }
}

void Viewer::mousePressEvent( QMouseEvent * e )
{
   qDebug() << "mousePressEvent:";

   m_prevMouse = e->pos();

   e->accept();
}

void Viewer::mouseReleaseEvent( QMouseEvent * e )
{
   e->accept();
}

void Viewer::mouseDoubleClickEvent( QMouseEvent * e )
{
   e->ignore();
}

void Viewer::mouseMoveEvent( QMouseEvent * e )
{
   const int dx = e->x() - m_prevMouse.x();
   const int dy = e->y() - m_prevMouse.y();

   m_prevMouse = e->pos();

   const bool panFlag    = ( e->buttons() & Qt::MidButton   );
   const bool rotateFlag = ( e->buttons() & Qt::LeftButton  );
   const bool zoomFlag   = ( e->buttons() & Qt::RightButton );


   if ( zoomFlag )
   {
       zoom( dy );
   }
   else if ( rotateFlag )
   {
       rotate( dx, dy );
   }
   else if ( panFlag )
   {
       pan( dx, dy );
   }

   updateCamera();
   update();

   e->accept();
}

void Viewer::updateCamera()
{
   qDebug() << "Update Camera";

   osg::Matrix vm = osg::Matrix::translate( -m_orbitCentre );
   vm *= osg::Matrix::rotate( m_cameraR.conj() );
   vm.setTrans( vm.getTrans() + osg::Vec3( 0., 0., -m_dolly ) );

   m_scene->setViewMatrix( vm );
}

void Viewer::rotate( int dx, int dy )
{
   const double ROTATE_FACTOR = 0.002 * osg::PI;

   const float   cameraYawChange = -dx * ROTATE_FACTOR;
   const float cameraPitchChange = -dy * ROTATE_FACTOR;

   m_cameraR  = osg::Quat( cameraPitchChange, osg::Vec3( 1., 0., 0. ) ) *
m_cameraR;
   m_cameraR *= osg::Quat( cameraYawChange  , osg::Vec3( 0., 1., 0. ) );
}

void Viewer::zoom( int dy )
{
   const float MIN_DOLLY   = 5.e-2f;
   const float MAX_DOLLY   = 2.e+0f;
   const float ZOOM_SCALE = 0.002;

   if ( m_dolly <= MIN_DOLLY && dy < 0 )
   {
       const double PAN_FORWARD_FACTOR = ZOOM_SCALE * MIN_DOLLY;

       const osg::Vec3 cameraZInWorld = m_cameraR * osg::Vec3( 0., 0., 1.
);

       m_orbitCentre += cameraZInWorld * ( dy * PAN_FORWARD_FACTOR );

       m_dolly = MIN_DOLLY;
   }
   else if ( m_dolly >= MAX_DOLLY && dy > 0 )
   {
       m_dolly = MAX_DOLLY;
   }
   else
   {
       const float deltaDolly = dy * ZOOM_SCALE * m_dolly;

       m_dolly += deltaDolly;

       if ( m_dolly > MAX_DOLLY )
           m_dolly  = MAX_DOLLY;
       else if ( m_dolly < MIN_DOLLY )
           m_dolly = MIN_DOLLY;
   }
}

void Viewer::pan( int dx, int dy )
{
   const float PAN_FACTOR = 0.002;

   const osg::Vec3 cameraXInWorld = m_cameraR * osg::Vec3( 1., 0., 0. );
   const osg::Vec3 cameraYInWorld = m_cameraR * osg::Vec3( 0., 1., 0. );

   double deltaPanX = double(  dx ) * PAN_FACTOR * m_dolly;
   m_orbitCentre -= cameraXInWorld * deltaPanX;

   double deltaPanY = double( -dy ) * PAN_FACTOR * m_dolly;
   m_orbitCentre -= cameraYInWorld * deltaPanY;
}

On 6/12/07, Robert Osfield <[EMAIL PROTECTED]> wrote:

Hi Peter,

How do you call the OSG to rendering i.e. your paintGL() method ?  I
can only see set up code in you snippets.

On 6/12/07, Peter O <[EMAIL PROTECTED]> wrote:
> Hi Robert,
>
> Thanks for the reply.
>
> Basically, we have a big QT based application with 2D visuals which
appear
> in normal QT widgets and 3D visuals which we draw using OSG inside
> QGLWidgets. However, ultimately we would like to be able to draw the 2D
> visuals directly over the 3D scene.
>
> We are using QT 4.3.0 and OSG 1.2.
>
> My update camera method just sets the view matrix based on some current
> dolly and rotation parameters.
>
> void Viewer::updateCamera()
> {
>     qDebug() << "Update Camera";
>
>     osg::Matrix vm = osg::Matrix::translate( -orbitCentre );
>     vm *= osg::Matrix::rotate( cameraR.conj() );
>     vm.setTrans( vm.getTrans() + osg::Vec3( 0., 0., -dolly ) );
>
>     m_scene->setViewMatrix( vm );
> }
>
> The resizeGL method updates the viewport and projection matrix.
>
> void Viewer::resizeGL( int w, int h)
> {
>     qDebug() << "ResizeGL: " << w << " " << h;
>
>     m_scene->setViewport( 0, 0, w, h );
>
>     const float VFOV = 30.f;
>     const float ASPECT_RATIO = static_cast< float >( w ) /
>                                static_cast< float >( h );
>      const float Z_N = 0.002f;
>     const float Z_F = 1.000f;
>
>     osg::Matrix projection;
>     projection.makePerspective( VFOV, ASPECT_RATIO, Z_N, Z_F );
>
>     m_scene->setProjectionMatrix( projection );
> }
>
> The m_scene variable in the paint event method is a osgUtil::SceneView
which
> is set up in the initializeGL method.
>
> void Viewer::initializeGL()
> {
>     m_scene = new osgUtil::SceneView;
>
>     m_scene->setDefaults();
>     m_scene->setClearColor( osg::Vec4( 247.0 / 255.0, 150.0 / 255.0,
150.0 /
> 255.0, 1.0) );
>     m_scene->getState()->setContextID(
> osg::GraphicsContext::createNewContextID() );
>
>     m_scene->setNearFarRatio( 0.02f );
>
>     m_scene->setSceneData( new osg::Group );
>
>     updateCamera();
> }
>
> If the drawLine command is commented out of the paintEvent everything
works
> otherwise as I said the 3D mesh only appears to be drawn on the first
paint
> event after it is loaded then on the next paint event it disappears.
>
> The mesh is added to the scene view using:
>
> m_scene->getSceneData()->asGroup()->addChild( mesh );
>
> Thanks for any help / suggestions,
>
> Pete.
>
>
>
> On 6/12/07, Robert Osfield <[EMAIL PROTECTED]> wrote:
> > Hi Peter,
> >
> > What be hidden inside the updateCamera() call???
> >
> > Why use overpainting?  What effect are you after?
> >
> > Robert.
> >
> > On 6/11/07, Peter O <[EMAIL PROTECTED] > wrote:
> > > Hi,
> > >
> > > I'm trying to adapt the QT overpainting example ( drawing 2D
primitives
> and
> > > text over a 3D scene ) to use osg instead of raw openGL. However,
the
> mesh
> > > I'm drawing only appears for the first paintEvent and then
disappears
> from
> > > the view. If I comment out any qpainter draw commands the mesh is
> correctly
> > > redrawn and can be rotated etc.
> > >
> > > Has anyone managed to get overpainting to work with osg?
> > >
> > > Here is my paintEvent method in case anyone can spot any obvious
errors:
> > >
> > > void Viewer::paintEvent( QPaintEvent * )
> > > {
> > >     qDebug() << "PaintEvent";
> > >
> > >     QPainter painter;
> > >     painter.begin(this);
> > >     painter.setRenderHint (QPainter::Antialiasing);
> > >     painter.setBrush( Qt::red );
> > >
> > >     // Preserve the current GL state.
> > >     glPushAttrib( GL_ALL_ATTRIB_BITS );
> > >     glMatrixMode(GL_PROJECTION);
> > >     glPushMatrix();
> > >     glMatrixMode(GL_TEXTURE);
> > >     glPushMatrix();
> > >     glMatrixMode(GL_MODELVIEW);
> > >     glPushMatrix();
> > >
> > >     // Do our OSG stuff...
> > >     /resizeGL( width(), height() );
> > >     updateCamera();
> > >
> > >     m_scene->update();
> > >     m_scene->cull();
> > >     m_scene->draw();
> > >
> > >     // Restore the old GL state.
> > >     glMatrixMode(GL_TEXTURE);
> > >     glPopMatrix();
> > >     glMatrixMode(GL_PROJECTION);
> > >     glPopMatrix();
> > >     glMatrixMode(GL_MODELVIEW);
> > >     glPopMatrix();
> > >     glPopAttrib();
> > >
> > >     painter.drawLine ( 0, 0, width(), height() );
> > >
> > >     painter.end();
> > >
> > > }
> > >
> > > Thanks in advance for any tips or help.
> > >
> > > Pete.
> > >
> > >
> > >
> > > _______________________________________________
> > > osg-users mailing list
> > > [email protected]
> > > http://openscenegraph.net/mailman/listinfo/osg-users
> > > http://www.openscenegraph.org/
> > >
> > _______________________________________________
> > osg-users mailing list
> > [email protected]
> > http://openscenegraph.net/mailman/listinfo/osg-users
> > http://www.openscenegraph.org/
> >
>
>

_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

Reply via email to