2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org
7 Copyright (c) 2000-2006 Torus Knot Software Ltd
8 Also see acknowledgements in Readme.html
10 This program is free software; you can redistribute it and/or modify it under
11 the terms of the GNU Lesser General Public License as published by the Free Software
12 Foundation; either version 2 of the License, or (at your option) any later
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22 http://www.gnu.org/copyleft/lesser.txt.
24 You may alternatively use this source under the terms of a specific version of
25 the OGRE Unrestricted License provided you have obtained such a license from
26 Torus Knot Software Ltd.
27 -----------------------------------------------------------------------------
30 #include "OgreStableHeaders.h"
34 #include "OgreRenderSystem.h"
35 #include "OgreRenderWindow.h"
36 #include "OgreException.h"
37 #include "OgreControllerManager.h"
38 #include "OgreLogManager.h"
40 #include "OgreDynLibManager.h"
41 #include "OgreDynLib.h"
42 #include "OgreConfigFile.h"
43 #include "OgreMaterialManager.h"
44 #include "OgreRenderSystemCapabilitiesManager.h"
45 #include "OgreMeshManager.h"
46 #include "OgreTextureManager.h"
47 #include "OgreParticleSystemManager.h"
48 #include "OgreSkeletonManager.h"
49 #include "OgreOverlayElementFactory.h"
50 #include "OgreOverlayManager.h"
51 #include "OgreProfiler.h"
52 #include "OgreErrorDialog.h"
53 #include "OgreConfigDialog.h"
54 #include "OgreStringConverter.h"
55 #include "OgreArchiveManager.h"
56 #include "OgrePlugin.h"
58 #include "OgreFileSystem.h"
59 #include "OgreShadowVolumeExtrudeProgram.h"
60 #include "OgreResourceBackgroundQueue.h"
61 #include "OgreEntity.h"
62 #include "OgreBillboardSet.h"
63 #include "OgreBillboardChain.h"
64 #include "OgreRibbonTrail.h"
65 #include "OgreLight.h"
66 #include "OgreManualObject.h"
67 #include "OgreRenderQueueInvocation.h"
68 #include "OgrePlatformInformation.h"
69 #include "OgreConvexBody.h"
71 #if OGRE_NO_FREEIMAGE == 0
72 #include "OgreFreeImageCodec.h"
74 #if OGRE_NO_DEVIL == 0
75 #include "OgreILCodecs.h"
77 #if OGRE_NO_DDS_CODEC == 0
78 #include "OgreDDSCodec.h"
81 #include "OgreFontManager.h"
82 #include "OgreHardwareBufferManager.h"
84 #include "OgreOverlay.h"
85 #include "OgreHighLevelGpuProgramManager.h"
87 #include "OgreExternalTextureSourceManager.h"
88 #include "OgreCompositorManager.h"
90 #include "OgreScriptCompiler.h"
92 #include "OgreWindowEventUtilities.h"
95 //-----------------------------------------------------------------------
96 template<> Root
* Singleton
<Root
>::ms_Singleton
= 0;
97 Root
* Root::getSingletonPtr(void)
101 Root
& Root::getSingleton(void)
103 assert( ms_Singleton
); return ( *ms_Singleton
);
106 typedef void (*DLL_START_PLUGIN
)(void);
107 typedef void (*DLL_STOP_PLUGIN
)(void);
110 //-----------------------------------------------------------------------
111 Root::Root(const String
& pluginFileName
, const String
& configFileName
,
112 const String
& logFileName
)
114 , mRenderSystemCapabilitiesManager(0)
116 , mFrameSmoothingTime(0.0f
)
117 , mNextMovableObjectTypeFlag(1)
118 , mIsInitialised(false)
120 // superclass will do singleton checking
125 mVersion
= StringConverter::toString(OGRE_VERSION_MAJOR
) + "." +
126 StringConverter::toString(OGRE_VERSION_MINOR
) + "." +
127 StringConverter::toString(OGRE_VERSION_PATCH
) +
128 OGRE_VERSION_SUFFIX
+ " " +
129 "(" + OGRE_VERSION_NAME
+ ")";
130 mConfigFileName
= configFileName
;
132 // Create log manager and default log file if there is no log manager yet
133 if(LogManager::getSingletonPtr() == 0)
135 mLogManager
= OGRE_NEW
LogManager();
136 mLogManager
->createLog(logFileName
, true, true);
139 // Dynamic library manager
140 mDynLibManager
= OGRE_NEW
DynLibManager();
142 mArchiveManager
= OGRE_NEW
ArchiveManager();
144 // ResourceGroupManager
145 mResourceGroupManager
= OGRE_NEW
ResourceGroupManager();
147 // ResourceBackgroundQueue
148 mResourceBackgroundQueue
= OGRE_NEW
ResourceBackgroundQueue();
150 // Create SceneManager enumerator (note - will be managed by singleton)
151 mSceneManagerEnum
= OGRE_NEW
SceneManagerEnumerator();
152 mCurrentSceneManager
= NULL
;
154 mShadowTextureManager
= OGRE_NEW
ShadowTextureManager();
156 mRenderSystemCapabilitiesManager
= OGRE_NEW
RenderSystemCapabilitiesManager();
158 // ..material manager
159 mMaterialManager
= OGRE_NEW
MaterialManager();
162 mMeshManager
= OGRE_NEW
MeshManager();
165 mSkeletonManager
= OGRE_NEW
SkeletonManager();
167 // ..particle system manager
168 mParticleManager
= OGRE_NEW
ParticleSystemManager();
171 //mCompilerManager = OGRE_NEW ScriptCompilerManager();
173 mTimer
= OGRE_NEW
Timer();
176 mOverlayManager
= OGRE_NEW
OverlayManager();
178 mPanelFactory
= OGRE_NEW
PanelOverlayElementFactory();
179 mOverlayManager
->addOverlayElementFactory(mPanelFactory
);
181 mBorderPanelFactory
= OGRE_NEW
BorderPanelOverlayElementFactory();
182 mOverlayManager
->addOverlayElementFactory(mBorderPanelFactory
);
184 mTextAreaFactory
= OGRE_NEW
TextAreaOverlayElementFactory();
185 mOverlayManager
->addOverlayElementFactory(mTextAreaFactory
);
187 mFontManager
= OGRE_NEW
FontManager();
189 // Lod strategy manager
190 mLodStrategyManager
= OGRE_NEW
LodStrategyManager();
194 mProfiler
= OGRE_NEW
Profiler();
195 Profiler::getSingleton().setTimer(mTimer
);
197 mFileSystemArchiveFactory
= OGRE_NEW
FileSystemArchiveFactory();
198 ArchiveManager::getSingleton().addArchiveFactory( mFileSystemArchiveFactory
);
199 mZipArchiveFactory
= OGRE_NEW
ZipArchiveFactory();
200 ArchiveManager::getSingleton().addArchiveFactory( mZipArchiveFactory
);
201 #if OGRE_NO_FREEIMAGE == 0
202 // Register image codecs
203 FreeImageCodec::startup();
205 #if OGRE_NO_DEVIL == 0
206 // Register image codecs
207 ILCodecs::registerCodecs();
209 #if OGRE_NO_DDS_CODEC == 0
210 // Register image codecs
214 mHighLevelGpuProgramManager
= OGRE_NEW
HighLevelGpuProgramManager();
216 mExternalTextureSourceManager
= OGRE_NEW
ExternalTextureSourceManager();
217 mCompositorManager
= OGRE_NEW
CompositorManager();
219 mCompilerManager
= OGRE_NEW
ScriptCompilerManager();
224 // instantiate and register base movable factories
225 mEntityFactory
= OGRE_NEW
EntityFactory();
226 addMovableObjectFactory(mEntityFactory
);
227 mLightFactory
= OGRE_NEW
LightFactory();
228 addMovableObjectFactory(mLightFactory
);
229 mBillboardSetFactory
= OGRE_NEW
BillboardSetFactory();
230 addMovableObjectFactory(mBillboardSetFactory
);
231 mManualObjectFactory
= OGRE_NEW
ManualObjectFactory();
232 addMovableObjectFactory(mManualObjectFactory
);
233 mBillboardChainFactory
= OGRE_NEW
BillboardChainFactory();
234 addMovableObjectFactory(mBillboardChainFactory
);
235 mRibbonTrailFactory
= OGRE_NEW
RibbonTrailFactory();
236 addMovableObjectFactory(mRibbonTrailFactory
);
239 if (!pluginFileName
.empty())
240 loadPlugins(pluginFileName
);
242 LogManager::getSingleton().logMessage("*-*-* OGRE Initialising");
243 msg
= "*-*-* Version " + mVersion
;
244 LogManager::getSingleton().logMessage(msg
);
246 // Can't create managers until initialised
247 mControllerManager
= 0;
249 mFirstTimePostWindowInit
= false;
253 //-----------------------------------------------------------------------
257 OGRE_DELETE mSceneManagerEnum
;
258 OGRE_DELETE mShadowTextureManager
;
259 OGRE_DELETE mRenderSystemCapabilitiesManager
;
261 destroyAllRenderQueueInvocationSequences();
262 OGRE_DELETE mCompositorManager
;
263 OGRE_DELETE mExternalTextureSourceManager
;
264 #if OGRE_NO_FREEIMAGE == 0
265 FreeImageCodec::shutdown();
267 #if OGRE_NO_DEVIL == 0
268 ILCodecs::deleteCodecs();
270 #if OGRE_NO_DDS_CODEC == 0
271 DDSCodec::shutdown();
274 OGRE_DELETE mProfiler
;
276 OGRE_DELETE mOverlayManager
;
277 OGRE_DELETE mFontManager
;
278 OGRE_DELETE mLodStrategyManager
;
279 OGRE_DELETE mArchiveManager
;
280 OGRE_DELETE mZipArchiveFactory
;
281 OGRE_DELETE mFileSystemArchiveFactory
;
282 OGRE_DELETE mSkeletonManager
;
283 OGRE_DELETE mMeshManager
;
284 OGRE_DELETE mParticleManager
;
285 //OGRE_DELETE mCompilerManager;
287 if( mControllerManager
)
288 OGRE_DELETE mControllerManager
;
289 if (mHighLevelGpuProgramManager
)
290 OGRE_DELETE mHighLevelGpuProgramManager
;
292 OGRE_DELETE mTextAreaFactory
;
293 OGRE_DELETE mBorderPanelFactory
;
294 OGRE_DELETE mPanelFactory
;
297 OGRE_DELETE mMaterialManager
;
298 Pass::processPendingPassUpdates(); // make sure passes are cleaned
299 OGRE_DELETE mResourceBackgroundQueue
;
300 OGRE_DELETE mResourceGroupManager
;
302 OGRE_DELETE mEntityFactory
;
303 OGRE_DELETE mLightFactory
;
304 OGRE_DELETE mBillboardSetFactory
;
305 OGRE_DELETE mManualObjectFactory
;
306 OGRE_DELETE mBillboardChainFactory
;
307 OGRE_DELETE mRibbonTrailFactory
;
311 OGRE_DELETE mDynLibManager
;
312 OGRE_DELETE mLogManager
;
314 OGRE_DELETE mCompilerManager
;
317 mFirstTimePostWindowInit
= false;
320 StringInterface::cleanupDictionary ();
323 //-----------------------------------------------------------------------
324 void Root::saveConfig(void)
326 if (mConfigFileName
.empty ())
329 std::ofstream
of(mConfigFileName
.c_str());
332 OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE
, "Cannot create settings file.",
337 of
<< "Render System=" << mActiveRenderer
->getName() << std::endl
;
341 of
<< "Render System=" << std::endl
;
344 for (RenderSystemList::const_iterator pRend
= getAvailableRenderers().begin(); pRend
!= getAvailableRenderers().end(); ++pRend
)
346 RenderSystem
* rs
= *pRend
;
348 of
<< "[" << rs
->getName() << "]" << std::endl
;
349 const ConfigOptionMap
& opts
= rs
->getConfigOptions();
350 for (ConfigOptionMap::const_iterator pOpt
= opts
.begin(); pOpt
!= opts
.end(); ++pOpt
)
352 of
<< pOpt
->first
<< "=" << pOpt
->second
.currentValue
<< std::endl
;
359 //-----------------------------------------------------------------------
360 bool Root::restoreConfig(void)
362 if (mConfigFileName
.empty ())
365 // Restores configuration from saved state
366 // Returns true if a valid saved configuration is
367 // available, and false if no saved config is
368 // stored, or if there has been a problem
372 // Don't trim whitespace
373 cfg
.load(mConfigFileName
, "\t:=", false);
377 if (e
.getNumber() == Exception::ERR_FILE_NOT_FOUND
)
387 ConfigFile::SectionIterator iSection
= cfg
.getSectionIterator();
388 while (iSection
.hasMoreElements())
390 const String
& renderSystem
= iSection
.peekNextKey();
391 const ConfigFile::SettingsMultiMap
& settings
= *iSection
.getNext();
393 RenderSystem
* rs
= getRenderSystemByName(renderSystem
);
396 // Unrecognised render system
400 ConfigFile::SettingsMultiMap::const_iterator i
;
401 for (i
= settings
.begin(); i
!= settings
.end(); ++i
)
403 rs
->setConfigOption(i
->first
, i
->second
);
407 RenderSystem
* rs
= getRenderSystemByName(cfg
.getSetting("Render System"));
410 // Unrecognised render system
421 //-----------------------------------------------------------------------
422 bool Root::showConfigDialog(void)
424 // Displays the standard config dialog
425 // Will use stored defaults if available
431 dlg
= OGRE_NEW
ConfigDialog();
433 if ((isOk
= dlg
->display()))
440 //-----------------------------------------------------------------------
441 const RenderSystemList
& Root::getAvailableRenderers(void)
443 // Returns a vector of renders
449 //-----------------------------------------------------------------------
450 RenderSystem
* Root::getRenderSystemByName(const String
& name
)
458 RenderSystemList::const_iterator pRend
;
459 for (pRend
= getAvailableRenderers().begin(); pRend
!= getAvailableRenderers().end(); ++pRend
)
461 RenderSystem
* rs
= *pRend
;
462 if (rs
->getName() == name
)
466 // Unrecognised render system
470 //-----------------------------------------------------------------------
471 void Root::setRenderSystem(RenderSystem
* system
)
473 // Sets the active rendering system
474 // Can be called direct or will be called by
475 // standard config dialog
477 // Is there already an active renderer?
478 // If so, disable it and init the new one
479 if( mActiveRenderer
&& mActiveRenderer
!= system
)
481 mActiveRenderer
->shutdown();
484 mActiveRenderer
= system
;
485 // Tell scene managers
486 SceneManagerEnumerator::getSingleton().setRenderSystem(system
);
489 //-----------------------------------------------------------------------
490 void Root::addRenderSystem(RenderSystem
*newRend
)
492 mRenderers
.push_back(newRend
);
494 //-----------------------------------------------------------------------
495 void Root::_setCurrentSceneManager(SceneManager
* sm
)
497 mCurrentSceneManager
= sm
;
499 //-----------------------------------------------------------------------
500 RenderSystem
* Root::getRenderSystem(void)
502 // Gets the currently active renderer
503 return mActiveRenderer
;
507 //-----------------------------------------------------------------------
508 RenderWindow
* Root::initialise(bool autoCreateWindow
, const String
& windowTitle
, const String
& customCapabilitiesConfig
)
510 if (!mActiveRenderer
)
511 OGRE_EXCEPT(Exception::ERR_INVALID_STATE
,
512 "Cannot initialise - no render "
513 "system has been selected.", "Root::initialise");
515 if (!mControllerManager
)
516 mControllerManager
= OGRE_NEW
ControllerManager();
518 // .rendercaps manager
519 RenderSystemCapabilitiesManager
& rscManager
= RenderSystemCapabilitiesManager::getSingleton();
520 // caller wants to load custom RenderSystemCapabilities form a config file
521 if(customCapabilitiesConfig
!= StringUtil::BLANK
)
524 cfg
.load(customCapabilitiesConfig
, "\t:=", false);
526 // Capabilities Database setting must be in the same format as
527 // resources.cfg in Ogre examples.
528 ConfigFile::SettingsIterator iter
= cfg
.getSettingsIterator("Capabilities Database");
529 while(iter
.hasMoreElements())
531 String archType
= iter
.peekNextKey();
532 String filename
= iter
.getNext();
534 rscManager
.parseCapabilitiesFromArchive(filename
, archType
, true);
537 String capsName
= cfg
.getSetting("Custom Capabilities");
538 // The custom capabilities have been parsed, let's retrieve them
539 RenderSystemCapabilities
* rsc
= rscManager
.loadParsedCapabilities(capsName
);
542 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND
,
543 String("Cannot load a RenderSystemCapability named ") + capsName
,
547 // Tell RenderSystem to use the comon rsc
548 useCustomRenderSystemCapabilities(rsc
);
552 PlatformInformation::log(LogManager::getSingleton().getDefaultLog());
553 mAutoWindow
= mActiveRenderer
->_initialise(autoCreateWindow
, windowTitle
);
556 if (autoCreateWindow
&& !mFirstTimePostWindowInit
)
558 oneTimePostWindowInit();
559 mAutoWindow
->_setPrimary();
566 ConvexBody::_initialisePool();
568 mIsInitialised
= true;
573 //-----------------------------------------------------------------------
574 void Root::useCustomRenderSystemCapabilities(RenderSystemCapabilities
* capabilities
)
576 mActiveRenderer
->useCustomRenderSystemCapabilities(capabilities
);
578 //-----------------------------------------------------------------------
579 String
Root::getErrorDescription(long errorNumber
)
582 // Pass to render system
584 return mActiveRenderer
->getErrorDescription(errorNumber
);
589 //-----------------------------------------------------------------------
590 void Root::addSceneManagerFactory(SceneManagerFactory
* fact
)
592 mSceneManagerEnum
->addFactory(fact
);
594 //-----------------------------------------------------------------------
595 void Root::removeSceneManagerFactory(SceneManagerFactory
* fact
)
597 mSceneManagerEnum
->removeFactory(fact
);
599 //-----------------------------------------------------------------------
600 const SceneManagerMetaData
* Root::getSceneManagerMetaData(const String
& typeName
) const
602 return mSceneManagerEnum
->getMetaData(typeName
);
604 //-----------------------------------------------------------------------
605 SceneManagerEnumerator::MetaDataIterator
606 Root::getSceneManagerMetaDataIterator(void) const
608 return mSceneManagerEnum
->getMetaDataIterator();
611 //-----------------------------------------------------------------------
612 SceneManager
* Root::createSceneManager(const String
& typeName
,
613 const String
& instanceName
)
615 return mSceneManagerEnum
->createSceneManager(typeName
, instanceName
);
617 //-----------------------------------------------------------------------
618 SceneManager
* Root::createSceneManager(SceneTypeMask typeMask
,
619 const String
& instanceName
)
621 return mSceneManagerEnum
->createSceneManager(typeMask
, instanceName
);
623 //-----------------------------------------------------------------------
624 void Root::destroySceneManager(SceneManager
* sm
)
626 mSceneManagerEnum
->destroySceneManager(sm
);
628 //-----------------------------------------------------------------------
629 SceneManager
* Root::getSceneManager(const String
& instanceName
) const
631 return mSceneManagerEnum
->getSceneManager(instanceName
);
633 //-----------------------------------------------------------------------
634 SceneManagerEnumerator::SceneManagerIterator
Root::getSceneManagerIterator(void)
636 return mSceneManagerEnum
->getSceneManagerIterator();
638 //-----------------------------------------------------------------------
639 TextureManager
* Root::getTextureManager(void)
641 return &TextureManager::getSingleton();
643 //-----------------------------------------------------------------------
644 MeshManager
* Root::getMeshManager(void)
646 return &MeshManager::getSingleton();
648 //-----------------------------------------------------------------------
649 void Root::addFrameListener(FrameListener
* newListener
)
651 // Check if the specified listener is scheduled for removal
652 set
<FrameListener
*>::type::iterator i
= mRemovedFrameListeners
.find(newListener
);
654 // If yes, cancel the removal. Otherwise add it to other listeners.
655 if (i
!= mRemovedFrameListeners
.end())
656 mRemovedFrameListeners
.erase(*i
);
658 mFrameListeners
.insert(newListener
); // Insert, unique only (set)
661 //-----------------------------------------------------------------------
662 void Root::removeFrameListener(FrameListener
* oldListener
)
664 // Remove, 1 only (set)
665 mRemovedFrameListeners
.insert(oldListener
);
667 //-----------------------------------------------------------------------
668 bool Root::_fireFrameStarted(FrameEvent
& evt
)
670 OgreProfileBeginGroup("Frame", OGREPROF_GENERAL
);
672 // Remove all marked listeners
673 set
<FrameListener
*>::type::iterator i
;
674 for (i
= mRemovedFrameListeners
.begin();
675 i
!= mRemovedFrameListeners
.end(); i
++)
677 mFrameListeners
.erase(*i
);
679 mRemovedFrameListeners
.clear();
681 // Tell all listeners
682 for (i
= mFrameListeners
.begin(); i
!= mFrameListeners
.end(); ++i
)
684 if (!(*i
)->frameStarted(evt
))
691 //-----------------------------------------------------------------------
692 bool Root::_fireFrameRenderingQueued(FrameEvent
& evt
)
694 // Increment next frame number
697 // Remove all marked listeners
698 set
<FrameListener
*>::type::iterator i
;
699 for (i
= mRemovedFrameListeners
.begin();
700 i
!= mRemovedFrameListeners
.end(); i
++)
702 mFrameListeners
.erase(*i
);
704 mRemovedFrameListeners
.clear();
706 // Tell all listeners
707 for (i
= mFrameListeners
.begin(); i
!= mFrameListeners
.end(); ++i
)
709 if (!(*i
)->frameRenderingQueued(evt
))
716 //-----------------------------------------------------------------------
717 bool Root::_fireFrameEnded(FrameEvent
& evt
)
719 // Remove all marked listeners
720 set
<FrameListener
*>::type::iterator i
;
721 for (i
= mRemovedFrameListeners
.begin();
722 i
!= mRemovedFrameListeners
.end(); i
++)
724 mFrameListeners
.erase(*i
);
726 mRemovedFrameListeners
.clear();
728 // Tell all listeners
730 for (i
= mFrameListeners
.begin(); i
!= mFrameListeners
.end(); ++i
)
732 if (!(*i
)->frameEnded(evt
))
739 // Tell buffer manager to free temp buffers used this frame
740 if (HardwareBufferManager::getSingletonPtr())
741 HardwareBufferManager::getSingleton()._releaseBufferCopies();
743 // Also tell the ResourceBackgroundQueue to propagate background load events
744 ResourceBackgroundQueue::getSingleton()._fireOnFrameCallbacks();
746 OgreProfileEndGroup("Frame", OGREPROF_GENERAL
);
750 //-----------------------------------------------------------------------
751 bool Root::_fireFrameStarted()
754 populateFrameEvent(FETT_STARTED
, evt
);
756 return _fireFrameStarted(evt
);
758 //-----------------------------------------------------------------------
759 bool Root::_fireFrameRenderingQueued()
762 populateFrameEvent(FETT_QUEUED
, evt
);
764 return _fireFrameRenderingQueued(evt
);
766 //-----------------------------------------------------------------------
767 bool Root::_fireFrameEnded()
770 populateFrameEvent(FETT_ENDED
, evt
);
771 return _fireFrameEnded(evt
);
773 //---------------------------------------------------------------------
774 void Root::populateFrameEvent(FrameEventTimeType type
, FrameEvent
& evtToUpdate
)
776 unsigned long now
= mTimer
->getMilliseconds();
777 evtToUpdate
.timeSinceLastEvent
= calculateEventTime(now
, FETT_ANY
);
778 evtToUpdate
.timeSinceLastFrame
= calculateEventTime(now
, type
);
780 //-----------------------------------------------------------------------
781 Real
Root::calculateEventTime(unsigned long now
, FrameEventTimeType type
)
783 // Calculate the average time passed between events of the given type
784 // during the last mFrameSmoothingTime seconds.
786 EventTimesQueue
& times
= mEventTimes
[type
];
787 times
.push_back(now
);
789 if(times
.size() == 1)
792 // Times up to mFrameSmoothingTime seconds old should be kept
793 unsigned long discardThreshold
=
794 static_cast<unsigned long>(mFrameSmoothingTime
* 1000.0f
);
796 // Find the oldest time to keep
797 EventTimesQueue::iterator it
= times
.begin(),
798 end
= times
.end()-2; // We need at least two times
801 if (now
- *it
> discardThreshold
)
808 times
.erase(times
.begin(), it
);
810 return Real(times
.back() - times
.front()) / ((times
.size()-1) * 1000);
812 //-----------------------------------------------------------------------
813 void Root::queueEndRendering(void)
817 //-----------------------------------------------------------------------
818 void Root::startRendering(void)
820 assert(mActiveRenderer
!= 0);
822 mActiveRenderer
->_initRenderTargets();
827 // Infinite loop, until broken out of by frame listeners
828 // or break out by calling queueEndRendering()
833 //Pump messages in all registered RenderWindow windows
834 WindowEventUtilities::messagePump();
836 if (!renderOneFrame())
840 //-----------------------------------------------------------------------
841 bool Root::renderOneFrame(void)
843 if(!_fireFrameStarted())
846 if (!_updateAllRenderTargets())
849 return _fireFrameEnded();
851 //---------------------------------------------------------------------
852 bool Root::renderOneFrame(Real timeSinceLastFrame
)
855 evt
.timeSinceLastFrame
= timeSinceLastFrame
;
857 unsigned long now
= mTimer
->getMilliseconds();
858 evt
.timeSinceLastEvent
= calculateEventTime(now
, FETT_ANY
);
860 if(!_fireFrameStarted(evt
))
863 if (!_updateAllRenderTargets(evt
))
866 now
= mTimer
->getMilliseconds();
867 evt
.timeSinceLastEvent
= calculateEventTime(now
, FETT_ANY
);
869 return _fireFrameEnded(evt
);
871 //-----------------------------------------------------------------------
872 void Root::shutdown(void)
874 SceneManagerEnumerator::getSingleton().shutdownAll();
877 ShadowVolumeExtrudeProgram::shutdown();
878 mResourceBackgroundQueue
->shutdown();
879 ResourceGroupManager::getSingleton().shutdownAll();
882 ConvexBody::_destroyPool();
885 mIsInitialised
= false;
887 LogManager::getSingleton().logMessage("*-*-* OGRE Shutdown");
889 //-----------------------------------------------------------------------
890 void Root::loadPlugins( const String
& pluginsfile
)
892 StringVector pluginList
;
897 cfg
.load( pluginsfile
);
901 LogManager::getSingleton().logMessage(pluginsfile
+ " not found, automatic plugin loading disabled.");
905 pluginDir
= cfg
.getSetting("PluginFolder"); // Ignored on Mac OS X, uses Resources/ directory
906 pluginList
= cfg
.getMultiSetting("Plugin");
908 #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE
909 if (pluginDir
.empty())
911 // User didn't specify plugins folder, try current one
916 char last_char
= pluginDir
[pluginDir
.length()-1];
917 if (last_char
!= '/' && last_char
!= '\\')
919 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
921 #elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
926 for( StringVector::iterator it
= pluginList
.begin(); it
!= pluginList
.end(); ++it
)
928 loadPlugin(pluginDir
+ (*it
));
932 //-----------------------------------------------------------------------
933 void Root::shutdownPlugins(void)
935 // NB Shutdown plugins in reverse order to enforce dependencies
936 for (PluginInstanceList::reverse_iterator i
= mPlugins
.rbegin(); i
!= mPlugins
.rend(); ++i
)
941 //-----------------------------------------------------------------------
942 void Root::initialisePlugins(void)
944 for (PluginInstanceList::iterator i
= mPlugins
.begin(); i
!= mPlugins
.end(); ++i
)
949 //-----------------------------------------------------------------------
950 void Root::unloadPlugins(void)
952 // unload dynamic libs first
953 for (PluginLibList::reverse_iterator i
= mPluginLibs
.rbegin(); i
!= mPluginLibs
.rend(); ++i
)
955 // Call plugin shutdown
956 DLL_STOP_PLUGIN pFunc
= (DLL_STOP_PLUGIN
)(*i
)->getSymbol("dllStopPlugin");
957 // this will call uninstallPlugin
959 // Unload library & destroy
960 DynLibManager::getSingleton().unload(*i
);
965 // now deal with any remaining plugins that were registered through other means
966 for (PluginInstanceList::reverse_iterator i
= mPlugins
.rbegin(); i
!= mPlugins
.rend(); ++i
)
968 // Note this does NOT call uninstallPlugin - this shutdown is for the
975 //-----------------------------------------------------------------------
976 void Root::addResourceLocation(const String
& name
, const String
& locType
,
977 const String
& groupName
, bool recursive
)
979 ResourceGroupManager::getSingleton().addResourceLocation(
980 name
, locType
, groupName
, recursive
);
982 //-----------------------------------------------------------------------
983 void Root::removeResourceLocation(const String
& name
, const String
& groupName
)
985 ResourceGroupManager::getSingleton().removeResourceLocation(
988 //-----------------------------------------------------------------------
989 void Root::convertColourValue(const ColourValue
& colour
, uint32
* pDest
)
991 assert(mActiveRenderer
!= 0);
992 mActiveRenderer
->convertColourValue(colour
, pDest
);
994 //-----------------------------------------------------------------------
995 RenderWindow
* Root::getAutoCreatedWindow(void)
999 //-----------------------------------------------------------------------
1000 RenderWindow
* Root::createRenderWindow(const String
&name
, unsigned int width
, unsigned int height
,
1001 bool fullScreen
, const NameValuePairList
*miscParams
)
1003 if (!mActiveRenderer
)
1005 OGRE_EXCEPT(Exception::ERR_INVALID_STATE
,
1006 "Cannot create window - no render "
1007 "system has been selected.", "Root::createRenderWindow");
1010 ret
= mActiveRenderer
->_createRenderWindow(name
, width
, height
, fullScreen
, miscParams
);
1012 // Initialisation for classes dependent on first window created
1013 if(!mFirstTimePostWindowInit
)
1015 oneTimePostWindowInit();
1022 //-----------------------------------------------------------------------
1023 bool Root::createRenderWindows(const RenderWindowDescriptionList
& renderWindowDescriptions
,
1024 RenderWindowList
& createdWindows
)
1026 if (!mActiveRenderer
)
1028 OGRE_EXCEPT(Exception::ERR_INVALID_STATE
,
1029 "Cannot create render windows - no render "
1030 "system has been selected.", "Root::createRenderWindows");
1035 success
= mActiveRenderer
->_createRenderWindows(renderWindowDescriptions
, createdWindows
);
1036 if(success
&& !mFirstTimePostWindowInit
)
1038 oneTimePostWindowInit();
1039 createdWindows
[0]->_setPrimary();
1044 //-----------------------------------------------------------------------
1045 void Root::detachRenderTarget(RenderTarget
* target
)
1047 if (!mActiveRenderer
)
1049 OGRE_EXCEPT(Exception::ERR_INVALID_STATE
,
1050 "Cannot create window - no render "
1051 "system has been selected.", "Root::destroyRenderWindow");
1054 mActiveRenderer
->detachRenderTarget( target
->getName() );
1056 //-----------------------------------------------------------------------
1057 void Root::detachRenderTarget(const String
&name
)
1059 if (!mActiveRenderer
)
1061 OGRE_EXCEPT(Exception::ERR_INVALID_STATE
,
1062 "Cannot create window - no render "
1063 "system has been selected.", "Root::destroyRenderWindow");
1066 mActiveRenderer
->detachRenderTarget( name
);
1068 //-----------------------------------------------------------------------
1069 RenderTarget
* Root::getRenderTarget(const String
&name
)
1071 if (!mActiveRenderer
)
1073 OGRE_EXCEPT(Exception::ERR_INVALID_STATE
,
1074 "Cannot create window - no render "
1075 "system has been selected.", "Root::getRenderWindow");
1078 return mActiveRenderer
->getRenderTarget(name
);
1080 //---------------------------------------------------------------------
1081 void Root::installPlugin(Plugin
* plugin
)
1083 LogManager::getSingleton().logMessage("Installing plugin: " + plugin
->getName());
1085 mPlugins
.push_back(plugin
);
1088 // if rendersystem is already initialised, call rendersystem init too
1091 plugin
->initialise();
1094 LogManager::getSingleton().logMessage("Plugin successfully installed");
1096 //---------------------------------------------------------------------
1097 void Root::uninstallPlugin(Plugin
* plugin
)
1099 LogManager::getSingleton().logMessage("Uninstalling plugin: " + plugin
->getName());
1100 PluginInstanceList::iterator i
=
1101 std::find(mPlugins
.begin(), mPlugins
.end(), plugin
);
1102 if (i
!= mPlugins
.end())
1106 plugin
->uninstall();
1109 LogManager::getSingleton().logMessage("Plugin successfully uninstalled");
1112 //-----------------------------------------------------------------------
1113 void Root::loadPlugin(const String
& pluginName
)
1115 // Load plugin library
1116 DynLib
* lib
= DynLibManager::getSingleton().load( pluginName
);
1117 // Store for later unload
1118 // Check for existence, because if called 2+ times DynLibManager returns existing entry
1119 if (std::find(mPluginLibs
.begin(), mPluginLibs
.end(), lib
) == mPluginLibs
.end())
1121 mPluginLibs
.push_back(lib
);
1123 // Call startup function
1124 DLL_START_PLUGIN pFunc
= (DLL_START_PLUGIN
)lib
->getSymbol("dllStartPlugin");
1127 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND
, "Cannot find symbol dllStartPlugin in library " + pluginName
,
1128 "Root::loadPlugin");
1130 // This must call installPlugin
1135 //-----------------------------------------------------------------------
1136 void Root::unloadPlugin(const String
& pluginName
)
1138 PluginLibList::iterator i
;
1140 for (i
= mPluginLibs
.begin(); i
!= mPluginLibs
.end(); ++i
)
1142 if ((*i
)->getName() == pluginName
)
1144 // Call plugin shutdown
1145 DLL_STOP_PLUGIN pFunc
= (DLL_STOP_PLUGIN
)(*i
)->getSymbol("dllStopPlugin");
1146 // this must call uninstallPlugin
1148 // Unload library (destroyed by DynLibManager)
1149 DynLibManager::getSingleton().unload(*i
);
1150 mPluginLibs
.erase(i
);
1156 //-----------------------------------------------------------------------
1157 Timer
* Root::getTimer(void)
1161 //-----------------------------------------------------------------------
1162 void Root::oneTimePostWindowInit(void)
1164 if (!mFirstTimePostWindowInit
)
1166 // Background loader
1167 mResourceBackgroundQueue
->initialise();
1168 // Initialise material manager
1169 mMaterialManager
->initialise();
1170 // Init particle systems manager
1171 mParticleManager
->_initialise();
1172 // Init mesh manager
1173 MeshManager::getSingleton()._initialise();
1174 // Init plugins - after window creation so rsys resources available
1175 initialisePlugins();
1176 mFirstTimePostWindowInit
= true;
1180 //-----------------------------------------------------------------------
1181 bool Root::_updateAllRenderTargets(void)
1183 // update all targets but don't swap buffers
1184 mActiveRenderer
->_updateAllRenderTargets(false);
1185 // give client app opportunity to use queued GPU time
1186 bool ret
= _fireFrameRenderingQueued();
1187 // block for final swap
1188 mActiveRenderer
->_swapAllRenderTargetBuffers(mActiveRenderer
->getWaitForVerticalBlank());
1190 // This belongs here, as all render targets must be updated before events are
1191 // triggered, otherwise targets could be mismatched. This could produce artifacts,
1192 // for instance, with shadows.
1193 for (SceneManagerEnumerator::SceneManagerIterator it
= getSceneManagerIterator(); it
.hasMoreElements(); it
.moveNext())
1194 it
.peekNextValue()->_handleLodEvents();
1198 //---------------------------------------------------------------------
1199 bool Root::_updateAllRenderTargets(FrameEvent
& evt
)
1201 // update all targets but don't swap buffers
1202 mActiveRenderer
->_updateAllRenderTargets(false);
1203 // give client app opportunity to use queued GPU time
1204 bool ret
= _fireFrameRenderingQueued(evt
);
1205 // block for final swap
1206 mActiveRenderer
->_swapAllRenderTargetBuffers(mActiveRenderer
->getWaitForVerticalBlank());
1208 // This belongs here, as all render targets must be updated before events are
1209 // triggered, otherwise targets could be mismatched. This could produce artifacts,
1210 // for instance, with shadows.
1211 for (SceneManagerEnumerator::SceneManagerIterator it
= getSceneManagerIterator(); it
.hasMoreElements(); it
.moveNext())
1212 it
.peekNextValue()->_handleLodEvents();
1216 //-----------------------------------------------------------------------
1217 void Root::clearEventTimes(void)
1219 // Clear event times
1220 for(int i
=0; i
<FETT_COUNT
; ++i
)
1221 mEventTimes
[i
].clear();
1223 //---------------------------------------------------------------------
1224 void Root::addMovableObjectFactory(MovableObjectFactory
* fact
,
1225 bool overrideExisting
)
1227 MovableObjectFactoryMap::iterator facti
= mMovableObjectFactoryMap
.find(
1229 if (!overrideExisting
&& facti
!= mMovableObjectFactoryMap
.end())
1231 OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM
,
1232 "A factory of type '" + fact
->getType() + "' already exists.",
1233 "Root::addMovableObjectFactory");
1236 if (fact
->requestTypeFlags())
1238 if (facti
!= mMovableObjectFactoryMap
.end() && facti
->second
->requestTypeFlags())
1240 // Copy type flags from the factory we're replacing
1241 fact
->_notifyTypeFlags(facti
->second
->getTypeFlags());
1246 fact
->_notifyTypeFlags(_allocateNextMovableObjectTypeFlag());
1251 mMovableObjectFactoryMap
[fact
->getType()] = fact
;
1253 LogManager::getSingleton().logMessage("MovableObjectFactory for type '" +
1254 fact
->getType() + "' registered.");
1257 //---------------------------------------------------------------------
1258 bool Root::hasMovableObjectFactory(const String
& typeName
) const
1260 return !(mMovableObjectFactoryMap
.find(typeName
) == mMovableObjectFactoryMap
.end());
1262 //---------------------------------------------------------------------
1263 MovableObjectFactory
* Root::getMovableObjectFactory(const String
& typeName
)
1265 MovableObjectFactoryMap::iterator i
=
1266 mMovableObjectFactoryMap
.find(typeName
);
1267 if (i
== mMovableObjectFactoryMap
.end())
1269 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND
,
1270 "MovableObjectFactory of type " + typeName
+ " does not exist",
1271 "Root::getMovableObjectFactory");
1275 //---------------------------------------------------------------------
1276 uint32
Root::_allocateNextMovableObjectTypeFlag(void)
1278 if (mNextMovableObjectTypeFlag
== SceneManager::USER_TYPE_MASK_LIMIT
)
1280 OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM
,
1281 "Cannot allocate a type flag since "
1282 "all the available flags have been used.",
1283 "Root::_allocateNextMovableObjectTypeFlag");
1286 uint32 ret
= mNextMovableObjectTypeFlag
;
1287 mNextMovableObjectTypeFlag
<<= 1;
1291 //---------------------------------------------------------------------
1292 void Root::removeMovableObjectFactory(MovableObjectFactory
* fact
)
1294 MovableObjectFactoryMap::iterator i
= mMovableObjectFactoryMap
.find(
1296 if (i
!= mMovableObjectFactoryMap
.end())
1298 mMovableObjectFactoryMap
.erase(i
);
1302 //---------------------------------------------------------------------
1303 Root::MovableObjectFactoryIterator
1304 Root::getMovableObjectFactoryIterator(void) const
1306 return MovableObjectFactoryIterator(mMovableObjectFactoryMap
.begin(),
1307 mMovableObjectFactoryMap
.end());
1310 //---------------------------------------------------------------------
1311 RenderQueueInvocationSequence
* Root::createRenderQueueInvocationSequence(
1314 RenderQueueInvocationSequenceMap::iterator i
=
1315 mRQSequenceMap
.find(name
);
1316 if (i
!= mRQSequenceMap
.end())
1318 OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM
,
1319 "RenderQueueInvocationSequence with the name " + name
+
1321 "Root::createRenderQueueInvocationSequence");
1323 RenderQueueInvocationSequence
* ret
= OGRE_NEW
RenderQueueInvocationSequence(name
);
1324 mRQSequenceMap
[name
] = ret
;
1327 //---------------------------------------------------------------------
1328 RenderQueueInvocationSequence
* Root::getRenderQueueInvocationSequence(
1331 RenderQueueInvocationSequenceMap::iterator i
=
1332 mRQSequenceMap
.find(name
);
1333 if (i
== mRQSequenceMap
.end())
1335 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND
,
1336 "RenderQueueInvocationSequence with the name " + name
+
1338 "Root::getRenderQueueInvocationSequence");
1342 //---------------------------------------------------------------------
1343 void Root::destroyRenderQueueInvocationSequence(
1346 RenderQueueInvocationSequenceMap::iterator i
=
1347 mRQSequenceMap
.find(name
);
1348 if (i
!= mRQSequenceMap
.end())
1350 OGRE_DELETE i
->second
;
1351 mRQSequenceMap
.erase(i
);
1354 //---------------------------------------------------------------------
1355 void Root::destroyAllRenderQueueInvocationSequences(void)
1357 for (RenderQueueInvocationSequenceMap::iterator i
= mRQSequenceMap
.begin();
1358 i
!= mRQSequenceMap
.end(); ++i
)
1360 OGRE_DELETE i
->second
;
1362 mRQSequenceMap
.clear();
1365 //---------------------------------------------------------------------
1366 unsigned int Root::getDisplayMonitorCount() const
1368 if (!mActiveRenderer
)
1370 OGRE_EXCEPT(Exception::ERR_INVALID_STATE
,
1371 "Cannot get display monitor count "
1372 "No render system has been selected.", "Root::getDisplayMonitorCount");
1375 return mActiveRenderer
->getDisplayMonitorCount();
1378 //---------------------------------------------------------------------