Added Viewer::setEndBarrierPosition method, change Viewer::setKeySetsDone(int) to setKeyEventSetDone(int),

added support for toggling threading model and end barrier position into osgviewer
This commit is contained in:
Robert Osfield
2007-01-12 21:05:39 +00:00
parent 5a515914bc
commit 694b304c00
5 changed files with 199 additions and 27 deletions

View File

@@ -29,7 +29,6 @@ int main_osgProducer(osg::ArgumentParser& arguments)
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display command line parameters");
arguments.getApplicationUsage()->addCommandLineOption("--help-env","Display environmental variables available");
arguments.getApplicationUsage()->addCommandLineOption("--help-keys","Display keyboard & mouse bindings available");
arguments.getApplicationUsage()->addCommandLineOption("--help-all","Display all command line, env vars and keyboard & mouse bindings.");
@@ -140,8 +139,101 @@ int main_osgProducer(osg::ArgumentParser& arguments)
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
class ThreadingHandler : public osgGA::GUIEventHandler
{
public:
ThreadingHandler() {}
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
if (!viewer) return false;
switch(ea.getEventType())
{
case(osgGA::GUIEventAdapter::KEYUP):
{
if (ea.getKey()=='m')
{
switch(viewer->getThreadingModel())
{
case(osgViewer::Viewer::SingleThreaded):
viewer->setThreadingModel(osgViewer::Viewer::ThreadPerContext);
osg::notify(osg::NOTICE)<<"Threading model 'ThreadPerContext' selected."<<std::endl;
break;
case(osgViewer::Viewer::ThreadPerContext):
viewer->setThreadingModel(osgViewer::Viewer::ThreadPerCamera);
osg::notify(osg::NOTICE)<<"Threading model 'ThreadPerCamera' selected."<<std::endl;
break;
case(osgViewer::Viewer::ThreadPerCamera):
viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
osg::notify(osg::NOTICE)<<"Threading model 'SingleTheaded' selected."<<std::endl;
break;
}
return true;
}
if (ea.getKey()=='e')
{
switch(viewer->getEndBarrierPosition())
{
case(osgViewer::Viewer::BeforeSwapBuffers):
viewer->setEndBarrierPosition(osgViewer::Viewer::AfterSwapBuffers);
osg::notify(osg::NOTICE)<<"Threading model 'AfterSwapBuffers' selected."<<std::endl;
break;
case(osgViewer::Viewer::AfterSwapBuffers):
viewer->setEndBarrierPosition(osgViewer::Viewer::BeforeSwapBuffers);
osg::notify(osg::NOTICE)<<"Threading model 'BeforeSwapBuffers' selected."<<std::endl;
break;
}
return true;
}
}
default: break;
}
return false;
}
bool _done;
};
int main_osgViewer(osg::ArgumentParser& arguments)
{
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models.");
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
arguments.getApplicationUsage()->addCommandLineOption("--image <filename>","Load an image and render it on a quad");
arguments.getApplicationUsage()->addCommandLineOption("--dem <filename>","Load an image/DEM and render it on a HeightField");
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display command line parameters");
arguments.getApplicationUsage()->addCommandLineOption("--help-env","Display environmental variables available");
arguments.getApplicationUsage()->addCommandLineOption("--help-keys","Display keyboard & mouse bindings available");
arguments.getApplicationUsage()->addCommandLineOption("--help-all","Display all command line, env vars and keyboard & mouse bindings.");
// if user request help write it out to cout.
bool helpAll = arguments.read("--help-all");
unsigned int helpType = ((helpAll || arguments.read("-h") || arguments.read("--help"))? osg::ApplicationUsage::COMMAND_LINE_OPTION : 0 ) |
((helpAll || arguments.read("--help-env"))? osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE : 0 ) |
((helpAll || arguments.read("--help-keys"))? osg::ApplicationUsage::KEYBOARD_MOUSE_BINDING : 0 );
if (helpType)
{
arguments.getApplicationUsage()->write(std::cout, helpType);
return 1;
}
// report any errors if they have occurred when parsing the program arguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
return 1;
}
if (arguments.argc()<=1)
{
arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
return 1;
}
osgViewer::Viewer viewer;
// set up the camera manipulators.
@@ -176,7 +268,35 @@ int main_osgViewer(osg::ArgumentParser& arguments)
viewer.addEventHandler( statesetManipulator.get() );
}
viewer.setSceneData( osgDB::readNodeFiles(arguments) );
// add the thread model handler
{
viewer.addEventHandler(new ThreadingHandler);
}
// load the data
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
if (!loadedModel)
{
std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
return 1;
}
// any option left unread are converted into errors to write out later.
arguments.reportRemainingOptionsAsUnrecognized();
// report any errors if they have occurred when parsing the program arguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
return 1;
}
// optimize the scene graph, remove redundant nodes and state etc.
osgUtil::Optimizer optimizer;
optimizer.optimize(loadedModel.get());
viewer.setSceneData( loadedModel.get() );
return viewer.run();
}

View File

@@ -123,7 +123,7 @@ int main( int argc, char **argv )
while (arguments.read("-p",pathfile))
{
apm = new osgGA::AnimationPathManipulator(pathfile);
if(!apm.valid() || !(apm->valid()) )
if (!apm.valid() || !(apm->valid()) )
{
apm = 0;
}

View File

@@ -57,14 +57,30 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View
/** Get the threading model the rendering traversals will use.*/
ThreadingModel getThreadingModel() const { return _threadingModel; }
/** Set the key value that the viewer checks on each frame to see if the viewer's done flag should be set to
enum BarrierPosition
{
BeforeSwapBuffers,
AfterSwapBuffers
};
/** Set the position of the end barrier.
* AfterSwapBuffers will may result is slightly higher framerates, by may
* lead to inconcistent swapping between different windows.
* BeforeSwapBuffers may lead to slightly lower framerate, but improve consistency in timing of swap buffers,
* especially important if you are likely to consistently break frame.*/
void setEndBarrierPosition(BarrierPosition bp);
/** Get the end barrier position.*/
BarrierPosition getEndBarrierPosition() const { return _endBarrierPosition; }
/** Set the key event that the viewer checks on each frame to see if the viewer's done flag should be set to
* signal end of viewers main loop.
* Default value is Escape (osgGA::GUIEVentAdapter::KEY_Escape).
* Setting to 0 switches off the feature.*/
void setKeySetsDone(int key) { _keySetsDone = key; }
void setKeyEventSetsDone(int key) { _keyEventSetsDone = key; }
/** get the key value that the viewer checks on each frame to see if the viewer's done flag.*/
int getKeySetsDone() const { return _keySetsDone; }
/** get the key event that the viewer checks on each frame to see if the viewer's done flag.*/
int getKeyEventSetsDone() const { return _keyEventSetsDone; }
/** if the flag is true, the viewer set its done flag when a QUIT_APPLICATION is received, false disables this feature */
void setQuitEventSetsDone(bool flag) { _quitEventSetsDone = flag; }
@@ -121,11 +137,12 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View
bool _firstFrame;
bool _done;
int _keySetsDone;
int _keyEventSetsDone;
bool _quitEventSetsDone;
ThreadingModel _threadingModel;
BarrierPosition _endBarrierPosition;
osg::ref_ptr<osg::BarrierOperation> _startRenderingBarrier;
osg::ref_ptr<osg::BarrierOperation> _endRenderingDispatchBarrier;

View File

@@ -26,9 +26,10 @@ using namespace osgViewer;
Viewer::Viewer():
_firstFrame(true),
_done(false),
_keySetsDone(osgGA::GUIEventAdapter::KEY_Escape),
_keyEventSetsDone(osgGA::GUIEventAdapter::KEY_Escape),
_quitEventSetsDone(true),
_threadingModel(ThreadPerContext),
_endBarrierPosition(AfterSwapBuffers),
_numThreadsOnBarrier(0)
{
_eventVisitor = new osgGA::EventVisitor;
@@ -129,6 +130,18 @@ void Viewer::setThreadingModel(ThreadingModel threadingModel)
if (_threadingModel!=SingleThreaded) startThreading();
}
void Viewer::setEndBarrierPosition(BarrierPosition bp)
{
if (_endBarrierPosition == bp) return;
if (_threadingModel!=SingleThreaded) stopThreading();
_endBarrierPosition = bp;
if (_threadingModel!=SingleThreaded) startThreading();
}
void Viewer::stopThreading()
{
if (_numThreadsOnBarrier==0) return;
@@ -293,12 +306,21 @@ void Viewer::startThreading()
// add the rendering operation itself.
gc->getGraphicsThread()->add(new RunOperations(gc));
// add the endRenderingDispatchBarrier
gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get());
if (_endBarrierPosition==BeforeSwapBuffers)
{
// add the endRenderingDispatchBarrier
gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get());
}
// add the swap buffers
gc->getGraphicsThread()->add(swapOp.get());
if (_endBarrierPosition==AfterSwapBuffers)
{
// add the endRenderingDispatchBarrier
gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get());
}
}
@@ -801,7 +823,7 @@ void Viewer::eventTraversal()
// osg::notify(osg::NOTICE)<<"Events "<<events.size()<<std::endl;
if ((_keySetsDone!=0) || (_quitEventSetsDone))
if ((_keyEventSetsDone!=0) || _quitEventSetsDone)
{
for(osgGA::EventQueue::Events::iterator itr = events.begin();
itr != events.end();
@@ -811,14 +833,11 @@ void Viewer::eventTraversal()
switch(event->getEventType())
{
case(osgGA::GUIEventAdapter::KEYUP):
if (event->getKey()==_keySetsDone) _done = true;
else if (event->getKey()=='s') { setThreadingModel(SingleThreaded); }
else if (event->getKey()=='c') { setThreadingModel(ThreadPerCamera); }
else if (event->getKey()=='w') { setThreadingModel(ThreadPerContext); }
if (_keyEventSetsDone && event->getKey()==_keyEventSetsDone) _done = true;
break;
case(osgGA::GUIEventAdapter::QUIT_APPLICATION):
_done = true;
if (_quitEventSetsDone) _done = true;
break;
default:

View File

@@ -32,6 +32,11 @@ BEGIN_ENUM_REFLECTOR(osgViewer::Viewer::ThreadingModel)
I_EnumLabel(osgViewer::Viewer::ThreadPerCamera);
END_REFLECTOR
BEGIN_ENUM_REFLECTOR(osgViewer::Viewer::BarrierPosition)
I_EnumLabel(osgViewer::Viewer::BeforeSwapBuffers);
I_EnumLabel(osgViewer::Viewer::AfterSwapBuffers);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgViewer::Viewer)
I_BaseType(osgViewer::View);
I_Constructor0(____Viewer,
@@ -69,13 +74,21 @@ BEGIN_OBJECT_REFLECTOR(osgViewer::Viewer)
__ThreadingModel__getThreadingModel,
"Get the threading model the rendering traversals will use. ",
"");
I_Method1(void, setKeySetsDone, IN, int, key,
__void__setKeySetsDone__int,
"Set the key value that the viewer checks on each frame to see if the viewer's done flag should be set to signal end of viewers main loop. ",
I_Method1(void, setEndBarrierPosition, IN, osgViewer::Viewer::BarrierPosition, bp,
__void__setEndBarrierPosition__BarrierPosition,
"Set the position of the end barrier. ",
"AfterSwapBuffers will may result is slightly higher framerates, by may lead to inconcistent swapping between different windows. BeforeSwapBuffers may lead to slightly lower framerate, but improve consistency in timing of swap buffers, especially important if you are likely to consistently break frame. ");
I_Method0(osgViewer::Viewer::BarrierPosition, getEndBarrierPosition,
__BarrierPosition__getEndBarrierPosition,
"Get the end barrier position. ",
"");
I_Method1(void, setKeyEventSetsDone, IN, int, key,
__void__setKeyEventSetsDone__int,
"Set the key event that the viewer checks on each frame to see if the viewer's done flag should be set to signal end of viewers main loop. ",
"Default value is Escape (osgGA::GUIEVentAdapter::KEY_Escape). Setting to 0 switches off the feature. ");
I_Method0(int, getKeySetsDone,
__int__getKeySetsDone,
"get the key value that the viewer checks on each frame to see if the viewer's done flag. ",
I_Method0(int, getKeyEventSetsDone,
__int__getKeyEventSetsDone,
"get the key event that the viewer checks on each frame to see if the viewer's done flag. ",
"");
I_Method1(void, setQuitEventSetsDone, IN, bool, flag,
__void__setQuitEventSetsDone__bool,
@@ -143,12 +156,15 @@ BEGIN_OBJECT_REFLECTOR(osgViewer::Viewer)
I_SimpleProperty(bool, Done,
0,
__void__setDone__bool);
I_SimpleProperty(osgViewer::Viewer::BarrierPosition, EndBarrierPosition,
__BarrierPosition__getEndBarrierPosition,
__void__setEndBarrierPosition__BarrierPosition);
I_SimpleProperty(osg::FrameStamp *, FrameStamp,
__osg_FrameStamp_P1__getFrameStamp,
0);
I_SimpleProperty(int, KeySetsDone,
__int__getKeySetsDone,
__void__setKeySetsDone__int);
I_SimpleProperty(int, KeyEventSetsDone,
__int__getKeyEventSetsDone,
__void__setKeyEventSetsDone__int);
I_SimpleProperty(bool, QuitEventSetsDone,
__bool__getQuitEventSetsDone,
__void__setQuitEventSetsDone__bool);