2006-11-27 22:52:07 +08:00
/* -*-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 ,
2007-01-20 03:53:23 +08:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
2006-11-27 22:52:07 +08:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* OpenSceneGraph Public License for more details .
*/
2006-12-23 01:46:21 +08:00
# include <osg/GLExtensions>
2007-02-02 20:41:13 +08:00
# include <osg/DeleteHandler>
2007-02-14 19:24:42 +08:00
# include <osgUtil/Optimizer>
2007-01-05 18:59:23 +08:00
# include <osgUtil/GLObjectsVisitor>
2007-06-06 18:57:02 +08:00
# include <osgDB/Registry>
2007-01-05 18:59:23 +08:00
# include <osgGA/TrackballManipulator>
# include <osgViewer/Viewer>
2006-11-27 22:52:07 +08:00
2007-01-02 02:20:10 +08:00
# include <osg/io_utils>
2006-12-21 05:13:29 +08:00
2007-06-13 19:09:31 +08:00
# include <sstream>
2007-01-02 02:20:10 +08:00
using namespace osgViewer ;
2006-12-21 05:13:29 +08:00
2007-02-02 20:41:13 +08:00
2007-02-01 06:24:20 +08:00
class ViewerQuerySupport
{
public :
ViewerQuerySupport ( osg : : Timer_t startTick ) :
_startTick ( startTick ) ,
_initialized ( false ) ,
_timerQuerySupported ( false ) ,
_extensions ( 0 ) ,
_previousQueryTime ( 0.0 )
{
}
typedef std : : pair < GLuint , int > QueryFrameNumberPair ;
typedef std : : list < QueryFrameNumberPair > QueryFrameNumberList ;
typedef std : : vector < GLuint > QueryList ;
inline void checkQuery ( osg : : Stats * stats )
{
for ( QueryFrameNumberList : : iterator itr = _queryFrameNumberList . begin ( ) ;
itr ! = _queryFrameNumberList . end ( ) ;
)
{
GLuint query = itr - > first ;
GLint available = 0 ;
_extensions - > glGetQueryObjectiv ( query , GL_QUERY_RESULT_AVAILABLE , & available ) ;
if ( available )
{
GLuint64EXT timeElapsed = 0 ;
_extensions - > glGetQueryObjectui64v ( query , GL_QUERY_RESULT , & timeElapsed ) ;
double timeElapsedSeconds = double ( timeElapsed ) * 1e-9 ;
double currentTime = osg : : Timer : : instance ( ) - > delta_s ( _startTick , osg : : Timer : : instance ( ) - > tick ( ) ) ;
double estimatedEndTime = ( _previousQueryTime + currentTime ) * 0.5 ;
double estimatedBeginTime = estimatedEndTime - timeElapsedSeconds ;
stats - > setAttribute ( itr - > second , " GPU draw begin time " , estimatedBeginTime ) ;
stats - > setAttribute ( itr - > second , " GPU draw end time " , estimatedEndTime ) ;
stats - > setAttribute ( itr - > second , " GPU draw time taken " , timeElapsedSeconds ) ;
itr = _queryFrameNumberList . erase ( itr ) ;
_availableQueryObjects . push_back ( query ) ;
}
else
{
+ + itr ;
}
}
_previousQueryTime = osg : : Timer : : instance ( ) - > delta_s ( _startTick , osg : : Timer : : instance ( ) - > tick ( ) ) ;
}
inline GLuint createQueryObject ( )
{
if ( _availableQueryObjects . empty ( ) )
{
GLuint query ;
_extensions - > glGenQueries ( 1 , & query ) ;
return query ;
}
else
{
GLuint query = _availableQueryObjects . back ( ) ;
_availableQueryObjects . pop_back ( ) ;
return query ;
}
}
inline void beginQuery ( int frameNumber )
{
GLuint query = createQueryObject ( ) ;
_extensions - > glBeginQuery ( GL_TIME_ELAPSED , query ) ;
_queryFrameNumberList . push_back ( QueryFrameNumberPair ( query , frameNumber ) ) ;
}
inline void endQuery ( )
{
_extensions - > glEndQuery ( GL_TIME_ELAPSED ) ;
}
void initialize ( osg : : State * state )
{
if ( _initialized ) return ;
_initialized = true ;
_extensions = osg : : Drawable : : getExtensions ( state - > getContextID ( ) , true ) ;
_timerQuerySupported = _extensions & & _extensions - > isTimerQuerySupported ( ) ;
_previousQueryTime = osg : : Timer : : instance ( ) - > delta_s ( _startTick , osg : : Timer : : instance ( ) - > tick ( ) ) ;
}
osg : : Timer_t _startTick ;
bool _initialized ;
bool _timerQuerySupported ;
const osg : : Drawable : : Extensions * _extensions ;
QueryFrameNumberList _queryFrameNumberList ;
QueryList _availableQueryObjects ;
double _previousQueryTime ;
} ;
// Draw operation, that does a draw on the scene graph.
2007-07-14 03:24:50 +08:00
struct ViewerRenderingOperation : public osg : : GraphicsOperation , public ViewerQuerySupport
2007-02-01 06:24:20 +08:00
{
ViewerRenderingOperation ( osgUtil : : SceneView * sceneView , osgDB : : DatabasePager * databasePager , osg : : Timer_t startTick ) :
2007-07-14 03:24:50 +08:00
osg : : GraphicsOperation ( " Render " , true ) ,
2007-02-01 06:24:20 +08:00
ViewerQuerySupport ( startTick ) ,
_sceneView ( sceneView ) ,
_databasePager ( databasePager )
{
_sceneView - > getCullVisitor ( ) - > setDatabaseRequestHandler ( _databasePager . get ( ) ) ;
}
2007-02-06 19:03:13 +08:00
osg : : Camera * getCamera ( ) { return _sceneView - > getCamera ( ) ; }
2007-07-14 03:24:50 +08:00
virtual void operator ( ) ( osg : : GraphicsContext * )
2007-02-01 06:24:20 +08:00
{
if ( ! _sceneView ) return ;
// osg::notify(osg::NOTICE)<<"RenderingOperation"<<std::endl;
osg : : Stats * stats = _sceneView - > getCamera ( ) - > getStats ( ) ;
osg : : State * state = _sceneView - > getState ( ) ;
const osg : : FrameStamp * fs = state - > getFrameStamp ( ) ;
int frameNumber = fs ? fs - > getFrameNumber ( ) : 0 ;
if ( ! _initialized )
{
initialize ( state ) ;
}
bool aquireGPUStats = stats & & _timerQuerySupported & & stats - > collectStats ( " gpu " ) ;
if ( aquireGPUStats )
{
checkQuery ( stats ) ;
}
// do cull taversal
osg : : Timer_t beforeCullTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2007-02-21 00:46:53 +08:00
2007-05-18 03:58:57 +08:00
// pass on the fusion distance settings from the View to the SceneView
osgViewer : : View * view = dynamic_cast < osgViewer : : View * > ( _sceneView - > getCamera ( ) - > getView ( ) ) ;
if ( view ) _sceneView - > setFusionDistance ( view - > getFusionDistanceMode ( ) , view - > getFusionDistanceValue ( ) ) ;
2007-02-21 00:46:53 +08:00
_sceneView - > inheritCullSettings ( * ( _sceneView - > getCamera ( ) ) ) ;
2007-02-01 06:24:20 +08:00
_sceneView - > cull ( ) ;
2007-02-21 00:46:53 +08:00
2007-02-01 06:24:20 +08:00
osg : : Timer_t afterCullTick = osg : : Timer : : instance ( ) - > tick ( ) ;
#if 0
if ( _sceneView - > getDynamicObjectCount ( ) = = 0 & & state - > getDynamicObjectRenderingCompletedCallback ( ) )
{
osg : : notify ( osg : : NOTICE ) < < " Completed in ViewerRenderingOperation " < < std : : endl ;
state - > getDynamicObjectRenderingCompletedCallback ( ) - > completed ( state ) ;
}
# endif
state - > setDynamicObjectCount ( _sceneView - > getDynamicObjectCount ( ) ) ;
// do draw traveral
if ( aquireGPUStats )
{
checkQuery ( stats ) ;
beginQuery ( frameNumber ) ;
}
_sceneView - > draw ( ) ;
double availableTime = 0.004 ; // 4 ms
2007-06-22 22:48:18 +08:00
if ( _databasePager . valid ( ) & & _databasePager - > requiresExternalCompileGLObjects ( _sceneView - > getState ( ) - > getContextID ( ) ) )
2007-02-01 06:24:20 +08:00
{
2007-06-22 22:48:18 +08:00
_databasePager - > compileGLObjects ( * ( _sceneView - > getState ( ) ) , availableTime ) ;
2007-02-01 06:24:20 +08:00
}
_sceneView - > flushDeletedGLObjects ( availableTime ) ;
if ( aquireGPUStats )
{
endQuery ( ) ;
checkQuery ( stats ) ;
}
osg : : Timer_t afterDrawTick = osg : : Timer : : instance ( ) - > tick ( ) ;
if ( stats & & stats - > collectStats ( " rendering " ) )
{
stats - > setAttribute ( frameNumber , " Cull traversal begin time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , beforeCullTick ) ) ;
stats - > setAttribute ( frameNumber , " Cull traversal end time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , afterCullTick ) ) ;
stats - > setAttribute ( frameNumber , " Cull traversal time taken " , osg : : Timer : : instance ( ) - > delta_s ( beforeCullTick , afterCullTick ) ) ;
stats - > setAttribute ( frameNumber , " Draw traversal begin time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , afterCullTick ) ) ;
stats - > setAttribute ( frameNumber , " Draw traversal end time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , afterDrawTick ) ) ;
stats - > setAttribute ( frameNumber , " Draw traversal time taken " , osg : : Timer : : instance ( ) - > delta_s ( afterCullTick , afterDrawTick ) ) ;
}
}
osg : : observer_ptr < osgUtil : : SceneView > _sceneView ;
osg : : observer_ptr < osgDB : : DatabasePager > _databasePager ;
} ;
// Draw operation, that does a draw on the scene graph.
2007-02-03 06:30:36 +08:00
struct ViewerDoubleBufferedRenderingOperation : public osg : : Operation , public ViewerQuerySupport
2007-02-01 06:24:20 +08:00
{
ViewerDoubleBufferedRenderingOperation ( bool graphicsThreadDoesCull , osgUtil : : SceneView * sv0 , osgUtil : : SceneView * sv1 , osgDB : : DatabasePager * databasePager , osg : : Timer_t startTick ) :
2007-02-03 06:30:36 +08:00
osg : : Operation ( " Render " , true ) ,
2007-02-01 06:24:20 +08:00
ViewerQuerySupport ( startTick ) ,
_graphicsThreadDoesCull ( graphicsThreadDoesCull ) ,
_done ( false ) ,
_databasePager ( databasePager )
{
2007-02-09 06:36:16 +08:00
_lockHeld [ 0 ] = false ;
_lockHeld [ 1 ] = false ;
2007-02-01 06:24:20 +08:00
_sceneView [ 0 ] = sv0 ;
_sceneView [ 0 ] - > getCullVisitor ( ) - > setDatabaseRequestHandler ( _databasePager . get ( ) ) ;
_sceneView [ 1 ] = sv1 ;
_sceneView [ 1 ] - > getCullVisitor ( ) - > setDatabaseRequestHandler ( _databasePager . get ( ) ) ;
_currentCull = 0 ;
_currentDraw = 0 ;
// lock the mutex for the current cull SceneView to
// prevent the draw traversal from reading from it before the cull traversal has been completed.
2007-02-09 06:36:16 +08:00
if ( ! _graphicsThreadDoesCull )
{
_mutex [ _currentCull ] . lock ( ) ;
_lockHeld [ _currentCull ] = true ;
}
2007-02-01 06:24:20 +08:00
2007-02-01 19:07:53 +08:00
// osg::notify(osg::NOTICE)<<"constructed"<<std::endl;
2007-02-01 06:24:20 +08:00
}
2007-02-06 19:03:13 +08:00
osg : : Camera * getCamera ( ) { return _sceneView [ 0 ] - > getCamera ( ) ; }
2007-02-01 06:24:20 +08:00
void setGraphicsThreadDoesCull ( bool flag )
{
if ( _graphicsThreadDoesCull = = flag ) return ;
_graphicsThreadDoesCull = flag ;
_currentCull = 0 ;
_currentDraw = 0 ;
if ( _graphicsThreadDoesCull )
{
// need to disable any locks held by the cull
2007-02-09 06:36:16 +08:00
if ( _lockHeld [ 0 ] )
{
_lockHeld [ 0 ] = false ;
_mutex [ 0 ] . unlock ( ) ;
}
if ( _lockHeld [ 1 ] )
{
_lockHeld [ 1 ] = false ;
_mutex [ 1 ] . unlock ( ) ;
}
2007-02-01 06:24:20 +08:00
}
else
{
// need to set a lock for cull
_mutex [ _currentCull ] . lock ( ) ;
2007-02-09 06:36:16 +08:00
_lockHeld [ _currentCull ] = true ;
2007-02-01 06:24:20 +08:00
}
}
bool getGraphicsThreadDoesCull ( ) const { return _graphicsThreadDoesCull ; }
void cull ( )
{
// osg::notify(osg::NOTICE)<<"cull()"<<std::endl;
if ( _done | | _graphicsThreadDoesCull ) return ;
// note we assume lock has already been aquired.
osgUtil : : SceneView * sceneView = _sceneView [ _currentCull ] . get ( ) ;
if ( sceneView )
{
// osg::notify(osg::NOTICE)<<"Culling buffer "<<_currentCull<<std::endl;
2007-05-18 03:58:57 +08:00
// pass on the fusion distance settings from the View to the SceneView
osgViewer : : View * view = dynamic_cast < osgViewer : : View * > ( sceneView - > getCamera ( ) - > getView ( ) ) ;
if ( view ) sceneView - > setFusionDistance ( view - > getFusionDistanceMode ( ) , view - > getFusionDistanceValue ( ) ) ;
2007-02-01 06:24:20 +08:00
osg : : Stats * stats = sceneView - > getCamera ( ) - > getStats ( ) ;
osg : : State * state = sceneView - > getState ( ) ;
const osg : : FrameStamp * fs = state - > getFrameStamp ( ) ;
int frameNumber = fs ? fs - > getFrameNumber ( ) : 0 ;
_frameNumber [ _currentCull ] = frameNumber ;
// do cull taversal
osg : : Timer_t beforeCullTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2007-02-21 00:46:53 +08:00
sceneView - > inheritCullSettings ( * ( sceneView - > getCamera ( ) ) ) ;
2007-02-01 06:24:20 +08:00
sceneView - > cull ( ) ;
2007-02-21 00:46:53 +08:00
2007-02-01 06:24:20 +08:00
osg : : Timer_t afterCullTick = osg : : Timer : : instance ( ) - > tick ( ) ;
#if 0
if ( sceneView - > getDynamicObjectCount ( ) = = 0 & & state - > getDynamicObjectRenderingCompletedCallback ( ) )
{
// osg::notify(osg::NOTICE)<<"Completed in cull"<<std::endl;
state - > getDynamicObjectRenderingCompletedCallback ( ) - > completed ( state ) ;
}
# endif
if ( stats & & stats - > collectStats ( " rendering " ) )
{
stats - > setAttribute ( frameNumber , " Cull traversal begin time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , beforeCullTick ) ) ;
stats - > setAttribute ( frameNumber , " Cull traversal end time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , afterCullTick ) ) ;
stats - > setAttribute ( frameNumber , " Cull traversal time taken " , osg : : Timer : : instance ( ) - > delta_s ( beforeCullTick , afterCullTick ) ) ;
}
}
2007-02-09 06:36:16 +08:00
// relase the mutex associated with this cull traversal, let the draw commence.
_lockHeld [ _currentCull ] = false ;
2007-02-01 06:24:20 +08:00
_mutex [ _currentCull ] . unlock ( ) ;
// swap which SceneView we need to do cull traversal on next.
_currentCull = 1 - _currentCull ;
// aquire the lock for it for the new cull traversal
_mutex [ _currentCull ] . lock ( ) ;
2007-02-09 06:36:16 +08:00
_lockHeld [ _currentCull ] = true ;
2007-02-01 06:24:20 +08:00
}
void draw ( )
{
// osg::notify(osg::NOTICE)<<"draw()"<<std::endl;
osgUtil : : SceneView * sceneView = _sceneView [ _currentDraw ] . get ( ) ;
if ( sceneView | | _done )
{
OpenThreads : : ScopedLock < OpenThreads : : Mutex > lock ( _mutex [ _currentDraw ] ) ;
// osg::notify(osg::NOTICE)<<"Drawing buffer "<<_currentDraw<<std::endl;
if ( _done )
{
osg : : notify ( osg : : INFO ) < < " ViewerDoubleBufferedRenderingOperation::release() causing draw to exit " < < std : : endl ;
return ;
}
if ( _graphicsThreadDoesCull )
{
osg : : notify ( osg : : INFO ) < < " ViewerDoubleBufferedRenderingOperation::draw() completing early due to change in _graphicsThreadDoesCull flag. " < < std : : endl ;
return ;
}
// osg::notify(osg::NOTICE)<<"RenderingOperation"<<std::endl;
osg : : Stats * stats = sceneView - > getCamera ( ) - > getStats ( ) ;
osg : : State * state = sceneView - > getState ( ) ;
int frameNumber = _frameNumber [ _currentDraw ] ;
if ( ! _initialized )
{
initialize ( state ) ;
}
state - > setDynamicObjectCount ( sceneView - > getDynamicObjectCount ( ) ) ;
if ( sceneView - > getDynamicObjectCount ( ) = = 0 & & state - > getDynamicObjectRenderingCompletedCallback ( ) )
{
// osg::notify(osg::NOTICE)<<"Completed in cull"<<std::endl;
state - > getDynamicObjectRenderingCompletedCallback ( ) - > completed ( state ) ;
}
osg : : Timer_t beforeDrawTick = osg : : Timer : : instance ( ) - > tick ( ) ;
bool aquireGPUStats = stats & & _timerQuerySupported & & stats - > collectStats ( " gpu " ) ;
if ( aquireGPUStats )
{
checkQuery ( stats ) ;
}
// do draw traveral
if ( aquireGPUStats )
{
checkQuery ( stats ) ;
beginQuery ( frameNumber ) ;
}
sceneView - > draw ( ) ;
double availableTime = 0.004 ; // 4 ms
2007-06-22 22:48:18 +08:00
if ( _databasePager . valid ( ) & & _databasePager - > requiresExternalCompileGLObjects ( sceneView - > getState ( ) - > getContextID ( ) ) )
2007-02-01 06:24:20 +08:00
{
_databasePager - > compileGLObjects ( * ( sceneView - > getState ( ) ) , availableTime ) ;
}
sceneView - > flushDeletedGLObjects ( availableTime ) ;
if ( aquireGPUStats )
{
endQuery ( ) ;
checkQuery ( stats ) ;
}
glFlush ( ) ;
osg : : Timer_t afterDrawTick = osg : : Timer : : instance ( ) - > tick ( ) ;
if ( stats & & stats - > collectStats ( " rendering " ) )
{
stats - > setAttribute ( frameNumber , " Draw traversal begin time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , beforeDrawTick ) ) ;
stats - > setAttribute ( frameNumber , " Draw traversal end time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , afterDrawTick ) ) ;
stats - > setAttribute ( frameNumber , " Draw traversal time taken " , osg : : Timer : : instance ( ) - > delta_s ( beforeDrawTick , afterDrawTick ) ) ;
}
}
_currentDraw = 1 - _currentDraw ;
}
void cull_draw ( )
{
osgUtil : : SceneView * sceneView = _sceneView [ _currentDraw ] . get ( ) ;
if ( ! sceneView | | _done ) return ;
OpenThreads : : ScopedLock < OpenThreads : : Mutex > lock ( _mutex [ _currentDraw ] ) ;
if ( _done )
{
osg : : notify ( osg : : INFO ) < < " ViewerDoubleBufferedRenderingOperation::release() causing cull_draw to exit " < < std : : endl ;
return ;
}
// osg::notify(osg::NOTICE)<<"RenderingOperation"<<std::endl;
2007-05-18 03:58:57 +08:00
// pass on the fusion distance settings from the View to the SceneView
osgViewer : : View * view = dynamic_cast < osgViewer : : View * > ( sceneView - > getCamera ( ) - > getView ( ) ) ;
if ( view ) sceneView - > setFusionDistance ( view - > getFusionDistanceMode ( ) , view - > getFusionDistanceValue ( ) ) ;
2007-02-01 06:24:20 +08:00
osg : : Stats * stats = sceneView - > getCamera ( ) - > getStats ( ) ;
osg : : State * state = sceneView - > getState ( ) ;
const osg : : FrameStamp * fs = state - > getFrameStamp ( ) ;
int frameNumber = fs ? fs - > getFrameNumber ( ) : 0 ;
if ( ! _initialized )
{
initialize ( state ) ;
}
bool aquireGPUStats = stats & & _timerQuerySupported & & stats - > collectStats ( " gpu " ) ;
if ( aquireGPUStats )
{
checkQuery ( stats ) ;
}
// do cull taversal
osg : : Timer_t beforeCullTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2007-02-21 00:46:53 +08:00
sceneView - > inheritCullSettings ( * ( sceneView - > getCamera ( ) ) ) ;
2007-02-01 06:24:20 +08:00
sceneView - > cull ( ) ;
2007-02-21 00:46:53 +08:00
2007-02-01 06:24:20 +08:00
osg : : Timer_t afterCullTick = osg : : Timer : : instance ( ) - > tick ( ) ;
if ( state - > getDynamicObjectCount ( ) = = 0 & & state - > getDynamicObjectRenderingCompletedCallback ( ) )
{
state - > getDynamicObjectRenderingCompletedCallback ( ) - > completed ( state ) ;
}
// do draw traveral
if ( aquireGPUStats )
{
checkQuery ( stats ) ;
beginQuery ( frameNumber ) ;
}
sceneView - > draw ( ) ;
double availableTime = 0.004 ; // 4 ms
2007-06-22 22:48:18 +08:00
if ( _databasePager . valid ( ) & & _databasePager - > requiresExternalCompileGLObjects ( sceneView - > getState ( ) - > getContextID ( ) ) )
2007-02-01 06:24:20 +08:00
{
_databasePager - > compileGLObjects ( * ( sceneView - > getState ( ) ) , availableTime ) ;
}
sceneView - > flushDeletedGLObjects ( availableTime ) ;
if ( aquireGPUStats )
{
endQuery ( ) ;
checkQuery ( stats ) ;
}
osg : : Timer_t afterDrawTick = osg : : Timer : : instance ( ) - > tick ( ) ;
if ( stats & & stats - > collectStats ( " rendering " ) )
{
stats - > setAttribute ( frameNumber , " Cull traversal begin time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , beforeCullTick ) ) ;
stats - > setAttribute ( frameNumber , " Cull traversal end time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , afterCullTick ) ) ;
stats - > setAttribute ( frameNumber , " Cull traversal time taken " , osg : : Timer : : instance ( ) - > delta_s ( beforeCullTick , afterCullTick ) ) ;
stats - > setAttribute ( frameNumber , " Draw traversal begin time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , afterCullTick ) ) ;
stats - > setAttribute ( frameNumber , " Draw traversal end time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , afterDrawTick ) ) ;
stats - > setAttribute ( frameNumber , " Draw traversal time taken " , osg : : Timer : : instance ( ) - > delta_s ( afterCullTick , afterDrawTick ) ) ;
}
}
2007-02-03 06:30:36 +08:00
virtual void operator ( ) ( osg : : Object * object )
2007-02-01 06:24:20 +08:00
{
2007-02-03 06:30:36 +08:00
osg : : GraphicsContext * context = dynamic_cast < osg : : GraphicsContext * > ( object ) ;
2007-02-06 19:03:13 +08:00
if ( ! context )
{
osg : : Camera * camera = dynamic_cast < osg : : Camera * > ( object ) ;
if ( camera ) cull ( ) ;
return ;
}
2007-02-03 06:30:36 +08:00
2007-02-01 06:24:20 +08:00
//osg::notify(osg::NOTICE)<<"GraphicsCall "<<std::endl;
// if (_done) return;
if ( _graphicsThreadDoesCull )
{
cull_draw ( ) ;
}
else
{
draw ( ) ;
}
}
virtual void release ( )
{
osg : : notify ( osg : : INFO ) < < " ViewerDoubleBufferedRenderingOperation::release() " < < std : : endl ;
_done = true ;
2007-02-09 06:36:16 +08:00
if ( _lockHeld [ 0 ] )
{
_lockHeld [ 0 ] = false ;
_mutex [ 0 ] . unlock ( ) ;
}
if ( _lockHeld [ 1 ] )
{
_lockHeld [ 1 ] = false ;
_mutex [ 1 ] . unlock ( ) ;
}
2007-02-01 06:24:20 +08:00
}
bool _graphicsThreadDoesCull ;
bool _done ;
unsigned int _currentCull ;
unsigned int _currentDraw ;
OpenThreads : : Mutex _mutex [ 2 ] ;
2007-02-09 06:36:16 +08:00
bool _lockHeld [ 2 ] ;
2007-02-01 06:24:20 +08:00
osg : : observer_ptr < osgUtil : : SceneView > _sceneView [ 2 ] ;
int _frameNumber [ 2 ] ;
osg : : observer_ptr < osgDB : : DatabasePager > _databasePager ;
} ;
2007-06-06 18:57:02 +08:00
Viewer : : Viewer ( )
2006-11-27 22:52:07 +08:00
{
2007-06-06 18:57:02 +08:00
constructorInit ( ) ;
}
Viewer : : Viewer ( osg : : ArgumentParser & arguments )
{
constructorInit ( ) ;
while ( arguments . read ( " --SingleThreaded " ) ) setThreadingModel ( SingleThreaded ) ;
while ( arguments . read ( " --CullDrawThreadPerContext " ) ) setThreadingModel ( CullDrawThreadPerContext ) ;
while ( arguments . read ( " --DrawThreadPerContext " ) ) setThreadingModel ( DrawThreadPerContext ) ;
while ( arguments . read ( " --CullThreadPerCameraDrawThreadPerContext " ) ) setThreadingModel ( CullThreadPerCameraDrawThreadPerContext ) ;
osg : : DisplaySettings : : instance ( ) - > readCommandLine ( arguments ) ;
osgDB : : readCommandLine ( arguments ) ;
std : : string colorStr ;
while ( arguments . read ( " --clear-color " , colorStr ) )
{
float r , g , b ;
float a = 1.0f ;
int cnt = sscanf ( colorStr . c_str ( ) , " %f,%f,%f,%f " , & r , & g , & b , & a ) ;
if ( cnt = = 3 | | cnt = = 4 ) getCamera ( ) - > setClearColor ( osg : : Vec4 ( r , g , b , a ) ) ;
else osg : : notify ( osg : : WARN ) < < " Invalid clear color \" " < < colorStr < < " \" " < < std : : endl ;
}
2007-06-13 18:38:40 +08:00
int screenNum = - 1 ;
while ( arguments . read ( " --screen " , screenNum ) ) { }
int x = - 1 , y = - 1 , width = - 1 , height = - 1 ;
while ( arguments . read ( " --window " , x , y , width , height ) ) { }
if ( width > 0 & & height > 0 )
{
if ( screenNum > = 0 ) setUpViewInWindow ( x , y , width , height , screenNum ) ;
else setUpViewInWindow ( x , y , width , height ) ;
}
else if ( screenNum > = 0 )
{
setUpViewOnSingleScreen ( screenNum ) ;
}
2007-06-06 18:57:02 +08:00
}
void Viewer : : constructorInit ( )
{
_firstFrame = true ;
_done = false ;
_keyEventSetsDone = osgGA : : GUIEventAdapter : : KEY_Escape ;
_quitEventSetsDone = true ;
_threadingModel = AutomaticSelection ;
_threadsRunning = false ;
_useMainThreadForRenderingTraversal = true ;
_endBarrierPosition = AfterSwapBuffers ;
_numWindowsOpenAtLastSetUpThreading = 0 ;
_startTick = 0 ;
2007-01-15 22:46:16 +08:00
_frameStamp = new osg : : FrameStamp ;
_frameStamp - > setFrameNumber ( 0 ) ;
_frameStamp - > setReferenceTime ( 0 ) ;
2007-01-25 20:02:51 +08:00
_frameStamp - > setSimulationTime ( 0 ) ;
2007-01-15 22:46:16 +08:00
2007-01-10 18:09:05 +08:00
_eventVisitor = new osgGA : : EventVisitor ;
_eventVisitor - > setActionAdapter ( this ) ;
2007-01-20 03:53:23 +08:00
setStats ( new osg : : Stats ( " Viewer " ) ) ;
2006-11-27 22:52:07 +08:00
}
Viewer : : ~ Viewer ( )
{
2007-01-04 00:06:12 +08:00
//osg::notify(osg::NOTICE)<<"Viewer::~Viewer()"<<std::endl;
2007-02-06 19:03:13 +08:00
Threads threads ;
getAllThreads ( threads ) ;
2007-02-06 22:38:08 +08:00
osg : : notify ( osg : : INFO ) < < " Viewer::~Viewer():: start destructor getThreads = " < < threads . size ( ) < < std : : endl ;
2007-02-06 19:03:13 +08:00
2007-01-04 19:49:15 +08:00
stopThreading ( ) ;
2006-12-23 01:46:21 +08:00
if ( _scene . valid ( ) & & _scene - > getDatabasePager ( ) )
{
_scene - > getDatabasePager ( ) - > cancel ( ) ;
_scene - > setDatabasePager ( 0 ) ;
}
2007-01-04 00:06:12 +08:00
2007-01-09 00:20:10 +08:00
Contexts contexts ;
getContexts ( contexts ) ;
// clear out all the previously assigned operations
for ( Contexts : : iterator citr = contexts . begin ( ) ;
citr ! = contexts . end ( ) ;
+ + citr )
{
( * citr ) - > close ( ) ;
}
2007-07-06 02:33:20 +08:00
2007-01-04 00:06:12 +08:00
//osg::notify(osg::NOTICE)<<"finish Viewer::~Viewer()"<<std::endl;
2007-01-09 00:20:10 +08:00
2007-02-06 19:03:13 +08:00
getAllThreads ( threads ) ;
2007-02-06 22:38:08 +08:00
osg : : notify ( osg : : INFO ) < < " Viewer::~Viewer() end destrcutor getThreads = " < < threads . size ( ) < < std : : endl ;
2007-02-06 19:03:13 +08:00
2006-11-27 22:52:07 +08:00
}
2006-11-29 19:00:02 +08:00
2007-01-05 18:59:23 +08:00
bool Viewer : : isRealized ( ) const
{
Contexts contexts ;
const_cast < Viewer * > ( this ) - > getContexts ( contexts ) ;
unsigned int numRealizedWindows = 0 ;
// clear out all the previously assigned operations
for ( Contexts : : iterator citr = contexts . begin ( ) ;
citr ! = contexts . end ( ) ;
+ + citr )
{
if ( ( * citr ) - > isRealized ( ) ) + + numRealizedWindows ;
}
return numRealizedWindows > 0 ;
}
2007-01-05 21:16:24 +08:00
int Viewer : : run ( )
2007-01-05 18:59:23 +08:00
{
// if we don't have any scene graph assigned then just return
if ( ! getSceneData ( ) )
{
osg : : notify ( osg : : NOTICE ) < < " Warning: Viewer::run() called without a scene graph being assigned to the viewer, cannot run. " < < std : : endl ;
2007-01-05 21:16:24 +08:00
return 1 ;
2007-01-05 18:59:23 +08:00
}
2007-05-27 22:52:43 +08:00
if ( ! getCameraManipulator ( ) & & getCamera ( ) - > getAllowEventFocus ( ) )
2007-01-05 18:59:23 +08:00
{
setCameraManipulator ( new osgGA : : TrackballManipulator ( ) ) ;
}
if ( ! isRealized ( ) )
{
realize ( ) ;
}
2007-02-14 22:36:38 +08:00
#if 0
2007-01-05 18:59:23 +08:00
while ( ! done ( ) )
{
frame ( ) ;
}
2007-02-09 21:36:44 +08:00
# else
2007-02-14 22:36:38 +08:00
const char * str = getenv ( " OSG_RUN_FRAME_COUNT " ) ;
if ( str )
2007-02-09 21:36:44 +08:00
{
2007-02-14 22:36:38 +08:00
int runTillFrameNumber = atoi ( str ) ;
while ( ! done ( ) & & getFrameStamp ( ) - > getFrameNumber ( ) < runTillFrameNumber )
{
frame ( ) ;
}
2007-02-09 21:36:44 +08:00
}
2007-02-14 22:36:38 +08:00
else
{
while ( ! done ( ) )
{
frame ( ) ;
}
}
2007-02-09 21:36:44 +08:00
# endif
2007-01-05 21:16:24 +08:00
return 0 ;
2007-01-05 18:59:23 +08:00
}
2007-01-15 22:46:16 +08:00
void Viewer : : setStartTick ( osg : : Timer_t tick )
{
_startTick = tick ;
Contexts contexts ;
getContexts ( contexts , false ) ;
2007-01-16 16:56:33 +08:00
getEventQueue ( ) - > setStartTick ( _startTick ) ;
2007-01-15 22:46:16 +08:00
for ( Contexts : : iterator citr = contexts . begin ( ) ;
citr ! = contexts . end ( ) ;
+ + citr )
{
osgViewer : : GraphicsWindow * gw = dynamic_cast < osgViewer : : GraphicsWindow * > ( * citr ) ;
if ( gw )
{
2007-01-16 16:56:33 +08:00
gw - > getEventQueue ( ) - > setStartTick ( _startTick ) ;
2007-01-15 22:46:16 +08:00
}
}
}
void Viewer : : setReferenceTime ( double time )
2007-01-06 05:19:01 +08:00
{
2007-01-15 22:46:16 +08:00
osg : : Timer_t tick = osg : : Timer : : instance ( ) - > tick ( ) ;
double currentTime = osg : : Timer : : instance ( ) - > delta_s ( _startTick , tick ) ;
double delta_ticks = ( time - currentTime ) * ( osg : : Timer : : instance ( ) - > getSecondsPerTick ( ) ) ;
if ( delta_ticks > = 0 ) tick + = osg : : Timer_t ( delta_ticks ) ;
else tick - = osg : : Timer_t ( - delta_ticks ) ;
// assign the new start tick
setStartTick ( tick ) ;
2007-01-06 05:19:01 +08:00
}
2007-01-15 22:46:16 +08:00
void Viewer : : setSceneData ( osg : : Node * node )
2007-01-06 05:19:01 +08:00
{
2007-01-15 22:46:16 +08:00
_scene = new osgViewer : : Scene ;
_scene - > setSceneData ( node ) ;
_scene - > setFrameStamp ( _frameStamp . get ( ) ) ;
2007-05-18 18:33:56 +08:00
computeActiveCoordinateSystemNodePath ( ) ;
2007-01-15 22:46:16 +08:00
setReferenceTime ( 0.0 ) ;
assignSceneDataToCameras ( ) ;
setUpRenderingSupport ( ) ;
2007-01-06 05:19:01 +08:00
}
2007-06-03 17:34:28 +08:00
GraphicsWindowEmbedded * Viewer : : setUpViewerAsEmbeddedInWindow ( int x , int y , int width , int height )
{
setThreadingModel ( SingleThreaded ) ;
osgViewer : : GraphicsWindowEmbedded * gw = new osgViewer : : GraphicsWindowEmbedded ( x , y , width , height ) ;
getCamera ( ) - > setViewport ( new osg : : Viewport ( 0 , 0 , width , height ) ) ;
2007-06-23 19:21:54 +08:00
getCamera ( ) - > setProjectionMatrixAsPerspective ( 30.0f , static_cast < double > ( width ) / static_cast < double > ( height ) , 1.0f , 10000.0f ) ;
2007-06-03 17:34:28 +08:00
getCamera ( ) - > setGraphicsContext ( gw ) ;
return gw ;
}
2007-01-03 01:39:31 +08:00
void Viewer : : setThreadingModel ( ThreadingModel threadingModel )
{
2007-01-04 19:49:15 +08:00
if ( _threadingModel = = threadingModel ) return ;
2006-12-21 05:13:29 +08:00
2007-02-01 19:07:53 +08:00
if ( _threadsRunning ) stopThreading ( ) ;
2006-12-21 05:13:29 +08:00
2007-01-04 19:49:15 +08:00
_threadingModel = threadingModel ;
2006-12-23 01:46:21 +08:00
2007-02-08 20:20:40 +08:00
if ( isRealized ( ) & & _threadingModel ! = SingleThreaded ) startThreading ( ) ;
2006-12-23 01:46:21 +08:00
}
2007-02-08 20:14:26 +08:00
void Viewer : : setUpThreading ( )
{
Contexts contexts ;
getContexts ( contexts ) ;
_numWindowsOpenAtLastSetUpThreading = contexts . size ( ) ;
if ( _threadingModel = = SingleThreaded )
{
if ( _threadsRunning ) stopThreading ( ) ;
else
{
// we'll set processor affinity here to help single threaded apps
// with multiple processor cores, and using the database pager.
int numProcessors = OpenThreads : : GetNumberOfProcessors ( ) ;
bool affinity = numProcessors > 1 ;
if ( affinity )
{
OpenThreads : : SetProcessorAffinityOfCurrentThread ( 0 ) ;
if ( _scene . valid ( ) & & _scene - > getDatabasePager ( ) )
{
_scene - > getDatabasePager ( ) - > setProcessorAffinity ( 1 ) ;
}
}
}
}
else
{
if ( ! _threadsRunning ) startThreading ( ) ;
}
}
2007-01-30 06:44:29 +08:00
void Viewer : : setUseMainThreadForRenderingTraversals ( bool flag )
{
if ( _useMainThreadForRenderingTraversal = = flag ) return ;
2007-02-01 19:07:53 +08:00
if ( _threadsRunning ) stopThreading ( ) ;
2007-01-30 06:44:29 +08:00
_useMainThreadForRenderingTraversal = flag ;
if ( _threadingModel ! = SingleThreaded ) startThreading ( ) ;
}
2007-01-13 05:05:39 +08:00
void Viewer : : setEndBarrierPosition ( BarrierPosition bp )
{
if ( _endBarrierPosition = = bp ) return ;
2007-02-01 19:07:53 +08:00
if ( _threadsRunning ) stopThreading ( ) ;
2007-01-13 05:05:39 +08:00
_endBarrierPosition = bp ;
if ( _threadingModel ! = SingleThreaded ) startThreading ( ) ;
}
2007-01-04 19:49:15 +08:00
void Viewer : : stopThreading ( )
2007-01-02 20:50:57 +08:00
{
2007-02-01 19:07:53 +08:00
if ( ! _threadsRunning ) return ;
2007-01-02 20:50:57 +08:00
2007-02-06 22:38:08 +08:00
osg : : notify ( osg : : INFO ) < < " Viewer::stopThreading() - stopping threading " < < std : : endl ;
2007-01-02 20:50:57 +08:00
2007-01-04 19:49:15 +08:00
Contexts contexts ;
getContexts ( contexts ) ;
2007-01-02 20:50:57 +08:00
2007-02-06 19:03:13 +08:00
Cameras cameras ;
getCameras ( cameras ) ;
Contexts : : iterator gcitr ;
Cameras : : iterator citr ;
2007-02-01 06:24:20 +08:00
// reset any double buffer graphics objects
2007-02-06 19:03:13 +08:00
for ( gcitr = contexts . begin ( ) ;
gcitr ! = contexts . end ( ) ;
+ + gcitr )
2007-02-01 06:24:20 +08:00
{
2007-02-06 19:03:13 +08:00
osg : : GraphicsContext * gc = ( * gcitr ) ;
2007-02-01 06:24:20 +08:00
2007-02-05 22:56:41 +08:00
OpenThreads : : ScopedLock < OpenThreads : : Mutex > lock ( * ( gc - > getOperationsMutex ( ) ) ) ;
2007-02-01 06:24:20 +08:00
osg : : GraphicsContext : : OperationQueue & operations = gc - > getOperationsQueue ( ) ;
for ( osg : : GraphicsContext : : OperationQueue : : iterator oitr = operations . begin ( ) ;
oitr ! = operations . end ( ) ;
+ + oitr )
{
ViewerDoubleBufferedRenderingOperation * vdbro = dynamic_cast < ViewerDoubleBufferedRenderingOperation * > ( oitr - > get ( ) ) ;
if ( vdbro )
{
vdbro - > release ( ) ;
}
}
}
2007-01-04 19:49:15 +08:00
// delete all the graphics threads.
2007-02-06 19:03:13 +08:00
for ( gcitr = contexts . begin ( ) ;
gcitr ! = contexts . end ( ) ;
+ + gcitr )
2007-01-02 20:50:57 +08:00
{
2007-02-06 19:03:13 +08:00
( * gcitr ) - > setGraphicsThread ( 0 ) ;
2007-01-02 20:50:57 +08:00
}
2007-02-06 19:03:13 +08:00
// delete all the camera threads.
for ( citr = cameras . begin ( ) ;
citr ! = cameras . end ( ) ;
2007-02-01 06:24:20 +08:00
+ + citr )
{
2007-02-06 19:03:13 +08:00
( * citr ) - > setCameraThread ( 0 ) ;
}
// reset any double buffer graphics objects
for ( gcitr = contexts . begin ( ) ;
gcitr ! = contexts . end ( ) ;
+ + gcitr )
{
osg : : GraphicsContext * gc = ( * gcitr ) ;
2007-02-01 06:24:20 +08:00
2007-02-05 22:56:41 +08:00
OpenThreads : : ScopedLock < OpenThreads : : Mutex > lock ( * ( gc - > getOperationsMutex ( ) ) ) ;
2007-02-01 06:24:20 +08:00
osg : : GraphicsContext : : OperationQueue & operations = gc - > getOperationsQueue ( ) ;
for ( osg : : GraphicsContext : : OperationQueue : : iterator oitr = operations . begin ( ) ;
oitr ! = operations . end ( ) ;
+ + oitr )
{
ViewerDoubleBufferedRenderingOperation * vdbro = dynamic_cast < ViewerDoubleBufferedRenderingOperation * > ( oitr - > get ( ) ) ;
if ( vdbro )
{
vdbro - > setGraphicsThreadDoesCull ( true ) ;
vdbro - > _done = false ;
}
}
}
2007-02-08 19:24:29 +08:00
int numProcessors = OpenThreads : : GetNumberOfProcessors ( ) ;
bool affinity = numProcessors > 1 ;
if ( affinity )
{
OpenThreads : : SetProcessorAffinityOfCurrentThread ( 0 ) ;
if ( _scene . valid ( ) & & _scene - > getDatabasePager ( ) )
{
_scene - > getDatabasePager ( ) - > setProcessorAffinity ( 1 ) ;
}
}
2007-02-01 19:07:53 +08:00
_threadsRunning = false ;
2007-01-04 19:49:15 +08:00
_startRenderingBarrier = 0 ;
_endRenderingDispatchBarrier = 0 ;
2007-02-01 06:24:20 +08:00
_endDynamicDrawBlock = 0 ;
2007-02-08 20:14:26 +08:00
_numWindowsOpenAtLastSetUpThreading = contexts . size ( ) ;
2007-02-06 22:38:08 +08:00
osg : : notify ( osg : : INFO ) < < " Viewer::stopThreading() - stopped threading. " < < std : : endl ;
2007-01-04 19:49:15 +08:00
}
2006-12-23 01:46:21 +08:00
// Compile operation, that compile OpenGL objects.
2007-07-14 03:24:50 +08:00
struct ViewerCompileOperation : public osg : : GraphicsOperation
2006-12-23 01:46:21 +08:00
{
2007-01-16 16:56:33 +08:00
ViewerCompileOperation ( osg : : Node * scene ) :
2007-07-14 03:24:50 +08:00
osg : : GraphicsOperation ( " Compile " , false ) ,
2006-12-23 01:46:21 +08:00
_scene ( scene )
{
}
2007-07-14 03:24:50 +08:00
virtual void operator ( ) ( osg : : GraphicsContext * context )
2006-12-23 01:46:21 +08:00
{
// OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mutex);
// osg::notify(osg::NOTICE)<<"Compile "<<context<<" "<<OpenThreads::Thread::CurrentThread()<<std::endl;
2007-02-18 22:21:16 +08:00
// context->makeCurrent();
2007-05-01 14:28:20 +08:00
context - > getState ( ) - > initializeExtensionProcs ( ) ;
2006-12-23 01:46:21 +08:00
osgUtil : : GLObjectsVisitor compileVisitor ;
compileVisitor . setState ( context - > getState ( ) ) ;
// do the compile traversal
2007-01-15 22:46:16 +08:00
if ( _scene . valid ( ) ) _scene - > accept ( compileVisitor ) ;
2006-12-23 01:46:21 +08:00
// osg::notify(osg::NOTICE)<<"Done Compile "<<context<<" "<<OpenThreads::Thread::CurrentThread()<<std::endl;
}
osg : : ref_ptr < osg : : Node > _scene ;
} ;
// Draw operation, that does a draw on the scene graph.
2007-07-14 03:24:50 +08:00
struct ViewerRunOperations : public osg : : GraphicsOperation
2006-12-23 01:46:21 +08:00
{
2007-01-16 16:56:33 +08:00
ViewerRunOperations ( ) :
2007-07-14 03:24:50 +08:00
osg : : GraphicsOperation ( " RunOperation " , true )
2006-12-23 01:46:21 +08:00
{
}
2007-07-14 03:24:50 +08:00
virtual void operator ( ) ( osg : : GraphicsContext * context )
2006-12-23 01:46:21 +08:00
{
2007-02-03 06:30:36 +08:00
context - > runOperations ( ) ;
2006-12-23 01:46:21 +08:00
}
} ;
2007-02-14 00:03:35 +08:00
static osg : : ApplicationUsageProxy Viewer_e0 ( osg : : ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_THREADING <value> " , " Set the threading model using by Viewer, <value> can be SingleThreaded, CullDrawThreadPerContext, DrawThreadPerContext or CullThreadPerCameraDrawThreadPerContext. " ) ;
2007-06-13 19:09:31 +08:00
static osg : : ApplicationUsageProxy Viewer_e1 ( osg : : ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_SCREEN <value> " , " Set the default screen that windows should open up on. " ) ;
static osg : : ApplicationUsageProxy Viewer_e2 ( osg : : ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_WINDOW x y width height " , " Set the default window dimensions that windows should open up on. " ) ;
2007-02-14 00:03:35 +08:00
2007-02-06 22:38:08 +08:00
Viewer : : ThreadingModel Viewer : : suggestBestThreadingModel ( )
{
2007-02-14 00:03:35 +08:00
const char * str = getenv ( " OSG_THREADING " ) ;
if ( str )
{
if ( strcmp ( str , " SingleThreaded " ) = = 0 ) return SingleThreaded ;
else if ( strcmp ( str , " CullDrawThreadPerContext " ) = = 0 ) return CullDrawThreadPerContext ;
2007-02-14 19:24:42 +08:00
else if ( strcmp ( str , " DrawThreadPerContext " ) = = 0 ) return DrawThreadPerContext ;
2007-02-14 00:03:35 +08:00
else if ( strcmp ( str , " CullThreadPerCameraDrawThreadPerContext " ) = = 0 ) return CullThreadPerCameraDrawThreadPerContext ;
}
2007-02-06 22:38:08 +08:00
Contexts contexts ;
getContexts ( contexts ) ;
if ( contexts . empty ( ) ) return SingleThreaded ;
2007-06-07 01:01:37 +08:00
#if 0
2007-02-15 23:06:18 +08:00
# ifdef _WIN32
// temporary hack to disable multi-threading under Windows till we find good solutions for
// crashes that users are seeing.
return SingleThreaded ;
2007-06-07 01:01:37 +08:00
# endif
2007-02-15 23:06:18 +08:00
# endif
2007-02-06 22:38:08 +08:00
Cameras cameras ;
getCameras ( cameras ) ;
if ( cameras . empty ( ) ) return SingleThreaded ;
int numProcessors = OpenThreads : : GetNumberOfProcessors ( ) ;
2007-02-18 22:21:16 +08:00
2007-02-06 22:38:08 +08:00
if ( contexts . size ( ) = = 1 )
{
if ( numProcessors = = 1 ) return SingleThreaded ;
else return DrawThreadPerContext ;
}
if ( numProcessors > = static_cast < int > ( cameras . size ( ) + contexts . size ( ) ) )
{
return CullThreadPerCameraDrawThreadPerContext ;
}
# if 1
return DrawThreadPerContext ;
# else
return CullDrawThreadPerContext ;
# endif
}
2007-01-04 19:49:15 +08:00
void Viewer : : startThreading ( )
2006-12-23 01:46:21 +08:00
{
2007-02-01 19:07:53 +08:00
if ( _threadsRunning ) return ;
2007-02-06 19:03:13 +08:00
2007-05-22 02:46:57 +08:00
// osg::notify(osg::NOTICE)<<"Viewer::startThreading() - starting threading"<<std::endl;
2007-02-06 19:03:13 +08:00
// release any context held by the main thread.
releaseContext ( ) ;
2007-02-01 19:07:53 +08:00
2007-02-06 22:38:08 +08:00
_threadingModel = _threadingModel = = AutomaticSelection ? suggestBestThreadingModel ( ) : _threadingModel ;
2007-02-06 19:03:13 +08:00
Contexts contexts ;
getContexts ( contexts ) ;
2007-05-22 02:46:57 +08:00
osg : : notify ( osg : : INFO ) < < " Viewer::startThreading() - contexts.size()= " < < contexts . size ( ) < < std : : endl ;
2006-12-23 01:46:21 +08:00
2007-02-06 19:03:13 +08:00
Cameras cameras ;
getCameras ( cameras ) ;
2007-01-04 19:49:15 +08:00
2007-02-08 20:14:26 +08:00
unsigned int numThreadsOnBarrier = 0 ;
2007-02-06 19:03:13 +08:00
switch ( _threadingModel )
2007-01-04 19:49:15 +08:00
{
2007-02-06 19:03:13 +08:00
case ( SingleThreaded ) :
2007-02-08 20:14:26 +08:00
numThreadsOnBarrier = 1 ;
2007-02-06 19:03:13 +08:00
return ;
2007-02-06 22:38:08 +08:00
case ( CullDrawThreadPerContext ) :
2007-02-08 20:14:26 +08:00
numThreadsOnBarrier = contexts . size ( ) + 1 ;
2007-02-06 19:03:13 +08:00
break ;
2007-02-06 22:38:08 +08:00
case ( DrawThreadPerContext ) :
2007-02-08 20:14:26 +08:00
numThreadsOnBarrier = 1 ;
2007-02-06 22:38:08 +08:00
break ;
case ( CullThreadPerCameraDrawThreadPerContext ) :
2007-02-08 20:14:26 +08:00
numThreadsOnBarrier = _useMainThreadForRenderingTraversal ? cameras . size ( ) : cameras . size ( ) + 1 ;
2007-02-06 19:03:13 +08:00
break ;
2007-02-06 22:38:08 +08:00
default :
osg : : notify ( osg : : NOTICE ) < < " Error: Threading model not selected " < < std : : endl ;
return ;
2007-01-04 19:49:15 +08:00
}
2007-01-05 05:18:03 +08:00
2007-01-05 00:49:58 +08:00
// using multi-threading so make sure that new objects are allocated with thread safe ref/unref
osg : : Referenced : : setThreadSafeReferenceCounting ( true ) ;
if ( getSceneData ( ) )
{
2007-01-05 05:18:03 +08:00
osg : : notify ( osg : : INFO ) < < " Making scene thread safe " < < std : : endl ;
2007-01-05 00:49:58 +08:00
// make sure that existing scene graph objects are allocated with thread safe ref/unref
getSceneData ( ) - > setThreadSafeRefUnref ( true ) ;
// update the scene graph so that it has enough GL object buffer memory for the graphics contexts that will be using it.
getSceneData ( ) - > resizeGLObjectBuffers ( osg : : DisplaySettings : : instance ( ) - > getMaxNumberOfGraphicsContexts ( ) ) ;
}
2006-12-27 01:38:47 +08:00
2007-02-06 19:03:13 +08:00
int numProcessors = OpenThreads : : GetNumberOfProcessors ( ) ;
2007-02-08 19:24:29 +08:00
bool affinity = numProcessors > 1 ;
2007-02-01 06:24:20 +08:00
Contexts : : iterator citr ;
unsigned int numViewerDoubleBufferedRenderingOperation = 0 ;
2007-02-06 22:38:08 +08:00
bool graphicsThreadsDoesCull = _threadingModel = = CullDrawThreadPerContext ;
2007-02-01 06:24:20 +08:00
// reset any double buffer graphics objects
for ( citr = contexts . begin ( ) ;
citr ! = contexts . end ( ) ;
+ + citr )
{
osg : : GraphicsContext * gc = ( * citr ) ;
2007-02-05 22:56:41 +08:00
OpenThreads : : ScopedLock < OpenThreads : : Mutex > lock ( * ( gc - > getOperationsMutex ( ) ) ) ;
2007-02-01 06:24:20 +08:00
osg : : GraphicsContext : : OperationQueue & operations = gc - > getOperationsQueue ( ) ;
for ( osg : : GraphicsContext : : OperationQueue : : iterator oitr = operations . begin ( ) ;
oitr ! = operations . end ( ) ;
+ + oitr )
{
ViewerDoubleBufferedRenderingOperation * vdbro = dynamic_cast < ViewerDoubleBufferedRenderingOperation * > ( oitr - > get ( ) ) ;
if ( vdbro )
{
2007-02-06 22:38:08 +08:00
vdbro - > setGraphicsThreadDoesCull ( graphicsThreadsDoesCull ) ;
2007-02-01 06:24:20 +08:00
vdbro - > _done = false ;
+ + numViewerDoubleBufferedRenderingOperation ;
}
}
2007-01-30 06:44:29 +08:00
2007-02-01 06:24:20 +08:00
}
2007-01-30 06:44:29 +08:00
2007-02-06 22:38:08 +08:00
if ( _threadingModel = = CullDrawThreadPerContext )
2007-01-30 06:44:29 +08:00
{
2007-02-06 19:03:13 +08:00
_startRenderingBarrier = 0 ;
_endRenderingDispatchBarrier = 0 ;
2007-02-01 06:24:20 +08:00
_endDynamicDrawBlock = 0 ;
2007-01-30 06:44:29 +08:00
}
2007-02-06 22:38:08 +08:00
else if ( _threadingModel = = DrawThreadPerContext | |
_threadingModel = = CullThreadPerCameraDrawThreadPerContext )
2007-01-30 06:44:29 +08:00
{
2007-02-01 06:24:20 +08:00
_startRenderingBarrier = 0 ;
_endRenderingDispatchBarrier = 0 ;
_endDynamicDrawBlock = new EndOfDynamicDrawBlock ( numViewerDoubleBufferedRenderingOperation ) ;
2007-02-14 01:39:42 +08:00
if ( ! osg : : Referenced : : getDeleteHandler ( ) ) osg : : Referenced : : setDeleteHandler ( new osg : : DeleteHandler ( 2 ) ) ;
else osg : : Referenced : : getDeleteHandler ( ) - > setNumFramesToRetainObjects ( 2 ) ;
2007-02-14 19:24:42 +08:00
// now make sure the scene graph is set up with the correct DataVariance to protect the dyamic elements of
// the scene graph from being run in parallel.
osgUtil : : Optimizer : : StaticObjectDetectionVisitor sodv ;
getSceneData ( ) - > accept ( sodv ) ;
2007-01-30 06:44:29 +08:00
}
2007-02-06 19:03:13 +08:00
2007-02-08 20:14:26 +08:00
if ( numThreadsOnBarrier > 1 )
2007-02-06 19:03:13 +08:00
{
2007-02-08 20:14:26 +08:00
_startRenderingBarrier = new osg : : BarrierOperation ( numThreadsOnBarrier , osg : : BarrierOperation : : NO_OPERATION ) ;
_endRenderingDispatchBarrier = new osg : : BarrierOperation ( numThreadsOnBarrier , osg : : BarrierOperation : : NO_OPERATION ) ;
2007-02-06 19:03:13 +08:00
}
2007-01-30 06:44:29 +08:00
2007-01-04 19:49:15 +08:00
2007-02-06 19:03:13 +08:00
osg : : ref_ptr < osg : : BarrierOperation > swapReadyBarrier = contexts . empty ( ) ? 0 : new osg : : BarrierOperation ( contexts . size ( ) , osg : : BarrierOperation : : NO_OPERATION ) ;
2007-01-04 19:49:15 +08:00
2007-02-06 19:03:13 +08:00
osg : : ref_ptr < osg : : SwapBuffersOperation > swapOp = new osg : : SwapBuffersOperation ( ) ;
2007-01-04 19:49:15 +08:00
2007-02-07 00:23:19 +08:00
typedef std : : map < OpenThreads : : Thread * , int > ThreadAffinityMap ;
ThreadAffinityMap threadAffinityMap ;
2007-02-06 19:03:13 +08:00
unsigned int processNum = 1 ;
for ( citr = contexts . begin ( ) ;
2007-01-04 19:49:15 +08:00
citr ! = contexts . end ( ) ;
2007-02-06 19:03:13 +08:00
+ + citr , + + processNum )
2007-01-04 19:49:15 +08:00
{
osg : : GraphicsContext * gc = ( * citr ) ;
2007-01-30 06:44:29 +08:00
gc - > getState ( ) - > setDynamicObjectRenderingCompletedCallback ( _endDynamicDrawBlock . get ( ) ) ;
2007-01-04 19:49:15 +08:00
// create the a graphics thread for this context
gc - > createGraphicsThread ( ) ;
if ( affinity ) gc - > getGraphicsThread ( ) - > setProcessorAffinity ( processNum % numProcessors ) ;
2007-02-07 00:23:19 +08:00
threadAffinityMap [ gc - > getGraphicsThread ( ) ] = processNum % numProcessors ;
2007-01-04 19:49:15 +08:00
2007-01-16 16:56:33 +08:00
gc - > getGraphicsThread ( ) - > add ( new ViewerCompileOperation ( getSceneData ( ) ) ) ;
2007-01-04 19:49:15 +08:00
// add the startRenderingBarrier
2007-02-06 22:38:08 +08:00
if ( _threadingModel = = CullDrawThreadPerContext & & _startRenderingBarrier . valid ( ) ) gc - > getGraphicsThread ( ) - > add ( _startRenderingBarrier . get ( ) ) ;
2007-01-04 19:49:15 +08:00
// add the rendering operation itself.
2007-01-16 16:56:33 +08:00
gc - > getGraphicsThread ( ) - > add ( new ViewerRunOperations ( ) ) ;
2006-12-23 01:46:21 +08:00
2007-02-06 22:38:08 +08:00
if ( _threadingModel = = CullDrawThreadPerContext & & _endBarrierPosition = = BeforeSwapBuffers & & _endRenderingDispatchBarrier . valid ( ) )
2007-01-13 05:05:39 +08:00
{
// add the endRenderingDispatchBarrier
gc - > getGraphicsThread ( ) - > add ( _endRenderingDispatchBarrier . get ( ) ) ;
}
2007-01-03 01:39:31 +08:00
2007-02-06 19:03:13 +08:00
if ( swapReadyBarrier . valid ( ) ) gc - > getGraphicsThread ( ) - > add ( swapReadyBarrier . get ( ) ) ;
2007-01-04 19:49:15 +08:00
// add the swap buffers
gc - > getGraphicsThread ( ) - > add ( swapOp . get ( ) ) ;
2007-02-06 22:38:08 +08:00
if ( _threadingModel = = CullDrawThreadPerContext & & _endBarrierPosition = = AfterSwapBuffers & & _endRenderingDispatchBarrier . valid ( ) )
2007-01-13 05:05:39 +08:00
{
// add the endRenderingDispatchBarrier
gc - > getGraphicsThread ( ) - > add ( _endRenderingDispatchBarrier . get ( ) ) ;
}
2007-02-06 19:03:13 +08:00
2007-01-04 19:49:15 +08:00
}
2007-02-06 19:03:13 +08:00
2007-02-08 20:14:26 +08:00
if ( _threadingModel = = CullThreadPerCameraDrawThreadPerContext & & numThreadsOnBarrier > 1 )
2007-01-15 22:46:16 +08:00
{
2007-02-06 19:03:13 +08:00
Cameras : : iterator camItr = cameras . begin ( ) ;
if ( _useMainThreadForRenderingTraversal ) + + camItr ;
for ( ;
camItr ! = cameras . end ( ) ;
+ + camItr , + + processNum )
{
osg : : Camera * camera = * camItr ;
camera - > createCameraThread ( ) ;
if ( affinity ) camera - > getCameraThread ( ) - > setProcessorAffinity ( processNum % numProcessors ) ;
2007-02-07 00:23:19 +08:00
threadAffinityMap [ camera - > getCameraThread ( ) ] = processNum % numProcessors ;
2007-02-08 20:14:26 +08:00
2007-02-06 19:03:13 +08:00
osg : : GraphicsContext * gc = camera - > getGraphicsContext ( ) ;
// add the startRenderingBarrier
if ( _startRenderingBarrier . valid ( ) ) camera - > getCameraThread ( ) - > add ( _startRenderingBarrier . get ( ) ) ;
OpenThreads : : ScopedLock < OpenThreads : : Mutex > lock ( * ( gc - > getOperationsMutex ( ) ) ) ;
osg : : GraphicsContext : : OperationQueue & operations = gc - > getOperationsQueue ( ) ;
for ( osg : : GraphicsContext : : OperationQueue : : iterator oitr = operations . begin ( ) ;
oitr ! = operations . end ( ) ;
+ + oitr )
{
ViewerDoubleBufferedRenderingOperation * vdbro = dynamic_cast < ViewerDoubleBufferedRenderingOperation * > ( oitr - > get ( ) ) ;
if ( vdbro & & vdbro - > getCamera ( ) = = camera )
{
camera - > getCameraThread ( ) - > add ( vdbro ) ;
}
}
if ( _endRenderingDispatchBarrier . valid ( ) )
{
// add the endRenderingDispatchBarrier
gc - > getGraphicsThread ( ) - > add ( _endRenderingDispatchBarrier . get ( ) ) ;
}
}
for ( camItr = cameras . begin ( ) ;
camItr ! = cameras . end ( ) ;
2007-02-07 00:23:19 +08:00
+ + camItr )
2007-02-06 19:03:13 +08:00
{
osg : : Camera * camera = * camItr ;
if ( camera - > getCameraThread ( ) & & ! camera - > getCameraThread ( ) - > isRunning ( ) )
{
osg : : notify ( osg : : INFO ) < < " camera->getCameraThread()-> " < < camera - > getCameraThread ( ) < < std : : endl ;
camera - > getCameraThread ( ) - > startThread ( ) ;
}
}
2007-01-15 22:46:16 +08:00
}
2007-02-06 19:03:13 +08:00
2007-02-08 19:24:29 +08:00
if ( affinity )
{
OpenThreads : : SetProcessorAffinityOfCurrentThread ( 0 ) ;
if ( _scene . valid ( ) & & _scene - > getDatabasePager ( ) )
{
#if 0
//_scene->getDatabasePager()->setProcessorAffinity(1);
# else
_scene - > getDatabasePager ( ) - > setProcessorAffinity ( 0 ) ;
# endif
}
}
2007-02-07 00:23:19 +08:00
#if 0
if ( affinity )
{
for ( ThreadAffinityMap : : iterator titr = threadAffinityMap . begin ( ) ;
titr ! = threadAffinityMap . end ( ) ;
+ + titr )
{
titr - > first - > setProcessorAffinity ( titr - > second ) ;
}
}
# endif
2007-01-04 19:49:15 +08:00
for ( citr = contexts . begin ( ) ;
citr ! = contexts . end ( ) ;
+ + citr )
{
osg : : GraphicsContext * gc = ( * citr ) ;
if ( gc - > getGraphicsThread ( ) & & ! gc - > getGraphicsThread ( ) - > isRunning ( ) )
2007-01-04 00:06:12 +08:00
{
2007-02-01 06:24:20 +08:00
osg : : notify ( osg : : INFO ) < < " gc->getGraphicsThread()->startThread() " < < gc - > getGraphicsThread ( ) < < std : : endl ;
2007-01-04 19:49:15 +08:00
gc - > getGraphicsThread ( ) - > startThread ( ) ;
// OpenThreads::Thread::YieldCurrentThread();
2007-01-04 00:06:12 +08:00
}
2007-01-04 19:49:15 +08:00
}
2007-02-01 06:24:20 +08:00
2007-02-01 19:07:53 +08:00
_threadsRunning = true ;
2007-02-08 20:14:26 +08:00
_numWindowsOpenAtLastSetUpThreading = contexts . size ( ) ;
2007-02-01 19:07:53 +08:00
2007-02-01 06:24:20 +08:00
osg : : notify ( osg : : INFO ) < < " Set up threading " < < std : : endl ;
2007-01-04 19:49:15 +08:00
}
void Viewer : : checkWindowStatus ( )
{
2007-02-08 20:14:26 +08:00
Contexts contexts ;
getContexts ( contexts ) ;
2007-05-22 02:17:54 +08:00
2007-05-22 02:46:57 +08:00
// osg::notify(osg::NOTICE)<<"Viewer::checkWindowStatus() - "<<contexts.size()<<std::endl;
2007-05-22 02:17:54 +08:00
if ( contexts . size ( ) = = 0 )
{
_done = true ;
if ( areThreadsRunning ( ) ) stopThreading ( ) ;
}
2007-01-04 19:49:15 +08:00
}
2006-12-23 01:46:21 +08:00
2007-04-21 00:17:48 +08:00
struct LessGraphicsContext
{
bool operator ( ) ( const osg : : GraphicsContext * lhs , const osg : : GraphicsContext * rhs ) const
{
int screenLeft = lhs - > getTraits ( ) ? lhs - > getTraits ( ) - > screenNum : 0 ;
int screenRight = rhs - > getTraits ( ) ? rhs - > getTraits ( ) - > screenNum : 0 ;
if ( screenLeft < screenRight ) return true ;
if ( screenLeft > screenRight ) return false ;
screenLeft = lhs - > getTraits ( ) ? lhs - > getTraits ( ) - > x : 0 ;
screenRight = rhs - > getTraits ( ) ? rhs - > getTraits ( ) - > x : 0 ;
if ( screenLeft < screenRight ) return true ;
if ( screenLeft > screenRight ) return false ;
screenLeft = lhs - > getTraits ( ) ? lhs - > getTraits ( ) - > y : 0 ;
screenRight = rhs - > getTraits ( ) ? rhs - > getTraits ( ) - > y : 0 ;
if ( screenLeft < screenRight ) return true ;
if ( screenLeft > screenRight ) return false ;
return lhs < rhs ;
}
} ;
2007-01-04 19:49:15 +08:00
void Viewer : : getContexts ( Contexts & contexts , bool onlyValid )
{
typedef std : : set < osg : : GraphicsContext * > ContextSet ;
ContextSet contextSet ;
if ( _camera . valid ( ) & &
_camera - > getGraphicsContext ( ) & &
( _camera - > getGraphicsContext ( ) - > valid ( ) | | ! onlyValid ) )
{
contextSet . insert ( _camera - > getGraphicsContext ( ) ) ;
}
for ( unsigned int i = 0 ; i < getNumSlaves ( ) ; + + i )
{
Slave & slave = getSlave ( i ) ;
if ( slave . _camera . valid ( ) & &
slave . _camera - > getGraphicsContext ( ) & &
( slave . _camera - > getGraphicsContext ( ) - > valid ( ) | | ! onlyValid ) )
{
contextSet . insert ( slave . _camera - > getGraphicsContext ( ) ) ;
2006-12-23 01:46:21 +08:00
}
}
2007-01-04 19:49:15 +08:00
contexts . clear ( ) ;
contexts . reserve ( contextSet . size ( ) ) ;
for ( ContextSet : : iterator itr = contextSet . begin ( ) ;
itr ! = contextSet . end ( ) ;
+ + itr )
{
contexts . push_back ( const_cast < osg : : GraphicsContext * > ( * itr ) ) ;
}
2007-04-21 00:17:48 +08:00
if ( contexts . size ( ) > = 2 )
{
std : : sort ( contexts . begin ( ) , contexts . end ( ) , LessGraphicsContext ( ) ) ;
}
2007-01-04 19:49:15 +08:00
}
void Viewer : : getWindows ( Windows & windows , bool onlyValid )
{
windows . clear ( ) ;
Contexts contexts ;
getContexts ( contexts , onlyValid ) ;
for ( Contexts : : iterator itr = contexts . begin ( ) ;
itr ! = contexts . end ( ) ;
+ + itr )
{
osgViewer : : GraphicsWindow * gw = dynamic_cast < osgViewer : : GraphicsWindow * > ( * itr ) ;
if ( gw ) windows . push_back ( gw ) ;
}
}
2007-01-30 19:40:23 +08:00
void Viewer : : getCameras ( Cameras & cameras , bool onlyActive )
{
cameras . clear ( ) ;
2007-05-22 02:46:57 +08:00
if ( ! onlyActive | | ( _camera - > getGraphicsContext ( ) & & _camera - > getGraphicsContext ( ) - > valid ( ) ) ) cameras . push_back ( _camera . get ( ) ) ;
2007-01-30 19:40:23 +08:00
for ( Slaves : : iterator itr = _slaves . begin ( ) ;
itr ! = _slaves . end ( ) ;
+ + itr )
{
2007-05-22 02:46:57 +08:00
if ( ! onlyActive | | ( itr - > _camera - > getGraphicsContext ( ) & & itr - > _camera - > getGraphicsContext ( ) - > valid ( ) ) ) cameras . push_back ( itr - > _camera . get ( ) ) ;
2007-01-30 19:40:23 +08:00
}
}
2007-02-06 19:03:13 +08:00
void Viewer : : getAllThreads ( Threads & threads , bool onlyActive )
{
2007-07-12 23:54:45 +08:00
OperationThreads operationThreads ;
getOperationThreads ( operationThreads ) ;
2007-02-06 19:03:13 +08:00
2007-07-12 23:54:45 +08:00
for ( OperationThreads : : iterator itr = operationThreads . begin ( ) ;
itr ! = operationThreads . end ( ) ;
2007-02-06 19:03:13 +08:00
+ + itr )
{
threads . push_back ( * itr ) ;
}
if ( _scene . valid ( ) & &
_scene - > getDatabasePager ( ) & &
( ! onlyActive | | _scene - > getDatabasePager ( ) - > isRunning ( ) ) )
{
threads . push_back ( _scene - > getDatabasePager ( ) ) ;
}
}
2007-07-12 23:54:45 +08:00
void Viewer : : getOperationThreads ( OperationThreads & threads , bool onlyActive )
2007-02-06 19:03:13 +08:00
{
threads . clear ( ) ;
Contexts contexts ;
getContexts ( contexts ) ;
for ( Contexts : : iterator gcitr = contexts . begin ( ) ;
gcitr ! = contexts . end ( ) ;
+ + gcitr )
{
osg : : GraphicsContext * gc = * gcitr ;
if ( gc - > getGraphicsThread ( ) & &
( ! onlyActive | | gc - > getGraphicsThread ( ) - > isRunning ( ) ) )
{
threads . push_back ( gc - > getGraphicsThread ( ) ) ;
}
}
Cameras cameras ;
getCameras ( cameras ) ;
for ( Cameras : : iterator citr = cameras . begin ( ) ;
citr ! = cameras . end ( ) ;
+ + citr )
{
osg : : Camera * camera = * citr ;
if ( camera - > getCameraThread ( ) & &
( ! onlyActive | | camera - > getCameraThread ( ) - > isRunning ( ) ) )
{
threads . push_back ( camera - > getCameraThread ( ) ) ;
}
}
}
2007-02-01 06:24:20 +08:00
void Viewer : : setUpRenderingSupport ( )
2007-01-05 05:49:02 +08:00
{
2007-02-01 19:07:53 +08:00
bool threadsRunningBeforeSetUpRenderingSupport = _threadsRunning ;
if ( _threadsRunning ) stopThreading ( ) ;
2007-02-01 06:24:20 +08:00
_sceneViews . clear ( ) ;
2007-01-23 05:16:51 +08:00
2007-02-01 06:24:20 +08:00
Contexts contexts ;
getContexts ( contexts ) ;
2007-01-23 05:16:51 +08:00
2007-02-01 06:24:20 +08:00
osg : : FrameStamp * frameStamp = getFrameStamp ( ) ;
osg : : DisplaySettings * ds = _displaySettings . valid ( ) ? _displaySettings . get ( ) : osg : : DisplaySettings : : instance ( ) ;
osgDB : : DatabasePager * dp = _scene . valid ( ) ? _scene - > getDatabasePager ( ) : 0 ;
2007-01-31 01:38:02 +08:00
2007-02-06 22:38:08 +08:00
bool graphicsThreadDoesCull = _threadingModel ! = CullThreadPerCameraDrawThreadPerContext ;
2007-02-01 06:24:20 +08:00
unsigned int numViewerDoubleBufferedRenderingOperation = 0 ;
2007-01-31 01:38:02 +08:00
2007-02-01 06:24:20 +08:00
Cameras localCameras ;
getCameras ( localCameras ) ;
2007-02-22 18:56:36 +08:00
unsigned int sceneViewOptions = osgUtil : : SceneView : : HEADLIGHT ;
2007-01-31 01:38:02 +08:00
2007-02-06 22:38:08 +08:00
if ( true ) //(_threadingModel==CullThreadPerCameraDrawThreadPerContext)
2007-02-01 06:24:20 +08:00
{
for ( Contexts : : iterator gcitr = contexts . begin ( ) ;
gcitr ! = contexts . end ( ) ;
+ + gcitr )
{
( * gcitr ) - > removeAllOperations ( ) ;
2007-01-31 01:38:02 +08:00
2007-02-01 06:24:20 +08:00
osg : : GraphicsContext * gc = * gcitr ;
osg : : GraphicsContext : : Cameras & cameras = gc - > getCameras ( ) ;
osg : : State * state = gc - > getState ( ) ;
2007-06-22 22:48:18 +08:00
2007-02-01 06:24:20 +08:00
if ( dp ) dp - > setCompileGLObjectsForContextID ( state - > getContextID ( ) , true ) ;
2007-01-31 01:38:02 +08:00
2007-02-01 06:24:20 +08:00
for ( osg : : GraphicsContext : : Cameras : : iterator citr = cameras . begin ( ) ;
citr ! = cameras . end ( ) ;
+ + citr )
{
osg : : Camera * camera = * citr ;
2007-02-15 09:45:44 +08:00
if ( ! camera - > getStats ( ) ) camera - > setStats ( new osg : : Stats ( " Camera " ) ) ;
2007-02-01 06:24:20 +08:00
bool localCamera = std : : find ( localCameras . begin ( ) , localCameras . end ( ) , camera ) ! = localCameras . end ( ) ;
if ( localCamera )
{
osgUtil : : SceneView * sceneViewList [ 2 ] ;
2007-01-05 05:49:02 +08:00
2007-02-01 06:24:20 +08:00
for ( int i = 0 ; i < 2 ; + + i )
{
osgUtil : : SceneView * sceneView = new osgUtil : : SceneView ;
2007-01-20 03:53:23 +08:00
2007-02-01 06:24:20 +08:00
_sceneViews . push_back ( sceneView ) ;
sceneViewList [ i ] = sceneView ;
2007-01-23 05:16:51 +08:00
2007-02-01 06:24:20 +08:00
sceneView - > setGlobalStateSet ( _camera - > getStateSet ( ) ) ;
2007-02-22 18:56:36 +08:00
sceneView - > setDefaults ( sceneViewOptions ) ;
2007-06-09 18:06:38 +08:00
sceneView - > setDisplaySettings ( camera - > getDisplaySettings ( ) ! = 0 ? camera - > getDisplaySettings ( ) : ds ) ;
2007-02-01 06:24:20 +08:00
sceneView - > setCamera ( camera ) ;
sceneView - > setState ( state ) ;
sceneView - > setFrameStamp ( frameStamp ) ;
}
2007-01-22 19:22:37 +08:00
2007-01-05 05:49:02 +08:00
2007-02-21 22:17:15 +08:00
// osg::notify(osg::NOTICE)<<"localCamera "<<camera->getName()<<std::endl;
2007-02-01 06:24:20 +08:00
ViewerDoubleBufferedRenderingOperation * vdbro = new ViewerDoubleBufferedRenderingOperation ( graphicsThreadDoesCull , sceneViewList [ 0 ] , sceneViewList [ 1 ] , dp , _startTick ) ;
gc - > add ( vdbro ) ;
+ + numViewerDoubleBufferedRenderingOperation ;
}
else
{
2007-02-01 19:07:53 +08:00
// osg::notify(osg::NOTICE)<<"non local Camera"<<std::endl;
2007-01-20 03:53:23 +08:00
2007-02-01 06:24:20 +08:00
osgUtil : : SceneView * sceneView = new osgUtil : : SceneView ;
2007-01-23 05:16:51 +08:00
2007-02-01 06:24:20 +08:00
_sceneViews . push_back ( sceneView ) ;
2007-01-20 03:53:23 +08:00
2007-02-01 06:24:20 +08:00
sceneView - > setGlobalStateSet ( _camera - > getStateSet ( ) ) ;
2007-02-22 18:56:36 +08:00
sceneView - > setDefaults ( sceneViewOptions ) ;
2007-02-01 06:24:20 +08:00
sceneView - > setDisplaySettings ( ds ) ;
sceneView - > setCamera ( camera ) ;
2007-06-09 18:06:38 +08:00
sceneView - > setDisplaySettings ( camera - > getDisplaySettings ( ) ! = 0 ? camera - > getDisplaySettings ( ) : ds ) ;
2007-02-01 06:24:20 +08:00
sceneView - > setState ( state ) ;
sceneView - > setFrameStamp ( frameStamp ) ;
2007-01-23 05:16:51 +08:00
2007-02-01 06:24:20 +08:00
ViewerRenderingOperation * vro = new ViewerRenderingOperation ( sceneView , dp , _startTick ) ;
gc - > add ( vro ) ;
}
2007-01-22 19:22:37 +08:00
2007-02-01 06:24:20 +08:00
}
2007-01-22 19:22:37 +08:00
}
2007-01-05 05:49:02 +08:00
}
2007-02-01 06:24:20 +08:00
else
{
for ( Contexts : : iterator gcitr = contexts . begin ( ) ;
gcitr ! = contexts . end ( ) ;
+ + gcitr )
{
( * gcitr ) - > removeAllOperations ( ) ;
2007-01-05 05:49:02 +08:00
2007-02-01 06:24:20 +08:00
osg : : GraphicsContext * gc = * gcitr ;
osg : : GraphicsContext : : Cameras & cameras = gc - > getCameras ( ) ;
osg : : State * state = gc - > getState ( ) ;
2007-01-05 05:49:02 +08:00
2007-02-01 06:24:20 +08:00
for ( osg : : GraphicsContext : : Cameras : : iterator citr = cameras . begin ( ) ;
citr ! = cameras . end ( ) ;
+ + citr )
{
osg : : Camera * camera = * citr ;
2007-01-05 05:49:02 +08:00
2007-02-15 09:45:44 +08:00
if ( ! camera - > getStats ( ) ) camera - > setStats ( new osg : : Stats ( " Camera " ) ) ;
2007-01-22 02:24:54 +08:00
2007-02-01 06:24:20 +08:00
osgUtil : : SceneView * sceneView = new osgUtil : : SceneView ;
_sceneViews . push_back ( sceneView ) ;
2007-01-22 02:24:54 +08:00
2007-02-01 06:24:20 +08:00
sceneView - > setGlobalStateSet ( _camera - > getStateSet ( ) ) ;
2007-02-22 18:56:36 +08:00
sceneView - > setDefaults ( sceneViewOptions ) ;
2007-06-09 18:06:38 +08:00
sceneView - > setDisplaySettings ( camera - > getDisplaySettings ( ) ! = 0 ? camera - > getDisplaySettings ( ) : ds ) ;
2007-02-01 06:24:20 +08:00
sceneView - > setCamera ( camera ) ;
sceneView - > setState ( state ) ;
sceneView - > setFrameStamp ( frameStamp ) ;
2007-01-22 02:24:54 +08:00
2007-02-01 06:24:20 +08:00
if ( dp ) dp - > setCompileGLObjectsForContextID ( state - > getContextID ( ) , true ) ;
2007-01-22 02:24:54 +08:00
2007-02-01 06:24:20 +08:00
gc - > add ( new ViewerRenderingOperation ( sceneView , dp , _startTick ) ) ;
2007-01-22 02:24:54 +08:00
2007-02-01 06:24:20 +08:00
+ + numViewerDoubleBufferedRenderingOperation ;
}
2007-01-22 02:24:54 +08:00
}
2007-01-05 05:49:02 +08:00
}
2007-02-01 06:24:20 +08:00
if ( _endDynamicDrawBlock . valid ( ) )
{
_endDynamicDrawBlock - > setNumOfBlocks ( numViewerDoubleBufferedRenderingOperation ) ;
}
2007-02-01 19:07:53 +08:00
if ( threadsRunningBeforeSetUpRenderingSupport ) startThreading ( ) ;
2007-01-05 05:49:02 +08:00
}
2007-01-04 19:49:15 +08:00
void Viewer : : realize ( )
{
//osg::notify(osg::INFO)<<"Viewer::realize()"<<std::endl;
2007-01-05 05:35:11 +08:00
2007-01-04 19:49:15 +08:00
setCameraWithFocus ( 0 ) ;
Contexts contexts ;
getContexts ( contexts ) ;
2007-01-05 05:35:11 +08:00
if ( contexts . empty ( ) )
{
2007-01-10 01:35:46 +08:00
osg : : notify ( osg : : INFO ) < < " Viewer::realize() - No valid contexts found, setting up view across all screens. " < < std : : endl ;
2007-01-05 05:35:11 +08:00
// no windows are already set up so set up a default view
2007-06-13 19:09:31 +08:00
const char * ptr = 0 ;
int screenNum = - 1 ;
if ( ( ptr = getenv ( " OSG_SCREEN " ) ) ! = 0 )
{
if ( strlen ( ptr ) ! = 0 ) screenNum = atoi ( ptr ) ;
else screenNum = - 1 ;
}
int x = - 1 , y = - 1 , width = - 1 , height = - 1 ;
if ( ( ptr = getenv ( " OSG_WINDOW " ) ) ! = 0 )
{
std : : istringstream iss ( ptr ) ;
iss > > x > > y > > width > > height ;
}
if ( width > 0 & & height > 0 )
{
if ( screenNum > = 0 ) setUpViewInWindow ( x , y , width , height , screenNum ) ;
else setUpViewInWindow ( x , y , width , height ) ;
}
else if ( screenNum > = 0 )
{
setUpViewOnSingleScreen ( screenNum ) ;
}
else
{
setUpViewAcrossAllScreens ( ) ;
}
2007-02-01 06:24:20 +08:00
2007-01-05 05:35:11 +08:00
getContexts ( contexts ) ;
}
2007-01-04 19:49:15 +08:00
2007-01-05 05:35:11 +08:00
if ( contexts . empty ( ) )
{
osg : : notify ( osg : : NOTICE ) < < " Viewer::realize() - failed to set up any windows " < < std : : endl ;
_done = true ;
return ;
}
2007-01-05 05:49:02 +08:00
setUpRenderingSupport ( ) ;
2007-01-04 19:49:15 +08:00
for ( Contexts : : iterator citr = contexts . begin ( ) ;
2006-12-23 01:46:21 +08:00
citr ! = contexts . end ( ) ;
+ + citr )
{
2007-01-29 01:11:21 +08:00
osg : : GraphicsContext * gc = * citr ;
gc - > realize ( ) ;
2007-05-22 02:46:57 +08:00
if ( _realizeOperation . valid ( ) & & gc - > valid ( ) )
2007-01-29 01:11:21 +08:00
{
gc - > makeCurrent ( ) ;
( * _realizeOperation ) ( gc ) ;
gc - > releaseContext ( ) ;
}
2006-12-23 01:46:21 +08:00
}
2006-12-21 19:20:42 +08:00
bool grabFocus = true ;
if ( grabFocus )
{
2007-01-04 19:49:15 +08:00
for ( Contexts : : iterator citr = contexts . begin ( ) ;
2006-12-23 01:46:21 +08:00
citr ! = contexts . end ( ) ;
+ + citr )
2006-12-21 19:20:42 +08:00
{
2006-12-23 01:46:21 +08:00
osgViewer : : GraphicsWindow * gw = dynamic_cast < osgViewer : : GraphicsWindow * > ( * citr ) ;
if ( gw )
{
gw - > grabFocusIfPointerInWindow ( ) ;
}
2006-12-21 19:20:42 +08:00
}
2007-01-05 00:49:58 +08:00
}
2006-12-27 01:38:47 +08:00
// initialize the global timer to be relative to the current time.
osg : : Timer : : instance ( ) - > setStartTick ( ) ;
2007-01-15 22:46:16 +08:00
// pass on the start tick to all the associated eventqueues
setStartTick ( osg : : Timer : : instance ( ) - > getStartTick ( ) ) ;
2007-01-29 01:11:21 +08:00
2007-02-08 20:14:26 +08:00
setUpThreading ( ) ;
2006-12-20 00:00:51 +08:00
}
2007-01-25 20:02:51 +08:00
void Viewer : : frame ( double simulationTime )
2006-11-29 19:00:02 +08:00
{
2006-12-22 00:56:20 +08:00
if ( _done ) return ;
2006-12-27 23:04:04 +08:00
// osg::notify(osg::NOTICE)<<std::endl<<"Viewer::frame()"<<std::endl<<std::endl;
2006-12-21 05:13:29 +08:00
if ( _firstFrame )
{
init ( ) ;
2007-01-05 18:59:23 +08:00
if ( ! isRealized ( ) )
{
realize ( ) ;
}
2006-12-21 05:13:29 +08:00
_firstFrame = false ;
}
2007-01-25 20:02:51 +08:00
advance ( simulationTime ) ;
2006-12-21 05:13:29 +08:00
2007-01-06 00:48:04 +08:00
eventTraversal ( ) ;
updateTraversal ( ) ;
renderingTraversals ( ) ;
2006-11-29 19:00:02 +08:00
}
2007-01-25 20:02:51 +08:00
void Viewer : : advance ( double simulationTime )
2006-11-29 19:00:02 +08:00
{
2006-12-22 00:56:20 +08:00
if ( _done ) return ;
2007-01-20 03:53:23 +08:00
double prevousReferenceTime = _frameStamp - > getReferenceTime ( ) ;
int previousFrameNumber = _frameStamp - > getFrameNumber ( ) ;
2007-01-15 22:46:16 +08:00
_frameStamp - > setFrameNumber ( _frameStamp - > getFrameNumber ( ) + 1 ) ;
2007-01-25 20:02:51 +08:00
_frameStamp - > setReferenceTime ( osg : : Timer : : instance ( ) - > delta_s ( _startTick , osg : : Timer : : instance ( ) - > tick ( ) ) ) ;
if ( simulationTime = = USE_REFERENCE_TIME )
{
_frameStamp - > setSimulationTime ( _frameStamp - > getReferenceTime ( ) ) ;
}
else
{
_frameStamp - > setSimulationTime ( simulationTime ) ;
}
2007-01-20 03:53:23 +08:00
2007-01-30 19:40:23 +08:00
if ( getStats ( ) & & getStats ( ) - > collectStats ( " frame_rate " ) )
2007-01-20 03:53:23 +08:00
{
// update previous frame stats
double deltaFrameTime = _frameStamp - > getReferenceTime ( ) - prevousReferenceTime ;
getStats ( ) - > setAttribute ( previousFrameNumber , " Frame duration " , deltaFrameTime ) ;
getStats ( ) - > setAttribute ( previousFrameNumber , " Frame rate " , 1.0 / deltaFrameTime ) ;
// update current frames stats
getStats ( ) - > setAttribute ( _frameStamp - > getFrameNumber ( ) , " Reference time " , _frameStamp - > getReferenceTime ( ) ) ;
}
2007-02-02 20:41:13 +08:00
if ( osg : : Referenced : : getDeleteHandler ( ) )
{
osg : : Referenced : : getDeleteHandler ( ) - > flush ( ) ;
osg : : Referenced : : getDeleteHandler ( ) - > setFrameNumber ( _frameStamp - > getFrameNumber ( ) ) ;
}
2006-11-29 19:00:02 +08:00
}
2007-01-06 00:48:04 +08:00
void Viewer : : eventTraversal ( )
2006-11-29 19:00:02 +08:00
{
2006-12-22 00:56:20 +08:00
if ( _done ) return ;
2007-01-20 04:25:17 +08:00
double beginEventTraversal = osg : : Timer : : instance ( ) - > delta_s ( _startTick , osg : : Timer : : instance ( ) - > tick ( ) ) ;
2006-12-21 05:13:29 +08:00
// osg::notify(osg::NOTICE)<<"Viewer::frameEventTraversal()."<<std::endl;
// need to copy events from the GraphicsWindow's into local EventQueue;
osgGA : : EventQueue : : Events events ;
2006-12-23 01:46:21 +08:00
Contexts contexts ;
getContexts ( contexts ) ;
2007-01-02 02:20:10 +08:00
osgGA : : GUIEventAdapter * eventState = getEventQueue ( ) - > getCurrentEventState ( ) ;
osg : : Matrix masterCameraVPW = getCamera ( ) - > getViewMatrix ( ) * getCamera ( ) - > getProjectionMatrix ( ) ;
if ( getCamera ( ) - > getViewport ( ) )
{
osg : : Viewport * viewport = getCamera ( ) - > getViewport ( ) ;
masterCameraVPW * = viewport - > computeWindowMatrix ( ) ;
eventState - > setInputRange ( viewport - > x ( ) , viewport - > y ( ) , viewport - > x ( ) + viewport - > width ( ) , viewport - > y ( ) + viewport - > height ( ) ) ;
}
else
{
eventState - > setInputRange ( - 1.0 , - 1.0 , 1.0 , 1.0 ) ;
}
2006-12-23 01:46:21 +08:00
for ( Contexts : : iterator citr = contexts . begin ( ) ;
citr ! = contexts . end ( ) ;
+ + citr )
2006-12-21 05:13:29 +08:00
{
2006-12-23 01:46:21 +08:00
osgViewer : : GraphicsWindow * gw = dynamic_cast < osgViewer : : GraphicsWindow * > ( * citr ) ;
2006-12-21 05:13:29 +08:00
if ( gw )
{
gw - > checkEvents ( ) ;
2007-01-02 02:20:10 +08:00
osgGA : : EventQueue : : Events gw_events ;
gw - > getEventQueue ( ) - > takeEvents ( gw_events ) ;
2007-01-09 03:29:59 +08:00
osgGA : : EventQueue : : Events : : iterator itr ;
for ( itr = gw_events . begin ( ) ;
2007-01-02 02:20:10 +08:00
itr ! = gw_events . end ( ) ;
+ + itr )
{
osgGA : : GUIEventAdapter * event = itr - > get ( ) ;
bool pointerEvent = false ;
float x = event - > getX ( ) ;
float y = event - > getY ( ) ;
bool invert_y = event - > getMouseYOrientation ( ) = = osgGA : : GUIEventAdapter : : Y_INCREASING_DOWNWARDS ;
2007-01-15 22:46:16 +08:00
if ( invert_y & & gw - > getTraits ( ) ) y = gw - > getTraits ( ) - > height - y ;
2007-01-02 02:20:10 +08:00
switch ( event - > getEventType ( ) )
{
case ( osgGA : : GUIEventAdapter : : PUSH ) :
case ( osgGA : : GUIEventAdapter : : RELEASE ) :
case ( osgGA : : GUIEventAdapter : : DRAG ) :
case ( osgGA : : GUIEventAdapter : : MOVE ) :
{
pointerEvent = true ;
if ( event - > getEventType ( ) ! = osgGA : : GUIEventAdapter : : DRAG | | ! getCameraWithFocus ( ) )
{
osg : : GraphicsContext : : Cameras & cameras = gw - > getCameras ( ) ;
for ( osg : : GraphicsContext : : Cameras : : iterator citr = cameras . begin ( ) ;
citr ! = cameras . end ( ) ;
+ + citr )
{
osg : : Camera * camera = * citr ;
2007-02-22 03:41:53 +08:00
if ( camera - > getView ( ) = = this & &
camera - > getAllowEventFocus ( ) & &
camera - > getRenderTargetImplementation ( ) = = osg : : Camera : : FRAME_BUFFER )
2007-01-02 02:20:10 +08:00
{
2007-01-22 02:34:26 +08:00
osg : : Viewport * viewport = camera ? camera - > getViewport ( ) : 0 ;
if ( viewport & &
x > = viewport - > x ( ) & & y > = viewport - > y ( ) & &
x < = ( viewport - > x ( ) + viewport - > width ( ) ) & & y < = ( viewport - > y ( ) + viewport - > height ( ) ) )
{
2007-02-22 03:41:53 +08:00
// osg::notify(osg::NOTICE)<<"setCamera with focus "<<camera->getName()<<" x="<<x<<" y="<<y<<std::endl;
2007-01-22 02:34:26 +08:00
setCameraWithFocus ( camera ) ;
}
2007-01-02 02:20:10 +08:00
}
}
}
break ;
}
default :
break ;
}
if ( pointerEvent )
{
if ( getCameraWithFocus ( ) )
{
osg : : Viewport * viewport = getCameraWithFocus ( ) - > getViewport ( ) ;
osg : : Matrix localCameraVPW = getCameraWithFocus ( ) - > getViewMatrix ( ) * getCameraWithFocus ( ) - > getProjectionMatrix ( ) ;
if ( viewport ) localCameraVPW * = viewport - > computeWindowMatrix ( ) ;
osg : : Matrix matrix ( osg : : Matrix : : inverse ( localCameraVPW ) * masterCameraVPW ) ;
osg : : Vec3d new_coord = osg : : Vec3d ( x , y , 0.0 ) * matrix ;
x = new_coord . x ( ) ;
y = new_coord . y ( ) ;
2007-02-22 03:41:53 +08:00
// osg::notify(osg::NOTICE)<<"pointer event new_coord.x()="<<new_coord.x()<<" new_coord.y()="<<new_coord.y()<<std::endl;
2007-01-02 02:20:10 +08:00
event - > setInputRange ( eventState - > getXmin ( ) , eventState - > getYmin ( ) , eventState - > getXmax ( ) , eventState - > getYmax ( ) ) ;
event - > setX ( x ) ;
event - > setY ( y ) ;
event - > setMouseYOrientation ( osgGA : : GUIEventAdapter : : Y_INCREASING_UPWARDS ) ;
}
2007-02-22 03:41:53 +08:00
else
{
x = eventState - > getXmin ( ) + ( x / double ( gw - > getTraits ( ) - > width ) ) * ( eventState - > getXmax ( ) - eventState - > getXmin ( ) ) ;
y = eventState - > getYmin ( ) + ( y / double ( gw - > getTraits ( ) - > height ) ) * ( eventState - > getYmax ( ) - eventState - > getYmin ( ) ) ;
// osg::notify(osg::NOTICE)<<"new x = "<<x<<" new y = "<<y<<std::endl;
event - > setInputRange ( eventState - > getXmin ( ) , eventState - > getYmin ( ) , eventState - > getXmax ( ) , eventState - > getYmax ( ) ) ;
event - > setX ( x ) ;
event - > setY ( y ) ;
event - > setMouseYOrientation ( osgGA : : GUIEventAdapter : : Y_INCREASING_UPWARDS ) ;
}
2007-01-02 02:20:10 +08:00
// pass along the new pointer events details to the eventState of the viewer
eventState - > setX ( x ) ;
eventState - > setY ( y ) ;
eventState - > setButtonMask ( event - > getButtonMask ( ) ) ;
eventState - > setMouseYOrientation ( osgGA : : GUIEventAdapter : : Y_INCREASING_UPWARDS ) ;
}
else
{
event - > setInputRange ( eventState - > getXmin ( ) , eventState - > getYmin ( ) , eventState - > getXmax ( ) , eventState - > getYmax ( ) ) ;
event - > setX ( eventState - > getX ( ) ) ;
event - > setY ( eventState - > getY ( ) ) ;
event - > setButtonMask ( eventState - > getButtonMask ( ) ) ;
event - > setMouseYOrientation ( eventState - > getMouseYOrientation ( ) ) ;
}
//osg::notify(osg::NOTICE)<<" mouse x = "<<event->getX()<<" y="<<event->getY()<<std::endl;
// osg::notify(osg::NOTICE)<<" mouse Xmin = "<<event->getXmin()<<" Ymin="<<event->getYmin()<<" xMax="<<event->getXmax()<<" Ymax="<<event->getYmax()<<std::endl;
}
2007-01-09 03:29:59 +08:00
for ( itr = gw_events . begin ( ) ;
itr ! = gw_events . end ( ) ;
+ + itr )
{
osgGA : : GUIEventAdapter * event = itr - > get ( ) ;
switch ( event - > getEventType ( ) )
{
case ( osgGA : : GUIEventAdapter : : CLOSE_WINDOW ) :
{
2007-05-22 02:46:57 +08:00
bool wasThreading = areThreadsRunning ( ) ;
if ( wasThreading ) stopThreading ( ) ;
2007-01-09 03:29:59 +08:00
gw - > close ( ) ;
2007-05-22 02:46:57 +08:00
if ( wasThreading ) startThreading ( ) ;
2007-01-09 03:29:59 +08:00
break ;
}
default :
break ;
}
}
2007-01-02 02:20:10 +08:00
events . insert ( events . end ( ) , gw_events . begin ( ) , gw_events . end ( ) ) ;
2006-12-21 05:13:29 +08:00
}
}
2006-12-28 04:23:34 +08:00
// osg::notify(osg::NOTICE)<<"mouseEventState Xmin = "<<eventState->getXmin()<<" Ymin="<<eventState->getYmin()<<" xMax="<<eventState->getXmax()<<" Ymax="<<eventState->getYmax()<<std::endl;
2007-01-16 16:56:33 +08:00
_eventQueue - > frame ( getFrameStamp ( ) - > getReferenceTime ( ) ) ;
2006-12-27 01:38:47 +08:00
_eventQueue - > takeEvents ( events ) ;
2006-12-21 05:13:29 +08:00
#if 0
// osg::notify(osg::NOTICE)<<"Events "<<events.size()<<std::endl;
for ( osgGA : : EventQueue : : Events : : iterator itr = events . begin ( ) ;
itr ! = events . end ( ) ;
+ + itr )
{
osgGA : : GUIEventAdapter * event = itr - > get ( ) ;
switch ( event - > getEventType ( ) )
{
case ( osgGA : : GUIEventAdapter : : PUSH ) :
osg : : notify ( osg : : NOTICE ) < < " PUSH " < < event - > getButton ( ) < < " x= " < < event - > getX ( ) < < " y= " < < event - > getY ( ) < < std : : endl ;
break ;
case ( osgGA : : GUIEventAdapter : : RELEASE ) :
osg : : notify ( osg : : NOTICE ) < < " RELEASE " < < event - > getButton ( ) < < " x= " < < event - > getX ( ) < < " y= " < < event - > getY ( ) < < std : : endl ;
break ;
case ( osgGA : : GUIEventAdapter : : DRAG ) :
osg : : notify ( osg : : NOTICE ) < < " DRAG " < < event - > getButtonMask ( ) < < " x= " < < event - > getX ( ) < < " y= " < < event - > getY ( ) < < std : : endl ;
break ;
case ( osgGA : : GUIEventAdapter : : MOVE ) :
osg : : notify ( osg : : NOTICE ) < < " MOVE " < < event - > getButtonMask ( ) < < " x= " < < event - > getX ( ) < < " y= " < < event - > getY ( ) < < std : : endl ;
break ;
case ( osgGA : : GUIEventAdapter : : SCROLL ) :
osg : : notify ( osg : : NOTICE ) < < " SCROLL " < < event - > getScrollingMotion ( ) < < std : : endl ;
break ;
case ( osgGA : : GUIEventAdapter : : KEYDOWN ) :
osg : : notify ( osg : : NOTICE ) < < " KEYDOWN ' " < < ( char ) event - > getKey ( ) < < " ' " < < std : : endl ;
break ;
case ( osgGA : : GUIEventAdapter : : KEYUP ) :
osg : : notify ( osg : : NOTICE ) < < " KEYUP ' " < < ( char ) event - > getKey ( ) < < " ' " < < std : : endl ;
break ;
2007-01-10 18:09:05 +08:00
case ( osgGA : : GUIEventAdapter : : RESIZE ) :
2007-01-09 18:06:20 +08:00
osg : : notify ( osg : : NOTICE ) < < " RESIZE " < < event - > getWindowX ( ) < < " / " < < event - > getWindowY ( ) < < " x " < < event - > getWindowWidth ( ) < < " / " < < event - > getWindowHeight ( ) < < std : : endl ;
break ;
case ( osgGA : : GUIEventAdapter : : QUIT_APPLICATION ) :
osg : : notify ( osg : : NOTICE ) < < " QUIT_APPLICATION " < < std : : endl ;
2007-01-02 02:20:10 +08:00
break ;
2006-12-21 05:13:29 +08:00
case ( osgGA : : GUIEventAdapter : : FRAME ) :
// osg::notify(osg::NOTICE)<<" FRAME "<<std::endl;
break ;
default :
// osg::notify(osg::NOTICE)<<" Event not handled"<<std::endl;
break ;
}
}
# endif
2006-12-22 00:56:20 +08:00
// osg::notify(osg::NOTICE)<<"Events "<<events.size()<<std::endl;
2007-01-05 05:28:16 +08:00
2007-01-13 05:05:39 +08:00
if ( ( _keyEventSetsDone ! = 0 ) | | _quitEventSetsDone )
2006-12-22 00:56:20 +08:00
{
2007-01-05 05:28:16 +08:00
for ( osgGA : : EventQueue : : Events : : iterator itr = events . begin ( ) ;
itr ! = events . end ( ) ;
+ + itr )
2006-12-22 00:56:20 +08:00
{
2007-01-05 05:28:16 +08:00
osgGA : : GUIEventAdapter * event = itr - > get ( ) ;
switch ( event - > getEventType ( ) )
{
case ( osgGA : : GUIEventAdapter : : KEYUP ) :
2007-01-13 05:05:39 +08:00
if ( _keyEventSetsDone & & event - > getKey ( ) = = _keyEventSetsDone ) _done = true ;
2007-01-05 05:28:16 +08:00
break ;
2007-01-09 18:06:20 +08:00
case ( osgGA : : GUIEventAdapter : : QUIT_APPLICATION ) :
2007-01-13 05:05:39 +08:00
if ( _quitEventSetsDone ) _done = true ;
2007-01-09 18:06:20 +08:00
break ;
2007-01-05 05:28:16 +08:00
default :
break ;
}
2006-12-22 00:56:20 +08:00
}
}
2007-01-05 05:28:16 +08:00
2006-12-22 00:56:20 +08:00
if ( _done ) return ;
2006-12-21 05:13:29 +08:00
for ( osgGA : : EventQueue : : Events : : iterator itr = events . begin ( ) ;
itr ! = events . end ( ) ;
+ + itr )
{
osgGA : : GUIEventAdapter * event = itr - > get ( ) ;
for ( EventHandlers : : iterator hitr = _eventHandlers . begin ( ) ;
2007-01-24 20:28:18 +08:00
hitr ! = _eventHandlers . end ( ) ;
2006-12-21 05:13:29 +08:00
+ + hitr )
{
2007-01-24 20:28:18 +08:00
if ( ( * hitr ) - > handle ( * event , * this , 0 , 0 ) ) event - > setHandled ( true ) ;
2006-12-21 05:13:29 +08:00
}
2007-02-26 21:01:17 +08:00
if ( _cameraManipulator . valid ( ) )
{
if ( _cameraManipulator - > handle ( * event , * this ) ) event - > setHandled ( true ) ;
}
2006-12-21 05:13:29 +08:00
}
2007-01-02 02:20:10 +08:00
2007-01-15 22:46:16 +08:00
if ( _eventVisitor . valid ( ) & & _scene . valid ( ) )
2007-01-10 18:09:05 +08:00
{
2007-01-15 22:46:16 +08:00
_eventVisitor - > setFrameStamp ( getFrameStamp ( ) ) ;
_eventVisitor - > setTraversalNumber ( getFrameStamp ( ) - > getFrameNumber ( ) ) ;
2007-01-10 18:09:05 +08:00
for ( osgGA : : EventQueue : : Events : : iterator itr = events . begin ( ) ;
itr ! = events . end ( ) ;
+ + itr )
{
osgGA : : GUIEventAdapter * event = itr - > get ( ) ;
_eventVisitor - > reset ( ) ;
_eventVisitor - > addEvent ( event ) ;
getSceneData ( ) - > accept ( * _eventVisitor ) ;
2007-05-28 01:29:29 +08:00
// call any camera update callbacks, but only traverse that callback, don't traverse its subgraph
// leave that to the scene update traversal.
osg : : NodeVisitor : : TraversalMode tm = _eventVisitor - > getTraversalMode ( ) ;
_eventVisitor - > setTraversalMode ( osg : : NodeVisitor : : TRAVERSE_NONE ) ;
if ( _camera . valid ( ) & & _camera - > getEventCallback ( ) ) _camera - > accept ( * _eventVisitor ) ;
for ( unsigned int i = 0 ; i < getNumSlaves ( ) ; + + i )
{
osg : : Camera * camera = getSlave ( i ) . _camera . get ( ) ;
if ( camera & & camera - > getEventCallback ( ) ) camera - > accept ( * _eventVisitor ) ;
}
_eventVisitor - > setTraversalMode ( tm ) ;
2007-01-10 18:09:05 +08:00
}
}
2007-01-30 19:40:23 +08:00
if ( getStats ( ) & & getStats ( ) - > collectStats ( " event " ) )
2007-01-20 04:25:17 +08:00
{
double endEventTraversal = osg : : Timer : : instance ( ) - > delta_s ( _startTick , osg : : Timer : : instance ( ) - > tick ( ) ) ;
// update current frames stats
2007-01-23 01:39:32 +08:00
getStats ( ) - > setAttribute ( _frameStamp - > getFrameNumber ( ) , " Event traversal begin time " , beginEventTraversal ) ;
getStats ( ) - > setAttribute ( _frameStamp - > getFrameNumber ( ) , " Event traversal end time " , endEventTraversal ) ;
2007-01-20 04:25:17 +08:00
getStats ( ) - > setAttribute ( _frameStamp - > getFrameNumber ( ) , " Event traversal time taken " , endEventTraversal - beginEventTraversal ) ;
}
2006-11-29 19:00:02 +08:00
}
2007-01-06 00:48:04 +08:00
void Viewer : : updateTraversal ( )
2006-11-29 19:00:02 +08:00
{
2006-12-22 00:56:20 +08:00
if ( _done ) return ;
2007-01-20 04:25:17 +08:00
double beginUpdateTraversal = osg : : Timer : : instance ( ) - > delta_s ( _startTick , osg : : Timer : : instance ( ) - > tick ( ) ) ;
2007-05-28 01:29:29 +08:00
// do the update traversal of the scene.
if ( _scene . valid ( ) ) _scene - > updateTraversal ( ) ;
2007-05-27 23:24:41 +08:00
2007-05-28 01:29:29 +08:00
osgUtil : : UpdateVisitor * uv = _scene . valid ( ) ? _scene - > getUpdateVisitor ( ) : 0 ;
if ( uv )
2007-05-27 23:24:41 +08:00
{
2007-05-28 01:29:29 +08:00
// call any camera update callbacks, but only traverse that callback, don't traverse its subgraph
// leave that to the scene update traversal.
2007-05-27 23:24:41 +08:00
osg : : NodeVisitor : : TraversalMode tm = uv - > getTraversalMode ( ) ;
uv - > setTraversalMode ( osg : : NodeVisitor : : TRAVERSE_NONE ) ;
2007-05-28 01:29:29 +08:00
if ( _camera . valid ( ) & & _camera - > getUpdateCallback ( ) ) _camera - > accept ( * uv ) ;
for ( unsigned int i = 0 ; i < getNumSlaves ( ) ; + + i )
{
osg : : Camera * camera = getSlave ( i ) . _camera . get ( ) ;
if ( camera & & camera - > getUpdateCallback ( ) ) camera - > accept ( * uv ) ;
}
2007-05-27 23:24:41 +08:00
uv - > setTraversalMode ( tm ) ;
}
2006-12-21 05:13:29 +08:00
if ( _cameraManipulator . valid ( ) )
{
2007-05-18 03:58:57 +08:00
setFusionDistance ( getCameraManipulator ( ) - > getFusionDistanceMode ( ) ,
getCameraManipulator ( ) - > getFusionDistanceValue ( ) ) ;
2006-12-21 05:13:29 +08:00
_camera - > setViewMatrix ( _cameraManipulator - > getInverseMatrix ( ) ) ;
}
updateSlaves ( ) ;
2007-01-20 04:25:17 +08:00
2007-01-30 19:40:23 +08:00
if ( getStats ( ) & & getStats ( ) - > collectStats ( " update " ) )
2007-01-20 04:25:17 +08:00
{
double endUpdateTraversal = osg : : Timer : : instance ( ) - > delta_s ( _startTick , osg : : Timer : : instance ( ) - > tick ( ) ) ;
// update current frames stats
2007-01-23 01:39:32 +08:00
getStats ( ) - > setAttribute ( _frameStamp - > getFrameNumber ( ) , " Update traversal begin time " , beginUpdateTraversal ) ;
getStats ( ) - > setAttribute ( _frameStamp - > getFrameNumber ( ) , " Update traversal end time " , endUpdateTraversal ) ;
2007-01-20 04:25:17 +08:00
getStats ( ) - > setAttribute ( _frameStamp - > getFrameNumber ( ) , " Update traversal time taken " , endUpdateTraversal - beginUpdateTraversal ) ;
}
2006-11-29 19:00:02 +08:00
}
2007-01-06 00:48:04 +08:00
void Viewer : : renderingTraversals ( )
2006-11-29 19:00:02 +08:00
{
2007-01-04 19:49:15 +08:00
// check to see if windows are still valid
checkWindowStatus ( ) ;
2006-12-22 01:23:07 +08:00
if ( _done ) return ;
2007-01-20 04:25:17 +08:00
double beginRenderingTraversals = osg : : Timer : : instance ( ) - > delta_s ( _startTick , osg : : Timer : : instance ( ) - > tick ( ) ) ;
2007-01-15 22:46:16 +08:00
osgDB : : DatabasePager * dp = _scene . valid ( ) ? _scene - > getDatabasePager ( ) : 0 ;
2006-12-22 01:23:07 +08:00
if ( dp )
{
2007-01-15 22:46:16 +08:00
dp - > signalBeginFrame ( getFrameStamp ( ) ) ;
2006-12-22 01:23:07 +08:00
}
2007-01-03 01:39:31 +08:00
// osg::notify(osg::NOTICE)<<std::endl<<"Joing _startRenderingBarrier block"<<std::endl;
2007-01-04 19:49:15 +08:00
2006-11-29 19:00:02 +08:00
2007-01-03 01:39:31 +08:00
Contexts contexts ;
getContexts ( contexts ) ;
2007-01-30 06:44:29 +08:00
Contexts : : iterator itr ;
2007-02-01 06:24:20 +08:00
// dispatch the the rendering threads
if ( _startRenderingBarrier . valid ( ) ) _startRenderingBarrier - > block ( ) ;
2007-01-30 06:44:29 +08:00
if ( _endDynamicDrawBlock . valid ( ) )
{
2007-02-01 06:24:20 +08:00
_endDynamicDrawBlock - > reset ( ) ;
}
// reset any double buffer graphics objects
for ( itr = contexts . begin ( ) ;
itr ! = contexts . end ( ) ;
+ + itr )
{
osg : : GraphicsContext * gc = ( * itr ) ;
2007-02-05 22:56:41 +08:00
OpenThreads : : ScopedLock < OpenThreads : : Mutex > lock ( * ( gc - > getOperationsMutex ( ) ) ) ;
2007-02-01 06:24:20 +08:00
osg : : GraphicsContext : : OperationQueue & operations = gc - > getOperationsQueue ( ) ;
for ( osg : : GraphicsContext : : OperationQueue : : iterator oitr = operations . begin ( ) ;
oitr ! = operations . end ( ) ;
+ + oitr )
2007-01-30 06:44:29 +08:00
{
2007-02-01 06:24:20 +08:00
ViewerDoubleBufferedRenderingOperation * vdbro = dynamic_cast < ViewerDoubleBufferedRenderingOperation * > ( oitr - > get ( ) ) ;
if ( vdbro )
{
2007-02-06 19:03:13 +08:00
if ( ! vdbro - > getGraphicsThreadDoesCull ( ) & & ! ( vdbro - > getCamera ( ) - > getCameraThread ( ) ) )
2007-02-01 06:24:20 +08:00
{
vdbro - > cull ( ) ;
}
}
2007-01-30 06:44:29 +08:00
}
}
2006-12-23 01:46:21 +08:00
2007-01-03 01:39:31 +08:00
for ( itr = contexts . begin ( ) ;
itr ! = contexts . end ( ) ;
+ + itr )
2006-12-22 00:56:20 +08:00
{
2007-01-03 01:39:31 +08:00
if ( _done ) return ;
2007-05-22 02:46:57 +08:00
if ( ! ( ( * itr ) - > getGraphicsThread ( ) ) & & ( * itr ) - > valid ( ) )
2007-01-03 01:39:31 +08:00
{
2007-02-06 19:03:13 +08:00
makeCurrent ( * itr ) ;
2006-12-23 01:46:21 +08:00
( * itr ) - > runOperations ( ) ;
2006-12-22 00:56:20 +08:00
}
2007-01-03 01:39:31 +08:00
}
2006-12-22 01:23:07 +08:00
2007-01-03 01:39:31 +08:00
// osg::notify(osg::NOTICE)<<"Joing _endRenderingDispatchBarrier block"<<std::endl;
2006-12-22 01:23:07 +08:00
2007-01-03 01:39:31 +08:00
// wait till the rendering dispatch is done.
if ( _endRenderingDispatchBarrier . valid ( ) ) _endRenderingDispatchBarrier - > block ( ) ;
for ( itr = contexts . begin ( ) ;
itr ! = contexts . end ( ) ;
+ + itr )
{
if ( _done ) return ;
2007-01-04 19:49:15 +08:00
2007-05-22 02:46:57 +08:00
if ( ! ( ( * itr ) - > getGraphicsThread ( ) ) & & ( * itr ) - > valid ( ) )
2007-01-03 01:39:31 +08:00
{
2007-02-06 19:03:13 +08:00
makeCurrent ( * itr ) ;
2006-12-23 01:46:21 +08:00
( * itr ) - > swapBuffers ( ) ;
}
2006-12-22 00:56:20 +08:00
}
2006-12-22 01:23:07 +08:00
if ( dp )
{
dp - > signalEndFrame ( ) ;
}
2007-01-20 04:25:17 +08:00
2007-02-06 19:03:13 +08:00
// wait till the dynamic draw is complete.
if ( _endDynamicDrawBlock . valid ( ) )
{
// osg::Timer_t startTick = osg::Timer::instance()->tick();
_endDynamicDrawBlock - > block ( ) ;
// osg::notify(osg::NOTICE)<<"Time waiting "<<osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick())<<std::endl;;
}
2007-01-30 19:40:23 +08:00
if ( getStats ( ) & & getStats ( ) - > collectStats ( " update " ) )
2007-01-20 04:25:17 +08:00
{
double endRenderingTraversals = osg : : Timer : : instance ( ) - > delta_s ( _startTick , osg : : Timer : : instance ( ) - > tick ( ) ) ;
// update current frames stats
getStats ( ) - > setAttribute ( _frameStamp - > getFrameNumber ( ) , " Rendering traversals begin time " , beginRenderingTraversals ) ;
getStats ( ) - > setAttribute ( _frameStamp - > getFrameNumber ( ) , " Rendering traversals end time " , endRenderingTraversals ) ;
getStats ( ) - > setAttribute ( _frameStamp - > getFrameNumber ( ) , " Rendering traversals time taken " , endRenderingTraversals - beginRenderingTraversals ) ;
}
2006-11-29 19:00:02 +08:00
}
2007-02-12 21:39:18 +08:00
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 ) ;
}
}