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-01-05 18:59:23 +08:00
# include <osgUtil/GLObjectsVisitor>
# 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-01-02 02:20:10 +08:00
using namespace osgViewer ;
2006-12-21 05:13:29 +08:00
Viewer : : Viewer ( ) :
2006-12-22 00:56:20 +08:00
_firstFrame ( true ) ,
2007-01-03 01:39:31 +08:00
_done ( false ) ,
2007-01-13 05:05:39 +08:00
_keyEventSetsDone ( osgGA : : GUIEventAdapter : : KEY_Escape ) ,
2007-01-09 18:06:20 +08:00
_quitEventSetsDone ( true ) ,
2007-01-04 19:49:15 +08:00
_threadingModel ( ThreadPerContext ) ,
2007-01-13 05:05:39 +08:00
_endBarrierPosition ( AfterSwapBuffers ) ,
2007-01-04 19:49:15 +08:00
_numThreadsOnBarrier ( 0 )
2006-11-27 22:52:07 +08:00
{
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-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-01-04 00:06:12 +08:00
//osg::notify(osg::NOTICE)<<"finish Viewer::~Viewer()"<<std::endl;
2007-01-09 00:20:10 +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
}
if ( ! getCameraManipulator ( ) )
{
setCameraManipulator ( new osgGA : : TrackballManipulator ( ) ) ;
}
if ( ! isRealized ( ) )
{
realize ( ) ;
}
while ( ! done ( ) )
{
frame ( ) ;
}
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 ( ) ) ;
setReferenceTime ( 0.0 ) ;
assignSceneDataToCameras ( ) ;
setUpRenderingSupport ( ) ;
2007-01-06 05:19:01 +08:00
}
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-01-04 19:49:15 +08:00
if ( _threadingModel ! = SingleThreaded ) 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-01-04 19:49:15 +08:00
if ( _threadingModel ! = SingleThreaded ) startThreading ( ) ;
2006-12-23 01:46:21 +08:00
}
2007-01-30 06:44:29 +08:00
void Viewer : : setUseMainThreadForRenderingTraversals ( bool flag )
{
if ( _useMainThreadForRenderingTraversal = = flag ) return ;
if ( _threadingModel ! = SingleThreaded ) stopThreading ( ) ;
_useMainThreadForRenderingTraversal = flag ;
if ( _threadingModel ! = SingleThreaded ) startThreading ( ) ;
}
2007-01-13 05:05:39 +08:00
void Viewer : : setEndBarrierPosition ( BarrierPosition bp )
{
if ( _endBarrierPosition = = bp ) return ;
if ( _threadingModel ! = SingleThreaded ) stopThreading ( ) ;
_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-01-04 19:49:15 +08:00
if ( _numThreadsOnBarrier = = 0 ) return ;
2007-01-02 20:50:57 +08:00
2007-01-04 19:49:15 +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-01-04 19:49:15 +08:00
// delete all the graphics threads.
for ( Contexts : : iterator itr = contexts . begin ( ) ;
itr ! = contexts . end ( ) ;
2007-01-02 20:50:57 +08:00
+ + itr )
{
2007-01-04 19:49:15 +08:00
( * itr ) - > setGraphicsThread ( 0 ) ;
2007-01-02 20:50:57 +08:00
}
2007-01-04 19:49:15 +08:00
_startRenderingBarrier = 0 ;
_endRenderingDispatchBarrier = 0 ;
_numThreadsOnBarrier = 0 ;
}
2006-12-23 01:46:21 +08:00
// Compile operation, that compile OpenGL objects.
2007-01-16 16:56:33 +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 ) :
2006-12-25 00:40:19 +08:00
osg : : GraphicsOperation ( " Compile " , false ) ,
2006-12-23 01:46:21 +08:00
_scene ( scene )
{
}
virtual void operator ( ) ( osg : : GraphicsContext * context )
{
// OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mutex);
// osg::notify(osg::NOTICE)<<"Compile "<<context<<" "<<OpenThreads::Thread::CurrentThread()<<std::endl;
// context->makeCurrentImplementation();
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-01-16 16:56:33 +08:00
struct ViewerRunOperations : public osg : : GraphicsOperation
2006-12-23 01:46:21 +08:00
{
2007-01-16 16:56:33 +08:00
ViewerRunOperations ( ) :
osg : : GraphicsOperation ( " RunOperation " , true )
2006-12-23 01:46:21 +08:00
{
}
virtual void operator ( ) ( osg : : GraphicsContext * gc )
{
gc - > runOperations ( ) ;
}
} ;
2007-01-04 19:49:15 +08:00
unsigned int Viewer : : computeNumberOfThreadsIncludingMainRequired ( )
{
Contexts contexts ;
getContexts ( contexts ) ;
2006-12-23 01:46:21 +08:00
2007-01-04 19:49:15 +08:00
if ( contexts . empty ( ) ) return 0 ;
if ( contexts . size ( ) = = 1 | | _threadingModel = = SingleThreaded )
{
return 1 ;
}
2007-01-30 06:44:29 +08:00
return _useMainThreadForRenderingTraversal ? contexts . size ( ) : contexts . size ( ) + 1 ;
2007-01-04 19:49:15 +08:00
}
void Viewer : : startThreading ( )
2006-12-23 01:46:21 +08:00
{
2007-01-04 19:49:15 +08:00
unsigned int numThreadsIncludingMainThread = computeNumberOfThreadsIncludingMainRequired ( ) ;
2006-12-23 01:46:21 +08:00
2007-01-04 19:49:15 +08:00
// return if we don't need multiple threads.
if ( numThreadsIncludingMainThread < = 1 ) return ;
// return if threading is already up and running
if ( numThreadsIncludingMainThread = = _numThreadsOnBarrier ) return ;
if ( _numThreadsOnBarrier ! = 0 )
{
// we already have threads running but not the right number, so stop them and then create new threads.
stopThreading ( ) ;
}
2007-01-02 02:20:10 +08:00
2007-01-05 05:18:03 +08:00
osg : : notify ( osg : : INFO ) < < " Viewer::startThreading() - starting threading " < < std : : endl ;
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-23 01:46:21 +08:00
Contexts contexts ;
getContexts ( contexts ) ;
2007-01-04 00:06:12 +08:00
int numProcessors = OpenThreads : : GetNumberOfProcessors ( ) ;
bool affinity = true ;
2006-12-27 01:38:47 +08:00
2007-01-04 19:49:15 +08:00
bool firstContextAsMainThread = numThreadsIncludingMainThread = = contexts . size ( ) ;
// osg::notify(osg::NOTICE)<<"numThreadsIncludingMainThread=="<<numThreadsIncludingMainThread<<std::endl;
_numThreadsOnBarrier = numThreadsIncludingMainThread ;
_startRenderingBarrier = new osg : : BarrierOperation ( _numThreadsOnBarrier , osg : : BarrierOperation : : NO_OPERATION ) ;
2007-01-30 06:44:29 +08:00
if ( _threadingModel = = ThreadPerContext )
{
# if 1
_endRenderingDispatchBarrier = new osg : : BarrierOperation ( _numThreadsOnBarrier , osg : : BarrierOperation : : NO_OPERATION ) ;
# else
_endRenderingDispatchBarrier = new osg : : BarrierOperation ( _numThreadsOnBarrier , osg : : BarrierOperation : : GL_FINISH ) ;
# endif
}
else
{
_endDynamicDrawBlock = new EndOfDynamicDrawBlock ;
}
2007-01-04 19:49:15 +08:00
osg : : ref_ptr < osg : : SwapBuffersOperation > swapOp = new osg : : SwapBuffersOperation ( ) ;
Contexts : : iterator citr = contexts . begin ( ) ;
unsigned int processNum = 0 ;
if ( firstContextAsMainThread )
2006-12-23 01:46:21 +08:00
{
2007-01-04 19:49:15 +08:00
+ + processNum ;
+ + citr ;
}
2007-01-30 06:44:29 +08:00
2007-01-04 19:49:15 +08:00
for ( ;
citr ! = contexts . end ( ) ;
+ + citr ,
+ + processNum )
{
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-01-16 16:56:33 +08:00
gc - > getGraphicsThread ( ) - > add ( new ViewerCompileOperation ( getSceneData ( ) ) ) ;
2007-01-04 19:49:15 +08:00
// add the startRenderingBarrier
gc - > getGraphicsThread ( ) - > add ( _startRenderingBarrier . get ( ) ) ;
// 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-01-30 06:44:29 +08:00
if ( _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-01-04 19:49:15 +08:00
// add the swap buffers
gc - > getGraphicsThread ( ) - > add ( swapOp . get ( ) ) ;
2007-01-30 06:44:29 +08:00
if ( _endBarrierPosition = = AfterSwapBuffers & & _endRenderingDispatchBarrier . valid ( ) )
2007-01-13 05:05:39 +08:00
{
// add the endRenderingDispatchBarrier
gc - > getGraphicsThread ( ) - > add ( _endRenderingDispatchBarrier . get ( ) ) ;
}
2007-01-04 19:49:15 +08:00
}
2007-01-15 22:46:16 +08:00
if ( firstContextAsMainThread )
{
if ( affinity ) OpenThreads : : SetProcessorAffinityOfCurrentThread ( 0 ) ;
}
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-01-04 19:49:15 +08:00
//osg::notify(osg::NOTICE)<<" gc->getGraphicsThread()->startThread() "<<gc->getGraphicsThread()<<std::endl;
gc - > getGraphicsThread ( ) - > startThread ( ) ;
// OpenThreads::Thread::YieldCurrentThread();
2007-01-04 00:06:12 +08:00
}
2007-01-04 19:49:15 +08:00
}
}
void Viewer : : checkWindowStatus ( )
{
unsigned int numThreadsIncludingMainThread = computeNumberOfThreadsIncludingMainRequired ( ) ;
if ( numThreadsIncludingMainThread ! = _numThreadsOnBarrier )
{
stopThreading ( ) ;
2007-01-04 00:06:12 +08:00
2007-01-04 19:49:15 +08:00
if ( numThreadsIncludingMainThread > 1 ) startThreading ( ) ;
}
if ( numThreadsIncludingMainThread = = 0 ) _done = true ;
}
2006-12-23 01:46:21 +08:00
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 ) ) ;
}
}
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-05 05:49:02 +08:00
// Draw operation, that does a draw on the scene graph.
2007-01-16 16:56:33 +08:00
struct ViewerRenderingOperation : public osg : : GraphicsOperation
2007-01-05 05:49:02 +08:00
{
2007-01-22 19:22:37 +08:00
ViewerRenderingOperation ( osgUtil : : SceneView * sceneView , osgDB : : DatabasePager * databasePager , osg : : Timer_t startTick ) :
2007-01-05 05:49:02 +08:00
osg : : GraphicsOperation ( " Render " , true ) ,
_sceneView ( sceneView ) ,
2007-01-22 19:22:37 +08:00
_databasePager ( databasePager ) ,
_startTick ( startTick ) ,
2007-01-23 05:16:51 +08:00
_initialized ( false ) ,
_aquireGPUStats ( false ) ,
_extensions ( 0 )
2007-01-05 05:49:02 +08:00
{
_sceneView - > getCullVisitor ( ) - > setDatabaseRequestHandler ( _databasePager . get ( ) ) ;
}
2007-01-23 05:16:51 +08:00
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 ) ;
}
2007-01-05 05:49:02 +08:00
virtual void operator ( ) ( osg : : GraphicsContext * )
{
if ( ! _sceneView ) return ;
// osg::notify(osg::NOTICE)<<"RenderingOperation"<<std::endl;
2007-01-20 03:53:23 +08:00
2007-01-22 19:22:37 +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 ;
2007-01-23 05:16:51 +08:00
if ( ! _initialized )
{
_initialized = true ;
_extensions = stats ? osg : : Drawable : : getExtensions ( state - > getContextID ( ) , true ) : 0 ;
_aquireGPUStats = _extensions & & _extensions - > isTimerQuerySupported ( ) ;
_previousQueryTime = osg : : Timer : : instance ( ) - > delta_s ( _startTick , osg : : Timer : : instance ( ) - > tick ( ) ) ;
}
2007-01-05 05:49:02 +08:00
2007-01-23 05:16:51 +08:00
// _aquireGPUStats = false;
2007-01-22 19:22:37 +08:00
2007-01-23 05:16:51 +08:00
if ( _aquireGPUStats )
{
checkQuery ( stats ) ;
}
// do cull taversal
osg : : Timer_t beforeCullTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2007-01-22 19:22:37 +08:00
_sceneView - > cull ( ) ;
osg : : Timer_t afterCullTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2007-01-05 05:49:02 +08:00
2007-01-30 06:44:29 +08:00
if ( state - > getDynamicObjectCount ( ) = = 0 & & state - > getDynamicObjectRenderingCompletedCallback ( ) )
{
state - > getDynamicObjectRenderingCompletedCallback ( ) - > completed ( state ) ;
}
2007-01-20 03:53:23 +08:00
2007-01-23 05:16:51 +08:00
// do draw traveral
if ( _aquireGPUStats )
2007-01-20 03:53:23 +08:00
{
2007-01-23 05:16:51 +08:00
checkQuery ( stats ) ;
beginQuery ( frameNumber ) ;
2007-01-20 03:53:23 +08:00
}
2007-01-23 05:16:51 +08:00
_sceneView - > draw ( ) ;
double availableTime = 0.004 ; // 4 ms
if ( _databasePager . valid ( ) )
2007-01-05 05:49:02 +08:00
{
2007-01-23 05:16:51 +08:00
_databasePager - > compileGLObjects ( * ( _sceneView - > getState ( ) ) , availableTime ) ;
}
_sceneView - > flushDeletedGLObjects ( availableTime ) ;
2007-01-20 03:53:23 +08:00
2007-01-23 05:16:51 +08:00
if ( _aquireGPUStats )
{
endQuery ( ) ;
checkQuery ( stats ) ;
2007-01-05 05:49:02 +08:00
}
2007-01-20 03:53:23 +08:00
2007-01-22 19:22:37 +08:00
osg : : Timer_t afterDrawTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2007-01-20 03:53:23 +08:00
2007-01-23 05:16:51 +08:00
2007-01-22 19:22:37 +08:00
if ( stats )
{
2007-01-23 01:39:32 +08:00
stats - > setAttribute ( frameNumber , " Cull traversal begin time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , beforeCullTick ) ) ;
2007-01-22 19:22:37 +08:00
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-01-23 01:39:32 +08:00
stats - > setAttribute ( frameNumber , " Draw traversal begin time " , osg : : Timer : : instance ( ) - > delta_s ( _startTick , afterCullTick ) ) ;
2007-01-22 19:22:37 +08:00
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-01-20 03:53:23 +08:00
2007-01-05 05:49:02 +08:00
}
2007-01-22 19:22:37 +08:00
osg : : observer_ptr < osgUtil : : SceneView > _sceneView ;
osg : : observer_ptr < osgDB : : DatabasePager > _databasePager ;
osg : : Timer_t _startTick ;
2007-01-23 05:16:51 +08:00
bool _initialized ;
bool _aquireGPUStats ;
const osg : : Drawable : : Extensions * _extensions ;
QueryFrameNumberList _queryFrameNumberList ;
QueryList _availableQueryObjects ;
double _previousQueryTime ;
2007-01-05 05:49:02 +08:00
} ;
void Viewer : : setUpRenderingSupport ( )
{
2007-01-22 02:24:54 +08:00
# if 1
2007-01-05 05:49:02 +08:00
_cameraSceneViewMap . clear ( ) ;
Contexts contexts ;
getContexts ( contexts ) ;
2007-01-22 02:24:54 +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-05 05:49:02 +08:00
2007-01-22 02:24:54 +08:00
for ( Contexts : : iterator gcitr = contexts . begin ( ) ;
gcitr ! = contexts . end ( ) ;
+ + gcitr )
2007-01-05 05:49:02 +08:00
{
2007-01-22 02:24:54 +08:00
( * gcitr ) - > removeAllOperations ( ) ;
osg : : GraphicsContext * gc = * gcitr ;
osg : : GraphicsContext : : Cameras & cameras = gc - > getCameras ( ) ;
osg : : State * state = gc - > getState ( ) ;
for ( osg : : GraphicsContext : : Cameras : : iterator citr = cameras . begin ( ) ;
citr ! = cameras . end ( ) ;
+ + citr )
{
osg : : Camera * camera = * citr ;
camera - > setStats ( new osg : : Stats ( " Camera " ) ) ;
osgUtil : : SceneView * sceneView = new osgUtil : : SceneView ;
_cameraSceneViewMap [ camera ] = sceneView ;
sceneView - > setGlobalStateSet ( _camera - > getStateSet ( ) ) ;
sceneView - > setDefaults ( ) ;
sceneView - > setDisplaySettings ( ds ) ;
sceneView - > setCamera ( camera ) ;
sceneView - > setState ( state ) ;
sceneView - > setFrameStamp ( frameStamp ) ;
if ( dp ) dp - > setCompileGLObjectsForContextID ( state - > getContextID ( ) , true ) ;
2007-01-22 19:22:37 +08:00
gc - > add ( new ViewerRenderingOperation ( sceneView , dp , _startTick ) ) ;
2007-01-22 02:24:54 +08:00
}
2007-01-05 05:49:02 +08:00
}
2007-01-22 02:24:54 +08:00
# else
_cameraSceneViewMap . clear ( ) ;
Contexts contexts ;
getContexts ( contexts ) ;
osg : : FrameStamp * frameStamp = getFrameStamp ( ) ;
2007-01-12 01:00:09 +08:00
osg : : DisplaySettings * ds = _displaySettings . valid ( ) ? _displaySettings . get ( ) : osg : : DisplaySettings : : instance ( ) ;
2007-01-15 22:46:16 +08:00
osgDB : : DatabasePager * dp = _scene . valid ( ) ? _scene - > getDatabasePager ( ) : 0 ;
2007-01-12 01:00:09 +08:00
2007-01-22 02:24:54 +08:00
// clear out all the previously assigned operations
for ( Contexts : : iterator gcitr = contexts . begin ( ) ;
gcitr ! = contexts . end ( ) ;
+ + gcitr )
{
( * gcitr ) - > removeAllOperations ( ) ;
}
2007-01-05 05:49:02 +08:00
if ( _camera . valid ( ) & & _camera - > getGraphicsContext ( ) )
{
2007-01-22 02:24:54 +08:00
_camera - > setStats ( new osg : : Stats ( " Camera " ) ) ;
2007-01-20 03:53:23 +08:00
2007-01-05 05:49:02 +08:00
osgUtil : : SceneView * sceneView = new osgUtil : : SceneView ;
_cameraSceneViewMap [ _camera ] = sceneView ;
2007-01-12 20:10:06 +08:00
sceneView - > setGlobalStateSet ( _camera - > getStateSet ( ) ) ;
2007-01-05 05:49:02 +08:00
sceneView - > setDefaults ( ) ;
2007-01-12 01:00:09 +08:00
sceneView - > setDisplaySettings ( ds ) ;
2007-01-05 05:49:02 +08:00
sceneView - > setCamera ( _camera . get ( ) ) ;
sceneView - > setState ( _camera - > getGraphicsContext ( ) - > getState ( ) ) ;
sceneView - > setSceneData ( getSceneData ( ) ) ;
sceneView - > setFrameStamp ( frameStamp ) ;
2007-01-18 05:11:57 +08:00
if ( dp ) dp - > setCompileGLObjectsForContextID ( _camera - > getGraphicsContext ( ) - > getState ( ) - > getContextID ( ) , true ) ;
2007-01-05 05:49:02 +08:00
2007-01-16 16:56:33 +08:00
_camera - > getGraphicsContext ( ) - > add ( new ViewerRenderingOperation ( sceneView , dp ) ) ;
2007-01-05 05:49:02 +08:00
}
for ( unsigned i = 0 ; i < getNumSlaves ( ) ; + + i )
{
Slave & slave = getSlave ( i ) ;
if ( slave . _camera . valid ( ) & & slave . _camera - > getGraphicsContext ( ) )
{
2007-01-20 03:53:23 +08:00
_camera - > setStats ( new osg : : Stats ( " Slave Camera " ) ) ;
2007-01-05 05:49:02 +08:00
osgUtil : : SceneView * sceneView = new osgUtil : : SceneView ;
_cameraSceneViewMap [ slave . _camera ] = sceneView ;
2007-01-12 20:10:06 +08:00
sceneView - > setGlobalStateSet ( _camera - > getStateSet ( ) ) ;
2007-01-05 05:49:02 +08:00
sceneView - > setDefaults ( ) ;
sceneView - > setCamera ( slave . _camera . get ( ) ) ;
2007-01-12 01:00:09 +08:00
sceneView - > setDisplaySettings ( ds ) ;
2007-01-05 05:49:02 +08:00
sceneView - > setState ( slave . _camera - > getGraphicsContext ( ) - > getState ( ) ) ;
sceneView - > setSceneData ( getSceneData ( ) ) ;
sceneView - > setFrameStamp ( frameStamp ) ;
2007-01-18 05:11:57 +08:00
if ( dp ) dp - > setCompileGLObjectsForContextID ( slave . _camera - > getGraphicsContext ( ) - > getState ( ) - > getContextID ( ) , true ) ;
2007-01-16 16:56:33 +08:00
slave . _camera - > getGraphicsContext ( ) - > add ( new ViewerRenderingOperation ( sceneView , dp ) ) ;
2007-01-05 05:49:02 +08:00
}
}
2007-01-22 02:24:54 +08:00
# endif
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
setUpViewAcrossAllScreens ( ) ;
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 ( ) ;
if ( _realizeOperation . valid ( ) )
{
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
startThreading ( ) ;
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
if ( getStats ( ) )
{
// 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 ( ) ) ;
}
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-01-22 02:34:26 +08:00
if ( camera - > getView ( ) = = this )
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 ( ) ) )
{
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 ( ) ;
event - > setInputRange ( eventState - > getXmin ( ) , eventState - > getYmin ( ) , eventState - > getXmax ( ) , eventState - > getYmax ( ) ) ;
event - > setX ( x ) ;
event - > setY ( y ) ;
event - > setMouseYOrientation ( osgGA : : GUIEventAdapter : : Y_INCREASING_UPWARDS ) ;
}
// 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-01-09 05:29:49 +08:00
// stopThreading();
2007-01-09 03:29:59 +08:00
gw - > close ( ) ;
2007-01-09 05:29:49 +08:00
// 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 ( ) ;
if ( _cameraManipulator . valid ( ) )
{
2007-01-24 20:28:18 +08:00
if ( _cameraManipulator - > handle ( * event , * this ) ) event - > setHandled ( true ) ;
2006-12-21 05:13:29 +08:00
}
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-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-01-20 04:25:17 +08:00
if ( getStats ( ) )
{
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 ( ) ) ;
2006-12-22 00:56:20 +08:00
if ( _scene . valid ( ) ) _scene - > frameUpdateTraversal ( ) ;
2006-12-21 05:13:29 +08:00
if ( _cameraManipulator . valid ( ) )
{
_camera - > setViewMatrix ( _cameraManipulator - > getInverseMatrix ( ) ) ;
}
updateSlaves ( ) ;
2007-01-20 04:25:17 +08:00
if ( getStats ( ) )
{
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 ;
if ( _endDynamicDrawBlock . valid ( ) )
{
unsigned int numToBlock = 0 ;
for ( itr = contexts . begin ( ) ;
itr ! = contexts . end ( ) ;
+ + itr )
{
if ( ( ( * itr ) - > getGraphicsThread ( ) ) ) + + numToBlock ;
}
_endDynamicDrawBlock - > set ( numToBlock ) ;
}
2006-12-23 01:46:21 +08:00
2007-01-03 01:39:31 +08:00
// dispatch the the rendering threads
if ( _startRenderingBarrier . valid ( ) ) _startRenderingBarrier - > block ( ) ;
2006-12-22 00:56:20 +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 ;
if ( ! ( ( * itr ) - > getGraphicsThread ( ) ) )
{
2006-12-23 01:46:21 +08:00
( * itr ) - > makeCurrent ( ) ;
( * itr ) - > runOperations ( ) ;
2007-01-09 00:20:10 +08:00
( * itr ) - > releaseContext ( ) ;
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-30 06:44:29 +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-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-01-03 01:39:31 +08:00
if ( ! ( ( * itr ) - > getGraphicsThread ( ) ) )
{
2006-12-23 01:46:21 +08:00
( * itr ) - > makeCurrent ( ) ;
( * itr ) - > swapBuffers ( ) ;
2007-01-09 00:20:10 +08:00
( * itr ) - > releaseContext ( ) ;
2006-12-23 01:46:21 +08:00
}
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
if ( getStats ( ) )
{
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
}