c++ - Multiple Qt widgets depicting different OpenSceneGraph nodes without performance loss -


we facing following problem: have application needs display multitude of separate openscenegraph scenes in different qt widgets. example, might have 1 qt widget depicting sphere, while widget depicts icosahedron. since using openscenegraph 3.0.1, followed osgviewerqt example official documentation implementing this.

the example code uses qtimer in order force updates viewer widget:

    connect( &_timer, signal(timeout()), this, slot(update()) );     _timer.start( 10 ); 

the problems begin when want create , show multiple widgets. since each widget comes own timer, performance rapidly decreases number of open widgets. not interaction osg widgets slow, interaction other qt widgets noticeably lags. halfway recent quad-core system overwhelmed when approximately 5 windows open. issue definitely not related our graphics hardware. other applications may render larger scenes (blender, meshlab etc.) without negative performance impact.

so, summarize: best way of creating multiple qt widgets showing different openscenegraph scenes without performance impact?

what tried:

  • we considered using single osgviewer::compositeviewer rendering all scene objects. however, discarded idea because make interactions single widget complicated.
  • we tried putting rendering portion of each osgviewer::compositeviewer in separate thread detailed osgqtwidgets example.

our second try (using threads) looked this:

   class viewerframethread : public openthreads::thread     {         public:             viewerframethread(osgviewer::viewerbase* viewerbase):                 _viewerbase(viewerbase) {}              ~viewerframethread()             {                 cancel();                 while(isrunning())                 {                     openthreads::thread::yieldcurrentthread();                 }             }              int cancel()             {                 _viewerbase->setdone(true);                 return 0;             }              void run()             {                 int result = _viewerbase->run();             }              osg::ref_ptr<osgviewer::viewerbase> _viewerbase;     }; 

however, also resulted in remarkable performance decrease. each thread still requires cpu time (which not surprising basic interaction still handled timer). advantage of approach @ least interaction other qt widgets remain possible.

the ideal solution widget fires redraw requests whenever user interacts it, example clicking, double-clicking, scrolling etc. more precisely, widget should remain idle until there need update. akin possible at all? welcome suggestions.

having tried out several models problem, happy report found 1 working perfectly. using qthread (similar thread described above) wraps osgviewer::viewerbase object , calls viewer->run().

the trick keep cpu usage low force openscenegraph render on demand only. having tried out various options, found following 2 settings work best:

viewer->setrunframescheme( osgviewer::viewerbase::on_demand ); viewer->setthreadingmodel( osgviewer::viewerbase::culldrawthreadpercontext ); 

a viewer modified not use spurious cpu cycles continuous updates while still using multiple threads culling , drawing. other threading models might of course perform better in cases, me, sufficient.

if 1 else attempts similar solution, warned operations require explicit redraw requests. example, when handling interactions osg objects or when writing own cameramanipulator class, doesn't hurt call viewer->requestredraw() after changing viewer settings. else, viewer refresh when widget requires repaint.

in short, here's learned:

  • don't use timers rendering
  • don't give on multiple threads yet
  • nothing beats reading source code (the official osg examples scarce on details, source never lies...)

Comments

Popular posts from this blog

java - Play! framework 2.0: How to display multiple image? -

gmail - Is there any documentation for read-only access to the Google Contacts API? -

php - Controller/JToolBar not working in Joomla 2.5 -