I'm working on an application which uses osgEarth to display terrain databases to users. I need the application to use as little CPU time as possible while still providing good user interaction, so I have set my viewer up so that it only renders when necessary. I keep a loop running that does the event and update traversals, but the renderingTraversals are only done when requestRedraw or requestContinuousUpdate have been called. This seems to work fine and to the user it generally beahves the same as when the scene is continuously rendered. However, when viewing the high detail levels it database pager often gets stuck in a loop when it keeps reloading a set of tiles over and over. You see the tiles alternately go blurry and then sharp again as the continously reload.
I don't know what is causing this, but if I switch to continuous render, so that every event and update traversal is followed by a render, the problem does not occur. It seems to happen most often loading earth files with high-res data, like the yahoo or google test files, and then moving the camera around at the high detail levels. Unfortunately, I can't seem to replicate the problem with an animation path. I have attached a simple viewer I created that implements the rendering method I described above. The important code is in the viewer's frame function. I've pasted it below in case anyone can tell at a glance what I'm doing wrong. If someone who knows the database pager well could take a look at this I would really appreciate it. Thanks, Evan advance(simulationTime); eventTraversal(); // If the database pager is going to update the scene the render flag is // set so that the updates show up if(getDatabasePager()->requiresUpdateSceneGraph()) needsRender = true; updateTraversal(); if(needsRender || continuousUpdate) { renderingTraversals(); needsRender = false; }
// RenderOnDemand.cpp : Defines the entry point for the console application. // #include <osgViewer/viewer> #include <osgDB/ReadFile> #include <osgViewer/ViewerEventHandlers> #include <osgGA/TrackballManipulator> #include <osgGA/FlightManipulator> #include <osgGA/DriveManipulator> #include <osgGA/KeySwitchMatrixManipulator> #include <osgGA/StateSetManipulator> #include <osgGA/TerrainManipulator> #include <OpenThreads/Thread> // The stats handler has to be modified to request continuous updates // when stats are being displayed class MyStats : public osgViewer::StatsHandler { protected: ~MyStats() {} int keyPresses; public: MyStats() : osgViewer::StatsHandler(), keyPresses(0) {} virtual bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa) { if( ea.getEventType() != osgGA::GUIEventAdapter::KEYDOWN ) return false; int key = ea.getKey(); if(key == -1) return false; if(key == 's') { if(keyPresses < 4) { aa.requestContinuousUpdate(true); keyPresses++; } else { keyPresses = 0; aa.requestContinuousUpdate(false); aa.requestRedraw(); } return osgViewer::StatsHandler::handle(ea, aa); } return false; } }; class MyViewer : public osgViewer::Viewer { public: MyViewer() : osgViewer::Viewer(), needsRender(true), continuousUpdate(false) {} MyViewer(osg::ArgumentParser &arguments) : osgViewer::Viewer(arguments), needsRender(true), continuousUpdate(false) {} virtual void requestRedraw() { needsRender = true; } virtual void requestContinuousUpdate(bool needed=true) { continuousUpdate = needed; } virtual int run() { // From osgViewer::Viewer if (!getCameraManipulator() && getCamera()->getAllowEventFocus()) { setCameraManipulator(new osgGA::TrackballManipulator); } addEventHandler(new MyStats()); setReleaseContextAtEndOfFrameHint(false); // From osgViewer::ViewerBase if (!isRealized()) { realize(); } while (!done()) { frame(); //Sleep for 10 miliseconds OpenThreads::Thread::microSleep(10000); } return 0; } virtual void frame(double simulationTime=USE_REFERENCE_TIME) { if (_done) return; // osg::notify(osg::NOTICE)<<std::endl<<"CompositeViewer::frame()"<<std::endl<<std::endl; if (_firstFrame) { viewerInit(); if (!isRealized()) { realize(); } _firstFrame = false; } advance(simulationTime); eventTraversal(); // If the database pager is going to update the scene the render flag is // set so that the updates show up if(getDatabasePager()->requiresUpdateSceneGraph()) needsRender = true; updateTraversal(); if(needsRender || continuousUpdate) { renderingTraversals(); needsRender = false; } } protected: ~MyViewer() {} bool needsRender; bool continuousUpdate; }; int main(int argc, char* argv[]) { osg::ArgumentParser arguments(&argc,argv); osg::ref_ptr<MyViewer> viewer = new MyViewer(arguments); // set up the camera manipulators. { osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator; keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() ); keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() ); keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() ); keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() ); viewer->setCameraManipulator( keyswitchManipulator.get() ); } osg::ref_ptr<osg::Node> node = osgDB::readNodeFiles(arguments); if(node.valid()) { viewer->setSceneData(node); viewer->run(); } return 0; }
_______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org