2006-07-18 23:21:48 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2005-03-13 09:47:46 +08:00
*
* This application is open source and may be redistributed and / or modified
* freely and without restriction , both in commericial and non commericial applications ,
* as long as this copyright notice is maintained .
*
* This application 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 .
*/
# include <osgDB/ReadFile>
# include <osgUtil/Optimizer>
# include <osg/CoordinateSystemNode>
2007-01-22 02:24:54 +08:00
# include <osg/Switch>
# include <osgText/Text>
2007-01-12 19:38:24 +08:00
2007-01-12 18:26:49 +08:00
# include <osgViewer/Viewer>
2007-01-23 19:01:20 +08:00
# include <osgViewer/StatsHandler>
2007-02-12 21:39:18 +08:00
# include <osgViewer/HelpHandler>
2007-01-22 02:24:54 +08:00
2007-01-12 19:38:24 +08:00
# include <osgGA/TrackballManipulator>
# include <osgGA/FlightManipulator>
# include <osgGA/DriveManipulator>
# include <osgGA/KeySwitchMatrixManipulator>
# include <osgGA/StateSetManipulator>
2007-01-12 23:08:45 +08:00
# include <osgGA/AnimationPathManipulator>
2007-01-15 19:44:38 +08:00
# include <osgGA/TerrainManipulator>
2007-01-12 19:38:24 +08:00
2007-01-22 02:24:54 +08:00
# include <iostream>
2007-01-13 05:05:39 +08:00
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 ) :
2007-02-06 22:38:08 +08:00
viewer - > setThreadingModel ( osgViewer : : Viewer : : CullDrawThreadPerContext ) ;
osg : : notify ( osg : : NOTICE ) < < " Threading model 'CullDrawThreadPerContext' selected. " < < std : : endl ;
2007-01-13 05:05:39 +08:00
break ;
2007-02-06 22:38:08 +08:00
case ( osgViewer : : Viewer : : CullDrawThreadPerContext ) :
viewer - > setThreadingModel ( osgViewer : : Viewer : : DrawThreadPerContext ) ;
osg : : notify ( osg : : NOTICE ) < < " Threading model 'DrawThreadPerContext' selected. " < < std : : endl ;
2007-01-13 05:05:39 +08:00
break ;
2007-02-06 22:38:08 +08:00
case ( osgViewer : : Viewer : : DrawThreadPerContext ) :
viewer - > setThreadingModel ( osgViewer : : Viewer : : CullThreadPerCameraDrawThreadPerContext ) ;
osg : : notify ( osg : : NOTICE ) < < " Threading model 'CullThreadPerCameraDrawThreadPerContext' selected. " < < std : : endl ;
break ;
case ( osgViewer : : Viewer : : CullThreadPerCameraDrawThreadPerContext ) :
2007-01-13 05:05:39 +08:00
viewer - > setThreadingModel ( osgViewer : : Viewer : : SingleThreaded ) ;
2007-02-06 22:38:08 +08:00
osg : : notify ( osg : : NOTICE ) < < " Threading model 'SingleThreaded' selected. " < < std : : endl ;
break ;
case ( osgViewer : : Viewer : : AutomaticSelection ) :
viewer - > setThreadingModel ( viewer - > suggestBestThreadingModel ( ) ) ;
osg : : notify ( osg : : NOTICE ) < < " Threading model 'AutomaticSelection' selected. " < < std : : endl ;
2007-01-13 05:05:39 +08:00
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 ;
}
2007-02-12 21:39:18 +08:00
/** 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. " ) ;
}
2007-01-13 05:05:39 +08:00
bool _done ;
} ;
2007-01-20 03:53:23 +08:00
2007-04-13 22:54:41 +08:00
class FullScreenToggleHandler : public osgGA : : GUIEventHandler
{
public :
FullScreenToggleHandler ( ) { }
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 ( ) = = ' f ' )
{
osgViewer : : Viewer : : Windows windows ;
viewer - > getWindows ( windows ) ;
for ( osgViewer : : Viewer : : Windows : : iterator itr = windows . begin ( ) ;
itr ! = windows . end ( ) ;
+ + itr )
{
toggleFullscreen ( * itr ) ;
}
}
}
default : break ;
}
return false ;
}
/** Get the keyboard and mouse usage of this manipulator.*/
virtual void getUsage ( osg : : ApplicationUsage & usage ) const
{
usage . addKeyboardMouseBinding ( " f " , " Toggle full screen. " ) ;
}
void toggleFullscreen ( osgViewer : : GraphicsWindow * window )
{
osg : : GraphicsContext : : WindowingSystemInterface * wsi = osg : : GraphicsContext : : getWindowingSystemInterface ( ) ;
if ( ! wsi )
{
osg : : notify ( osg : : NOTICE ) < < " Error, no WindowSystemInterface available, cannot toggle window fullscreen. " < < std : : endl ;
return ;
}
unsigned int screen_width , screen_height ;
wsi - > getScreenResolution ( * ( window - > getTraits ( ) ) , screen_width , screen_height ) ;
int x , y , width , height ;
window - > getWindowRectangle ( x , y , width , height ) ;
bool isFullScreen = x = = 0 & & y = = 0 & & width = = screen_width & & height = = screen_height ;
if ( isFullScreen )
{
window - > setWindowRectangle ( screen_width / 4 , screen_height / 4 , screen_width / 2 , screen_height / 2 ) ;
window - > setWindowDecoration ( true ) ;
}
else
{
window - > setWindowDecoration ( false ) ;
window - > setWindowRectangle ( 0 , 0 , screen_width , screen_height ) ;
}
window - > grabFocusIfPointerInWindow ( ) ;
return ;
}
bool _done ;
} ;
2007-01-22 02:24:54 +08:00
int main ( int argc , char * * argv )
2007-01-12 18:26:49 +08:00
{
2007-01-22 02:24:54 +08:00
// use an ArgumentParser object to manage the program arguments.
osg : : ArgumentParser arguments ( & argc , argv ) ;
2007-01-13 05:05:39 +08:00
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. " ) ;
2007-02-08 20:24:33 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --SingleThreaded " , " Select SingleThreaded threading model for viewer. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --CullDrawThreadPerContext " , " Select CullDrawThreadPerContext threading model for viewer. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --DrawThreadPerContext " , " Select DrawThreadPerContext threading model for viewer. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --CullThreadPerCameraDrawThreadPerContext " , " Select CullThreadPerCameraDrawThreadPerContext threading model for viewer. " ) ;
2007-01-13 05:05:39 +08:00
// 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 ;
}
2007-01-12 18:26:49 +08:00
osgViewer : : Viewer viewer ;
2007-01-12 19:38:24 +08:00
// 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 ( ) ) ;
2007-01-15 19:44:38 +08:00
keyswitchManipulator - > addMatrixManipulator ( ' 4 ' , " Terrain " , new osgGA : : TerrainManipulator ( ) ) ;
2007-01-12 19:38:24 +08:00
2007-01-12 23:08:45 +08:00
std : : string pathfile ;
2007-01-15 19:44:38 +08:00
char keyForAnimationPath = ' 5 ' ;
2007-01-12 23:08:45 +08:00
while ( arguments . read ( " -p " , pathfile ) )
{
osgGA : : AnimationPathManipulator * apm = new osgGA : : AnimationPathManipulator ( pathfile ) ;
if ( apm | | ! apm - > valid ( ) )
{
unsigned int num = keyswitchManipulator - > getNumMatrixManipulators ( ) ;
2007-01-15 19:44:38 +08:00
keyswitchManipulator - > addMatrixManipulator ( keyForAnimationPath , " Path " , apm ) ;
2007-01-12 23:08:45 +08:00
keyswitchManipulator - > selectMatrixManipulator ( num ) ;
2007-01-15 19:44:38 +08:00
+ + keyForAnimationPath ;
2007-01-12 23:08:45 +08:00
}
}
2007-01-12 19:38:24 +08:00
viewer . setCameraManipulator ( keyswitchManipulator . get ( ) ) ;
}
// add the state manipulator
2007-01-24 00:28:59 +08:00
viewer . addEventHandler ( new osgGA : : StateSetManipulator ( viewer . getCamera ( ) - > getOrCreateStateSet ( ) ) ) ;
2007-01-12 19:38:24 +08:00
2007-01-13 05:05:39 +08:00
// add the thread model handler
2007-01-20 03:53:23 +08:00
viewer . addEventHandler ( new ThreadingHandler ) ;
2007-04-13 22:54:41 +08:00
// add the full screen toggle handler
viewer . addEventHandler ( new FullScreenToggleHandler ) ;
2007-01-20 03:53:23 +08:00
// add the stats handler
2007-01-23 19:01:20 +08:00
viewer . addEventHandler ( new osgViewer : : StatsHandler ) ;
2007-01-13 05:05:39 +08:00
2007-02-12 21:39:18 +08:00
// add the help handler
viewer . addEventHandler ( new osgViewer : : HelpHandler ( arguments . getApplicationUsage ( ) ) ) ;
2007-02-05 22:56:41 +08:00
2007-02-08 20:24:33 +08:00
while ( arguments . read ( " --SingleThreaded " ) ) viewer . setThreadingModel ( osgViewer : : Viewer : : SingleThreaded ) ;
while ( arguments . read ( " --CullDrawThreadPerContext " ) ) viewer . setThreadingModel ( osgViewer : : Viewer : : CullDrawThreadPerContext ) ;
while ( arguments . read ( " --DrawThreadPerContext " ) ) viewer . setThreadingModel ( osgViewer : : Viewer : : DrawThreadPerContext ) ;
while ( arguments . read ( " --CullThreadPerCameraDrawThreadPerContext " ) ) viewer . setThreadingModel ( osgViewer : : Viewer : : CullThreadPerCameraDrawThreadPerContext ) ;
2007-02-05 22:56:41 +08:00
unsigned int screenNum ;
while ( arguments . read ( " --screen " , screenNum ) )
{
viewer . setUpViewOnSingleScreen ( screenNum ) ;
}
2007-01-13 05:05:39 +08:00
// 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 ( ) ) ;
2007-01-12 18:26:49 +08:00
return viewer . run ( ) ;
}