diff --git a/VisualStudio/osgViewer/osgViewer.dsp b/VisualStudio/osgViewer/osgViewer.dsp index 1ba132115..7d5731a2c 100644 --- a/VisualStudio/osgViewer/osgViewer.dsp +++ b/VisualStudio/osgViewer/osgViewer.dsp @@ -179,6 +179,10 @@ SOURCE=..\..\src\osgViewer\CompositeViewer.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osgViewer\HelpHandler.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osgViewer\StatsHandler.cpp # End Source File # Begin Source File @@ -223,6 +227,10 @@ SOURCE=..\..\Include\osgViewer\SimpleViewer # End Source File # Begin Source File +SOURCE=..\..\Include\osgViewer\HelpHandler +# End Source File +# Begin Source File + SOURCE=..\..\Include\osgViewer\StatsHandler # End Source File # Begin Source File diff --git a/applications/osgviewer/osgviewer.cpp b/applications/osgviewer/osgviewer.cpp index bebeeec7e..93c9c11e2 100644 --- a/applications/osgviewer/osgviewer.cpp +++ b/applications/osgviewer/osgviewer.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -113,6 +114,15 @@ public: return false; } + /** Get the keyboard and mouse usage of this manipulator.*/ + virtual void getUsage(osg::ApplicationUsage& usage) const + { + usage.addKeyboardMouseBinding("m","Toggle threading model."); + usage.addKeyboardMouseBinding("e","Toggle the placement of the end of frame barrier."); + } + + + bool _done; }; @@ -197,6 +207,8 @@ int main(int argc, char** argv) // add the stats handler viewer.addEventHandler(new osgViewer::StatsHandler); + // add the help handler + viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage())); while (arguments.read("--SingleThreaded")) viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); while (arguments.read("--CullDrawThreadPerContext")) viewer.setThreadingModel(osgViewer::Viewer::CullDrawThreadPerContext); diff --git a/include/osg/ApplicationUsage b/include/osg/ApplicationUsage index 99ed4fce3..fee43240a 100644 --- a/include/osg/ApplicationUsage +++ b/include/osg/ApplicationUsage @@ -14,7 +14,7 @@ #ifndef OSG_APPLICATIONUSAGE #define OSG_APPLICATIONUSAGE 1 -#include +#include #include #include @@ -22,7 +22,7 @@ namespace osg { -class OSG_EXPORT ApplicationUsage +class OSG_EXPORT ApplicationUsage : public osg::Referenced { public: @@ -88,6 +88,8 @@ class OSG_EXPORT ApplicationUsage protected: + virtual ~ApplicationUsage() {} + std::string _applicationName; std::string _description; std::string _commandLineUsage; diff --git a/include/osg/ArgumentParser b/include/osg/ArgumentParser index 6914c7411..67ac7d250 100644 --- a/include/osg/ArgumentParser +++ b/include/osg/ArgumentParser @@ -15,6 +15,8 @@ #define OSG_ARGUMENTPARSER 1 #include +#include +#include #include #include @@ -22,9 +24,6 @@ namespace osg { -// forward declare -class ApplicationUsage; - class OSG_EXPORT ArgumentParser { public: @@ -89,8 +88,8 @@ class OSG_EXPORT ArgumentParser ArgumentParser(int* argc,char **argv); void setApplicationUsage(ApplicationUsage* usage) { _usage = usage; } - ApplicationUsage* getApplicationUsage() { return _usage; } - const ApplicationUsage* getApplicationUsage() const { return _usage; } + ApplicationUsage* getApplicationUsage() { return _usage.get(); } + const ApplicationUsage* getApplicationUsage() const { return _usage.get(); } /** Return the argument count. */ int& argc() { return *_argc; } @@ -187,10 +186,10 @@ class OSG_EXPORT ArgumentParser protected: - int* _argc; - char** _argv; - ErrorMessageMap _errorMessageMap; - ApplicationUsage* _usage; + int* _argc; + char** _argv; + ErrorMessageMap _errorMessageMap; + ref_ptr _usage; }; diff --git a/include/osgViewer/HelpHandler b/include/osgViewer/HelpHandler new file mode 100644 index 000000000..f95cc7fcd --- /dev/null +++ b/include/osgViewer/HelpHandler @@ -0,0 +1,59 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGVIEWER_HELPHANDLER +#define OSGVIEWER_HELPHANDLER 1 + +#include + +#include + +namespace osgViewer { + +class OSGVIEWER_EXPORT HelpHandler : public osgGA::GUIEventHandler +{ + public: + + HelpHandler(osg::ApplicationUsage* au=0); + + void setApplicationUsage(osg::ApplicationUsage* au) { _applicationUsage = au; } + osg::ApplicationUsage* getApplicationUsage() { return _applicationUsage.get(); } + const osg::ApplicationUsage* getApplicationUsage() const { return _applicationUsage.get(); } + + void setKeyEventTogglesOnScreenHelp(int key) { _keyEventTogglesOnScreenHelp = key; } + int getKeyEventTogglesOnScreenHelp() const { return _keyEventTogglesOnScreenHelp; } + + bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa); + + /** Get the keyboard and mouse usage of this manipulator.*/ + virtual void getUsage(osg::ApplicationUsage& usage) const; + + protected: + + void setUpHUDCamera(osgViewer::Viewer* viewer); + + void setUpScene(osgViewer::Viewer* viewer); + + osg::ref_ptr _applicationUsage; + + int _keyEventTogglesOnScreenHelp; + + bool _helpEnabled; + osg::ref_ptr _camera; + osg::ref_ptr _switch; + +}; + +} + +#endif diff --git a/include/osgViewer/StatsHandler b/include/osgViewer/StatsHandler index 2b6e8d467..75fbd1f47 100644 --- a/include/osgViewer/StatsHandler +++ b/include/osgViewer/StatsHandler @@ -45,6 +45,9 @@ class OSGVIEWER_EXPORT StatsHandler : public osgGA::GUIEventHandler double getBlockMultiplier() const { return _blockMultiplier; } + /** Get the keyboard and mouse usage of this manipulator.*/ + virtual void getUsage(osg::ApplicationUsage& usage) const; + protected: void setUpHUDCamera(osgViewer::Viewer* viewer); diff --git a/include/osgViewer/Viewer b/include/osgViewer/Viewer index 868b7b038..ae68237ec 100644 --- a/include/osgViewer/Viewer +++ b/include/osgViewer/Viewer @@ -161,6 +161,9 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View /** Set up the Operations to render the various viewer cameras on the viewers graphics windows.*/ void setUpRenderingSupport(); + /** Get the keyboard and mouse usage of this viewer.*/ + virtual void getUsage(osg::ApplicationUsage& usage) const; + protected: void checkWindowStatus(); diff --git a/src/osg/ApplicationUsage.cpp b/src/osg/ApplicationUsage.cpp index feeddf6f2..9b0405cef 100644 --- a/src/osg/ApplicationUsage.cpp +++ b/src/osg/ApplicationUsage.cpp @@ -1,5 +1,19 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + #include #include +#include using namespace osg; @@ -10,8 +24,8 @@ ApplicationUsage::ApplicationUsage(const std::string& commandLineUsage): ApplicationUsage* ApplicationUsage::instance() { - static ApplicationUsage s_applicationUsage; - return &s_applicationUsage; + static osg::ref_ptr s_applicationUsage = new ApplicationUsage; + return s_applicationUsage.get(); } void ApplicationUsage::addUsageExplanation(Type type,const std::string& option,const std::string& explanation) diff --git a/src/osg/ArgumentParser.cpp b/src/osg/ArgumentParser.cpp index 66562817f..c07a5b313 100644 --- a/src/osg/ArgumentParser.cpp +++ b/src/osg/ArgumentParser.cpp @@ -1,3 +1,16 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + #include #include #include @@ -552,7 +565,7 @@ void ArgumentParser::reportError(const std::string& message,ErrorSeverity severi void ArgumentParser::reportRemainingOptionsAsUnrecognized(ErrorSeverity severity) { std::set options; - if (_usage) + if (_usage.valid()) { // parse the usage options to get all the option that the application can potential handle. for(ApplicationUsage::UsageMap::const_iterator itr=_usage->getCommandLineOptions().begin(); diff --git a/src/osgViewer/GNUmakefile b/src/osgViewer/GNUmakefile index ec6b214a8..d91a458b7 100644 --- a/src/osgViewer/GNUmakefile +++ b/src/osgViewer/GNUmakefile @@ -7,6 +7,7 @@ CXXFILES = \ Scene.cpp\ SimpleViewer.cpp\ StatsHandler.cpp\ + HelpHandler.cpp\ Version.cpp\ View.cpp\ Viewer.cpp\ diff --git a/src/osgViewer/HelpHandler.cpp b/src/osgViewer/HelpHandler.cpp new file mode 100644 index 000000000..995fa1138 --- /dev/null +++ b/src/osgViewer/HelpHandler.cpp @@ -0,0 +1,173 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include + +#include + +#include + +using namespace osgViewer; + +HelpHandler::HelpHandler(osg::ApplicationUsage* au): + _applicationUsage(au), + _keyEventTogglesOnScreenHelp('h'), + _helpEnabled(false) +{ +} + +bool HelpHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) +{ + osgViewer::Viewer* viewer = dynamic_cast(&aa); + if (!viewer) return false; + + switch(ea.getEventType()) + { + case(osgGA::GUIEventAdapter::KEYDOWN): + { + if (ea.getKey()==_keyEventTogglesOnScreenHelp) + { + if (!_camera.valid()) + { + setUpHUDCamera(viewer); + setUpScene(viewer); + } + + _helpEnabled = !_helpEnabled; + + if (_helpEnabled) + { + _camera->setNodeMask(0xffffffff); + } + else + { + _camera->setNodeMask(0); + } + return true; + } + } + default: break; + } + + return false; + +} + +void HelpHandler::setUpHUDCamera(osgViewer::Viewer* viewer) +{ + osgViewer::Viewer::Windows windows; + viewer->getWindows(windows); + + if (windows.empty()) return; + + osgViewer::GraphicsWindow* window = windows.front(); + + _camera = new osg::Camera; + _camera->setGraphicsContext(window); + _camera->setViewport(0, 0, window->getTraits()->width, window->getTraits()->height); + + _camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,1024)); + _camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + _camera->setViewMatrix(osg::Matrix::identity()); + + // only clear the depth buffer + _camera->setClearMask(0); + + viewer->setUpRenderingSupport(); +} + +void HelpHandler::setUpScene(osgViewer::Viewer* viewer) +{ + _switch = new osg::Switch; + + _camera->addChild(_switch.get()); + + osg::StateSet* stateset = _switch->getOrCreateStateSet(); + stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); + stateset->setMode(GL_BLEND,osg::StateAttribute::ON); + stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF); + stateset->setAttribute(new osg::PolygonMode(), osg::StateAttribute::PROTECTED); + + std::string font("fonts/arial.ttf"); + + if (!_applicationUsage) setApplicationUsage(new osg::ApplicationUsage()); + + viewer->getUsage(*_applicationUsage); + + float leftPos = 10.0f; + float startDescription = 200.0f; + float characterSize = 20.0f; + + osg::Vec3 pos(leftPos,1000.0f,0.0f); + osg::Vec4 color(1.0f,1.0f,1.0f,1.0f); + + osg::Geode* geode = new osg::Geode(); + _switch->addChild(geode, true); + + // application description + if (!_applicationUsage->getDescription().empty()) + { + + osg::ref_ptr label = new osgText::Text; + geode->addDrawable( label.get() ); + + label->setColor(color); + label->setBackdropType(osgText::Text::OUTLINE); + label->setFont(font); + label->setCharacterSize(characterSize); + label->setPosition(pos); + label->setText(_applicationUsage->getDescription()); + + pos.x() = label->getBound().xMax(); + pos.y() -= characterSize*2.5f; + } + + const osg::ApplicationUsage::UsageMap& keyboardBinding = _applicationUsage->getKeyboardMouseBindings(); + + for(osg::ApplicationUsage::UsageMap::const_iterator itr = keyboardBinding.begin(); + itr != keyboardBinding.end(); + ++itr) + { + pos.x() = leftPos; + + osg::ref_ptr key = new osgText::Text; + geode->addDrawable( key.get() ); + key->setColor(color); + key->setBackdropType(osgText::Text::OUTLINE); + key->setFont(font); + key->setCharacterSize(characterSize); + key->setPosition(pos); + key->setText(itr->first); + + pos.x() = startDescription; + + osg::ref_ptr description = new osgText::Text; + geode->addDrawable( description.get() ); + description->setColor(color); + description->setBackdropType(osgText::Text::OUTLINE); + description->setFont(font); + description->setCharacterSize(characterSize); + description->setPosition(pos); + + description->setText(itr->second); + + pos.y() -= characterSize*1.5f; + + } +} + + +void HelpHandler::getUsage(osg::ApplicationUsage& usage) const +{ + usage.addKeyboardMouseBinding("h","Onscreen help."); +} diff --git a/src/osgViewer/StatsHandler.cpp b/src/osgViewer/StatsHandler.cpp index 9d58ab8b7..65acb2993 100644 --- a/src/osgViewer/StatsHandler.cpp +++ b/src/osgViewer/StatsHandler.cpp @@ -806,4 +806,11 @@ osg::Node* StatsHandler::createCameraStats(const std::string& font, osg::Vec3& p return group; } + +void StatsHandler::getUsage(osg::ApplicationUsage& usage) const +{ + usage.addKeyboardMouseBinding("s","Onscreen stats."); + usage.addKeyboardMouseBinding("S","Output stats to console."); +} + } diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index d0e379b82..3ffcf40d1 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -2070,3 +2070,19 @@ void Viewer::renderingTraversals() getStats()->setAttribute(_frameStamp->getFrameNumber(), "Rendering traversals time taken", endRenderingTraversals-beginRenderingTraversals); } } + +void Viewer::getUsage(osg::ApplicationUsage& usage) const +{ + if (_cameraManipulator.valid()) + { + _cameraManipulator->getUsage(usage); + } + + for(EventHandlers::const_iterator hitr = _eventHandlers.begin(); + hitr != _eventHandlers.end(); + ++hitr) + { + (*hitr)->getUsage(usage); + } + +}