Hi all,

We are creating a simple flipbook animation. There's a node at the top, and
after a certain delta time the child node that's on is turned off, and
the next child is turned on.

If all the child nodes are turned on we get a nice solid 60 FPS. Spin it
around, move it here and there, no change in FPS. So the prolem isn't just
too much data to fit on the card.

When we animate with a delta time of .05 seconds we also get a nice smooth
animation at 60 FPS.

But, here's where things get weird, if we use a delta time of 1 second we
get a sudden and very drastic drop in frame rate. The size of the drop seems
to be related to the amount of data getting turned on and off. Same thing if
you manually single step the animation.

more details...

We've tried this with using both nodemasks and a switch node with no
change. We've seen this with OSG 2.8 and 3.1. We only have Linux boxes with
Nvidia cards, although we've tried many models and many drivers and they all
do it.

Try it yourself! Below is a program that demonstrates the problem. Save it to
jumpy.cpp, build it, and try this:

  ./jumpy .05

hit the S key a couple of times to bring up the stats. Mostly GPU. Then exit
and try:

  ./jumpy 1

hit the S key a couple of times to bring up the stats and notice the U
shaped dips in the top line of the strip chart. Each dip matches a step, and
also corresponds to a flash of yellow Draw activity, then it's back to GPU.

Has anyone else seen a problem like this? Can you give it a try and let us
know if you also see, or don't see, the problem? Maybe with more tests we can
pinpoint the source of the problem.

Many thanks,

John


#include <osg/NodeCallback>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>


class MyUpdateCallback : public osg::NodeCallback
{
public:
    MyUpdateCallback( double deltaFlipTime=0.1 )
      : _deltaFlipTime( deltaFlipTime )
    {}
    virtual void operator()( osg::Node* node, osg::NodeVisitor* nv )
    {
unsigned int intTime( nv->getFrameStamp()->getReferenceTime() / _deltaFlipTime );
        osg::Group* grp( node->asGroup() );
        grp->getChild( 0 )->setNodeMask( intTime & 0x1 );
        grp->getChild( 1 )->setNodeMask( (intTime+1) & 0x1 );
        traverse( node, nv );
    }
protected:
    ~MyUpdateCallback() {}
    double _deltaFlipTime;
};

osg::Node* createFrame( double t )
{
  osg::Geode* geode( new osg::Geode );
geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );

  osg::Geometry* geom( new osg::Geometry );
  geom->setDataVariance( osg::Object::STATIC );
  geom->setUseDisplayList( false );
  geom->setUseVertexBufferObjects( true );
  geode->addDrawable( geom );

  unsigned int w( 121 ), h( 121 ), d( 120 );
  unsigned int totalSamples( w*h*d );
  osg::Vec3Array* v( new osg::Vec3Array );
  osg::Vec4Array* c( new osg::Vec4Array );
  v->resize( totalSamples );
  c->resize( totalSamples );
  unsigned int index( 0 );
  unsigned int wIdx, hIdx, dIdx;
  for( wIdx=0; wIdx<w; ++wIdx )
    {
      for( hIdx=0; hIdx<h; ++hIdx )
        {
          for( dIdx=0; dIdx<d; ++dIdx )
            {
              const double r( ((double)wIdx)/(w-1.) );
              const double g( ((double)hIdx)/(h-1.) );
              const double b( ((double)dIdx)/(d-1.) );
              const double x( r * (double)w - (w*.5) );
              const double y( g * (double)h - (h*.5) );
              const double z( b * (double)d - (d*.5) );
(*v)[ index ].set( x + sin( (x+y+t)*.8 ), y + sin( (x+y+t) ), z + sin( (x+y+t)*1.2 ) );
              (*c)[ index ].set( r, g, b, 1. );
              ++index;
            }
        }
    }
  geom->setVertexArray( v );
  geom->setColorArray( c );
  geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX );

#if 1
osg::DrawElementsUInt* deui( new osg::DrawElementsUInt( GL_POINTS, totalSamples ) );
  for( index=0; index<totalSamples; index++ )
    (*deui)[ index ] = index;
  geom->addPrimitiveSet( deui );
#else
  geom->addPrimitiveSet( new osg::DrawArrays( GL_POINTS, 0, totalSamples ) );
#endif

  return( geode );
}

int main( int argc, char** argv )
{
  double deltaFlipTime( 0.1 );
  if( argc > 1 )
    deltaFlipTime = atof( argv[ 1 ] );

  osg::Group* root( new osg::Group() );
  root->addChild( createFrame( 0.0 ) );
  root->addChild( createFrame( 0.5 ) );

  root->setUpdateCallback( new MyUpdateCallback( deltaFlipTime ) );

  osgViewer::Viewer viewer;
  viewer.addEventHandler( new osgViewer::StatsHandler );
  viewer.addEventHandler( new osgViewer::ThreadingHandler );
  viewer.setSceneData( root );
  viewer.run();
}

_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to