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/