1 | /*
|
---|
2 | -----------------------------------------------------------------------------
|
---|
3 | This source file is part of OGRE
|
---|
4 | (Object-oriented Graphics Rendering Engine)
|
---|
5 | For the latest info, see http://ogre.sourceforge.net/
|
---|
6 |
|
---|
7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
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
|
---|
13 | version.
|
---|
14 |
|
---|
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.
|
---|
18 |
|
---|
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.
|
---|
23 | -----------------------------------------------------------------------------
|
---|
24 | */
|
---|
25 | // Ogre includes
|
---|
26 | #include "OgreStableHeaders.h"
|
---|
27 |
|
---|
28 | #include "OgreRoot.h"
|
---|
29 |
|
---|
30 | #include "OgreRenderSystem.h"
|
---|
31 | #include "OgreRenderWindow.h"
|
---|
32 | #include "OgreException.h"
|
---|
33 | #include "OgreControllerManager.h"
|
---|
34 | #include "OgreLogManager.h"
|
---|
35 | #include "OgreMath.h"
|
---|
36 | #include "OgreDynLibManager.h"
|
---|
37 | #include "OgreDynLib.h"
|
---|
38 | #include "OgreConfigFile.h"
|
---|
39 | #include "OgreMaterialManager.h"
|
---|
40 | #include "OgreMeshManager.h"
|
---|
41 | #include "OgreTextureManager.h"
|
---|
42 | #include "OgreParticleSystemManager.h"
|
---|
43 | #include "OgreSkeletonManager.h"
|
---|
44 | #include "OgreOverlayElementFactory.h"
|
---|
45 | #include "OgreOverlayManager.h"
|
---|
46 | #include "OgreProfiler.h"
|
---|
47 | #include "OgreErrorDialog.h"
|
---|
48 | #include "OgreConfigDialog.h"
|
---|
49 | #include "OgreStringConverter.h"
|
---|
50 | #include "OgrePlatformManager.h"
|
---|
51 | #include "OgreArchiveManager.h"
|
---|
52 | #include "OgreZip.h"
|
---|
53 | #include "OgreFileSystem.h"
|
---|
54 | #include "OgreShadowVolumeExtrudeProgram.h"
|
---|
55 | #include "OgreResourceBackgroundQueue.h"
|
---|
56 |
|
---|
57 | #if OGRE_NO_DEVIL == 0
|
---|
58 | #include "OgreILCodecs.h"
|
---|
59 | #endif
|
---|
60 |
|
---|
61 | #include "OgreFontManager.h"
|
---|
62 | #include "OgreHardwareBufferManager.h"
|
---|
63 |
|
---|
64 | #include "OgreOverlay.h"
|
---|
65 | #include "OgreHighLevelGpuProgramManager.h"
|
---|
66 |
|
---|
67 | #include "OgreExternalTextureSourceManager.h"
|
---|
68 |
|
---|
69 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
---|
70 |
|
---|
71 | # define WIN32_LEAN_AND_MEAN
|
---|
72 | # include <direct.h>
|
---|
73 | # include <windows.h>
|
---|
74 |
|
---|
75 | #endif
|
---|
76 |
|
---|
77 |
|
---|
78 | namespace Ogre {
|
---|
79 | //-----------------------------------------------------------------------
|
---|
80 | template<> Root* Singleton<Root>::ms_Singleton = 0;
|
---|
81 | Root* Root::getSingletonPtr(void)
|
---|
82 | {
|
---|
83 | return ms_Singleton;
|
---|
84 | }
|
---|
85 | Root& Root::getSingleton(void)
|
---|
86 | {
|
---|
87 | assert( ms_Singleton ); return ( *ms_Singleton );
|
---|
88 | }
|
---|
89 |
|
---|
90 | typedef void (*DLL_START_PLUGIN)(void);
|
---|
91 | typedef void (*DLL_STOP_PLUGIN)(void);
|
---|
92 |
|
---|
93 |
|
---|
94 | //-----------------------------------------------------------------------
|
---|
95 | // Termination handler
|
---|
96 | extern "C" _OgreExport void handleTerminate(void)
|
---|
97 | {
|
---|
98 | LogManager::getSingleton().logMessage("Termination handler: uncaught exception!", LML_CRITICAL);
|
---|
99 |
|
---|
100 | Root::getSingleton().shutdown();
|
---|
101 |
|
---|
102 | ErrorDialog* dlg = PlatformManager::getSingleton().createErrorDialog();
|
---|
103 |
|
---|
104 | Exception* e = Exception::getLastException();
|
---|
105 |
|
---|
106 | if (e)
|
---|
107 | dlg->display(e->getFullDescription());
|
---|
108 | else
|
---|
109 | dlg->display("Unknown");
|
---|
110 |
|
---|
111 | // Abort
|
---|
112 | exit(-1);
|
---|
113 |
|
---|
114 | }
|
---|
115 |
|
---|
116 | void Root::termHandler()
|
---|
117 | {
|
---|
118 | handleTerminate();
|
---|
119 | }
|
---|
120 |
|
---|
121 |
|
---|
122 | //-----------------------------------------------------------------------
|
---|
123 | Root::Root(const String& pluginFileName, const String& configFileName, const String& logFileName)
|
---|
124 | : mLogManager(0), mCurrentFrame(0)
|
---|
125 | {
|
---|
126 | // First create new exception handler
|
---|
127 | SET_TERM_HANDLER;
|
---|
128 |
|
---|
129 | // superclass will do singleton checking
|
---|
130 | String msg;
|
---|
131 |
|
---|
132 | // Init
|
---|
133 | mActiveRenderer = 0;
|
---|
134 | mVersion = StringConverter::toString(OGRE_VERSION_MAJOR) + "." +
|
---|
135 | StringConverter::toString(OGRE_VERSION_MINOR) + "." +
|
---|
136 | StringConverter::toString(OGRE_VERSION_PATCH) + " " +
|
---|
137 | "(" + OGRE_VERSION_NAME + ")";
|
---|
138 | mConfigFileName = configFileName;
|
---|
139 |
|
---|
140 | // Create log manager and default log file if there is no log manager yet
|
---|
141 | if(LogManager::getSingletonPtr() == 0)
|
---|
142 | {
|
---|
143 | mLogManager = new LogManager();
|
---|
144 | mLogManager->createLog(logFileName, true, true);
|
---|
145 | }
|
---|
146 |
|
---|
147 | // Dynamic library manager
|
---|
148 | mDynLibManager = new DynLibManager();
|
---|
149 |
|
---|
150 | mArchiveManager = new ArchiveManager();
|
---|
151 |
|
---|
152 | // ResourceGroupManager
|
---|
153 | mResourceGroupManager = new ResourceGroupManager();
|
---|
154 |
|
---|
155 | // ResourceBackgroundQueue
|
---|
156 | mResourceBackgroundQueue = new ResourceBackgroundQueue();
|
---|
157 |
|
---|
158 | // Create SceneManager enumerator (note - will be managed by singleton)
|
---|
159 | mSceneManagerEnum = new SceneManagerEnumerator();
|
---|
160 | mCurrentSceneManager = NULL;
|
---|
161 |
|
---|
162 | // ..material manager
|
---|
163 | mMaterialManager = new MaterialManager();
|
---|
164 |
|
---|
165 | // Mesh manager
|
---|
166 | mMeshManager = new MeshManager();
|
---|
167 |
|
---|
168 | // Skeleton manager
|
---|
169 | mSkeletonManager = new SkeletonManager();
|
---|
170 |
|
---|
171 | // ..particle system manager
|
---|
172 | mParticleManager = new ParticleSystemManager();
|
---|
173 |
|
---|
174 | // Platform manager
|
---|
175 | mPlatformManager = new PlatformManager();
|
---|
176 |
|
---|
177 | // Timer
|
---|
178 | mTimer = mPlatformManager->createTimer();
|
---|
179 |
|
---|
180 | // Overlay manager
|
---|
181 | mOverlayManager = new OverlayManager();
|
---|
182 |
|
---|
183 | mPanelFactory = new PanelOverlayElementFactory();
|
---|
184 | mOverlayManager->addOverlayElementFactory(mPanelFactory);
|
---|
185 |
|
---|
186 | mBorderPanelFactory = new BorderPanelOverlayElementFactory();
|
---|
187 | mOverlayManager->addOverlayElementFactory(mBorderPanelFactory);
|
---|
188 |
|
---|
189 | mTextAreaFactory = new TextAreaOverlayElementFactory();
|
---|
190 | mOverlayManager->addOverlayElementFactory(mTextAreaFactory);
|
---|
191 | // Font manager
|
---|
192 | mFontManager = new FontManager();
|
---|
193 |
|
---|
194 | #if OGRE_PROFILING
|
---|
195 | // Profiler
|
---|
196 | mProfiler = new Profiler();
|
---|
197 | Profiler::getSingleton().setTimer(mTimer);
|
---|
198 | #endif
|
---|
199 | mFileSystemArchiveFactory = new FileSystemArchiveFactory();
|
---|
200 | ArchiveManager::getSingleton().addArchiveFactory( mFileSystemArchiveFactory );
|
---|
201 | mZipArchiveFactory = new ZipArchiveFactory();
|
---|
202 | ArchiveManager::getSingleton().addArchiveFactory( mZipArchiveFactory );
|
---|
203 | #if OGRE_NO_DEVIL == 0
|
---|
204 | // Register image codecs
|
---|
205 | ILCodecs::registerCodecs();
|
---|
206 | #endif
|
---|
207 |
|
---|
208 | mHighLevelGpuProgramManager = new HighLevelGpuProgramManager();
|
---|
209 |
|
---|
210 | mExternalTextureSourceManager = new ExternalTextureSourceManager();
|
---|
211 |
|
---|
212 | // Auto window
|
---|
213 | mAutoWindow = 0;
|
---|
214 |
|
---|
215 | // Load plugins
|
---|
216 | if (!pluginFileName.empty())
|
---|
217 | loadPlugins(pluginFileName);
|
---|
218 |
|
---|
219 | LogManager::getSingleton().logMessage("*-*-* OGRE Initialising");
|
---|
220 | msg = "*-*-* Version " + mVersion;
|
---|
221 | LogManager::getSingleton().logMessage(msg);
|
---|
222 |
|
---|
223 | // Can't create managers until initialised
|
---|
224 | mControllerManager = 0;
|
---|
225 |
|
---|
226 | mFirstTimePostWindowInit = false;
|
---|
227 |
|
---|
228 | }
|
---|
229 |
|
---|
230 | //-----------------------------------------------------------------------
|
---|
231 | Root::~Root()
|
---|
232 | {
|
---|
233 | shutdownPlugins();
|
---|
234 | shutdown();
|
---|
235 | delete mSceneManagerEnum;
|
---|
236 |
|
---|
237 | delete mExternalTextureSourceManager;
|
---|
238 | #if OGRE_NO_DEVIL == 0
|
---|
239 | ILCodecs::deleteCodecs();
|
---|
240 | #endif
|
---|
241 | #if OGRE_PROFILING
|
---|
242 | delete mProfiler;
|
---|
243 | #endif
|
---|
244 | delete mOverlayManager;
|
---|
245 | delete mFontManager;
|
---|
246 | delete mArchiveManager;
|
---|
247 | delete mZipArchiveFactory;
|
---|
248 | delete mFileSystemArchiveFactory;
|
---|
249 | delete mSkeletonManager;
|
---|
250 | delete mMeshManager;
|
---|
251 | delete mParticleManager;
|
---|
252 |
|
---|
253 | if( mControllerManager )
|
---|
254 | delete mControllerManager;
|
---|
255 | if (mHighLevelGpuProgramManager)
|
---|
256 | delete mHighLevelGpuProgramManager;
|
---|
257 |
|
---|
258 | delete mTextAreaFactory;
|
---|
259 | delete mBorderPanelFactory;
|
---|
260 | delete mPanelFactory;
|
---|
261 |
|
---|
262 | unloadPlugins();
|
---|
263 | delete mMaterialManager;
|
---|
264 | Pass::processPendingPassUpdates(); // make sure passes are cleaned
|
---|
265 | delete mResourceBackgroundQueue;
|
---|
266 | delete mResourceGroupManager;
|
---|
267 |
|
---|
268 |
|
---|
269 |
|
---|
270 | mPlatformManager->destroyTimer(mTimer);
|
---|
271 | delete mPlatformManager;
|
---|
272 | delete mDynLibManager;
|
---|
273 | delete mLogManager;
|
---|
274 |
|
---|
275 |
|
---|
276 | StringInterface::cleanupDictionary ();
|
---|
277 | }
|
---|
278 |
|
---|
279 | //-----------------------------------------------------------------------
|
---|
280 | void Root::saveConfig(void)
|
---|
281 | {
|
---|
282 | std::ofstream of(mConfigFileName.c_str());
|
---|
283 |
|
---|
284 | if (!of)
|
---|
285 | OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, "Cannot create settings file.",
|
---|
286 | "Root::saveConfig");
|
---|
287 |
|
---|
288 | if (mActiveRenderer)
|
---|
289 | {
|
---|
290 | of << "Render System\t" << mActiveRenderer->getName() << std::endl;;
|
---|
291 |
|
---|
292 | ConfigOptionMap& opts = mActiveRenderer->getConfigOptions();
|
---|
293 | for( ConfigOptionMap::iterator pOpt = opts.begin(); pOpt != opts.end(); ++pOpt )
|
---|
294 | {
|
---|
295 | of << pOpt->first << "\t" << pOpt->second.currentValue << std::endl;;
|
---|
296 | }
|
---|
297 | }
|
---|
298 | else
|
---|
299 | {
|
---|
300 | of << "Render System\t ";
|
---|
301 | }
|
---|
302 |
|
---|
303 | of.close();
|
---|
304 |
|
---|
305 | }
|
---|
306 | //-----------------------------------------------------------------------
|
---|
307 | bool Root::restoreConfig(void)
|
---|
308 | {
|
---|
309 | // Restores configuration from saved state
|
---|
310 | // Returns true if a valid saved configuration is
|
---|
311 | // available, and false if no saved config is
|
---|
312 | // stored, or if there has been a problem
|
---|
313 | ConfigFile cfg;
|
---|
314 | String renderSystem;
|
---|
315 | RenderSystemList::iterator pRend;
|
---|
316 |
|
---|
317 | try {
|
---|
318 | // Don't trim whitespace
|
---|
319 | cfg.load(mConfigFileName, "\t:=", false);
|
---|
320 | }
|
---|
321 | catch (Exception& e)
|
---|
322 | {
|
---|
323 | if (e.getNumber() == Exception::ERR_FILE_NOT_FOUND)
|
---|
324 | {
|
---|
325 | return false;
|
---|
326 | }
|
---|
327 | else
|
---|
328 | {
|
---|
329 | throw;
|
---|
330 | }
|
---|
331 | }
|
---|
332 |
|
---|
333 | renderSystem = cfg.getSetting("Render System");
|
---|
334 | if(renderSystem.empty())
|
---|
335 | {
|
---|
336 | // No render system entry - error
|
---|
337 | return false;
|
---|
338 | }
|
---|
339 |
|
---|
340 | pRend = getAvailableRenderers()->begin();
|
---|
341 | while (pRend != getAvailableRenderers()->end())
|
---|
342 | {
|
---|
343 | String rName = (*pRend)->getName();
|
---|
344 | if (rName == renderSystem)
|
---|
345 | break;
|
---|
346 | pRend++;
|
---|
347 | }
|
---|
348 |
|
---|
349 | if (pRend == getAvailableRenderers()->end())
|
---|
350 | {
|
---|
351 | // Unrecognised render system
|
---|
352 | return false;
|
---|
353 | }
|
---|
354 |
|
---|
355 | setRenderSystem(*pRend);
|
---|
356 |
|
---|
357 | ConfigFile::SettingsIterator i = cfg.getSettingsIterator();
|
---|
358 |
|
---|
359 | String optName, optVal;
|
---|
360 | while (i.hasMoreElements())
|
---|
361 | {
|
---|
362 | optName = i.peekNextKey();
|
---|
363 | optVal = i.getNext();
|
---|
364 | if(optName != "Render System")
|
---|
365 | {
|
---|
366 | mActiveRenderer->setConfigOption(optName, optVal);
|
---|
367 | }
|
---|
368 | }
|
---|
369 |
|
---|
370 | // Successful load
|
---|
371 | return true;
|
---|
372 |
|
---|
373 | }
|
---|
374 |
|
---|
375 | //-----------------------------------------------------------------------
|
---|
376 | bool Root::showConfigDialog(void)
|
---|
377 | {
|
---|
378 | // Displays the standard config dialog
|
---|
379 | // Will use stored defaults if available
|
---|
380 | ConfigDialog* dlg;
|
---|
381 | bool isOk;
|
---|
382 |
|
---|
383 | dlg = mPlatformManager->createConfigDialog();
|
---|
384 |
|
---|
385 | isOk = dlg->display();
|
---|
386 |
|
---|
387 | mPlatformManager->destroyConfigDialog(dlg);
|
---|
388 |
|
---|
389 | return isOk;
|
---|
390 |
|
---|
391 | }
|
---|
392 |
|
---|
393 | //-----------------------------------------------------------------------
|
---|
394 | RenderSystemList* Root::getAvailableRenderers(void)
|
---|
395 | {
|
---|
396 | // Returns a vector of renders
|
---|
397 |
|
---|
398 | return &mRenderers;
|
---|
399 |
|
---|
400 | }
|
---|
401 |
|
---|
402 | //-----------------------------------------------------------------------
|
---|
403 | void Root::setRenderSystem(RenderSystem* system)
|
---|
404 | {
|
---|
405 | // Sets the active rendering system
|
---|
406 | // Can be called direct or will be called by
|
---|
407 | // standard config dialog
|
---|
408 |
|
---|
409 | // Is there already an active renderer?
|
---|
410 | // If so, disable it and init the new one
|
---|
411 | if( mActiveRenderer && mActiveRenderer != system )
|
---|
412 | {
|
---|
413 | mActiveRenderer->shutdown();
|
---|
414 | }
|
---|
415 |
|
---|
416 | mActiveRenderer = system;
|
---|
417 | // Tell scene managers
|
---|
418 | SceneManagerEnumerator::getSingleton().setRenderSystem(system);
|
---|
419 |
|
---|
420 | }
|
---|
421 | //-----------------------------------------------------------------------
|
---|
422 | void Root::addRenderSystem(RenderSystem *newRend)
|
---|
423 | {
|
---|
424 | mRenderers.push_back(newRend);
|
---|
425 | }
|
---|
426 | //-----------------------------------------------------------------------
|
---|
427 | void Root::setSceneManager(SceneType sType, SceneManager *sm)
|
---|
428 | {
|
---|
429 | SceneManagerEnumerator::getSingleton().setSceneManager(sType, sm);
|
---|
430 | }
|
---|
431 |
|
---|
432 | //-----------------------------------------------------------------------
|
---|
433 | RenderSystem* Root::getRenderSystem(void)
|
---|
434 | {
|
---|
435 | // Gets the currently active renderer
|
---|
436 | return mActiveRenderer;
|
---|
437 |
|
---|
438 | }
|
---|
439 |
|
---|
440 | //-----------------------------------------------------------------------
|
---|
441 | RenderWindow* Root::initialise(bool autoCreateWindow, const String& windowTitle)
|
---|
442 | {
|
---|
443 | if (!mActiveRenderer)
|
---|
444 | OGRE_EXCEPT(Exception::ERR_NO_RENDERSYSTEM_SELECTED,
|
---|
445 | "Cannot initialise - no render "
|
---|
446 | "system has been selected.", "Root::initialise");
|
---|
447 |
|
---|
448 | mControllerManager = new ControllerManager();
|
---|
449 |
|
---|
450 | mAutoWindow = mActiveRenderer->initialise(autoCreateWindow, windowTitle);
|
---|
451 |
|
---|
452 | mResourceBackgroundQueue->initialise();
|
---|
453 |
|
---|
454 | if (autoCreateWindow && !mFirstTimePostWindowInit)
|
---|
455 | {
|
---|
456 | oneTimePostWindowInit();
|
---|
457 | mAutoWindow->_setPrimary();
|
---|
458 | }
|
---|
459 |
|
---|
460 | // Initialise timer
|
---|
461 | mTimer->reset();
|
---|
462 | return mAutoWindow;
|
---|
463 |
|
---|
464 | }
|
---|
465 | //-----------------------------------------------------------------------
|
---|
466 | String Root::getErrorDescription(long errorNumber)
|
---|
467 | {
|
---|
468 |
|
---|
469 | // Pass to render system
|
---|
470 | if (mActiveRenderer)
|
---|
471 | return mActiveRenderer->getErrorDescription(errorNumber);
|
---|
472 | else
|
---|
473 | return "";
|
---|
474 |
|
---|
475 | }
|
---|
476 | //-----------------------------------------------------------------------
|
---|
477 | SceneManager* Root::getSceneManager(SceneType sceneType)
|
---|
478 | {
|
---|
479 | // Delegate
|
---|
480 | return mSceneManagerEnum->getSceneManager(sceneType);
|
---|
481 | }
|
---|
482 | //-----------------------------------------------------------------------
|
---|
483 | TextureManager* Root::getTextureManager(void)
|
---|
484 | {
|
---|
485 | return &TextureManager::getSingleton();
|
---|
486 | }
|
---|
487 | //-----------------------------------------------------------------------
|
---|
488 | MeshManager* Root::getMeshManager(void)
|
---|
489 | {
|
---|
490 | return &MeshManager::getSingleton();
|
---|
491 | }
|
---|
492 | //-----------------------------------------------------------------------
|
---|
493 | void Root::addFrameListener(FrameListener* newListener)
|
---|
494 | {
|
---|
495 | // Insert, unique only (set)
|
---|
496 | mFrameListeners.insert(newListener);
|
---|
497 |
|
---|
498 | }
|
---|
499 |
|
---|
500 | //-----------------------------------------------------------------------
|
---|
501 | void Root::removeFrameListener(FrameListener* oldListener)
|
---|
502 | {
|
---|
503 | // Remove, 1 only (set)
|
---|
504 | mRemovedFrameListeners.insert(oldListener);
|
---|
505 | }
|
---|
506 | //-----------------------------------------------------------------------
|
---|
507 | bool Root::_fireFrameStarted(FrameEvent& evt)
|
---|
508 | {
|
---|
509 | // Increment frame number
|
---|
510 | ++mCurrentFrame;
|
---|
511 |
|
---|
512 | // Remove all marked listeners
|
---|
513 | std::set<FrameListener*>::iterator i;
|
---|
514 | for (i = mRemovedFrameListeners.begin();
|
---|
515 | i != mRemovedFrameListeners.end(); i++)
|
---|
516 | {
|
---|
517 | mFrameListeners.erase(*i);
|
---|
518 | }
|
---|
519 | mRemovedFrameListeners.clear();
|
---|
520 |
|
---|
521 | // Tell all listeners
|
---|
522 | for (i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i)
|
---|
523 | {
|
---|
524 | if (!(*i)->frameStarted(evt))
|
---|
525 | return false;
|
---|
526 | }
|
---|
527 |
|
---|
528 | return true;
|
---|
529 |
|
---|
530 | }
|
---|
531 | //-----------------------------------------------------------------------
|
---|
532 | bool Root::_fireFrameEnded(FrameEvent& evt)
|
---|
533 | {
|
---|
534 | // Remove all marked listeners
|
---|
535 | std::set<FrameListener*>::iterator i;
|
---|
536 | for (i = mRemovedFrameListeners.begin();
|
---|
537 | i != mRemovedFrameListeners.end(); i++)
|
---|
538 | {
|
---|
539 | mFrameListeners.erase(*i);
|
---|
540 | }
|
---|
541 | mRemovedFrameListeners.clear();
|
---|
542 |
|
---|
543 | // Tell all listeners
|
---|
544 | bool ret = true;
|
---|
545 | for (i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i)
|
---|
546 | {
|
---|
547 | if (!(*i)->frameEnded(evt))
|
---|
548 | {
|
---|
549 | ret = false;
|
---|
550 | break;
|
---|
551 | }
|
---|
552 | }
|
---|
553 |
|
---|
554 | // Tell buffer manager to free temp buffers used this frame
|
---|
555 | if (HardwareBufferManager::getSingletonPtr())
|
---|
556 | HardwareBufferManager::getSingleton()._releaseBufferCopies();
|
---|
557 |
|
---|
558 | return ret;
|
---|
559 | }
|
---|
560 | //-----------------------------------------------------------------------
|
---|
561 | bool Root::_fireFrameStarted()
|
---|
562 | {
|
---|
563 | unsigned long now = mTimer->getMilliseconds();
|
---|
564 | FrameEvent evt;
|
---|
565 | evt.timeSinceLastEvent = calculateEventTime(now, FETT_ANY);
|
---|
566 | evt.timeSinceLastFrame = calculateEventTime(now, FETT_STARTED);
|
---|
567 |
|
---|
568 | return _fireFrameStarted(evt);
|
---|
569 | }
|
---|
570 | //-----------------------------------------------------------------------
|
---|
571 | bool Root::_fireFrameEnded()
|
---|
572 | {
|
---|
573 | unsigned long now = mTimer->getMilliseconds();
|
---|
574 | FrameEvent evt;
|
---|
575 | evt.timeSinceLastEvent = calculateEventTime(now, FETT_ANY);
|
---|
576 | evt.timeSinceLastFrame = calculateEventTime(now, FETT_ENDED);
|
---|
577 |
|
---|
578 | return _fireFrameEnded(evt);
|
---|
579 | }
|
---|
580 | //-----------------------------------------------------------------------
|
---|
581 | Real Root::calculateEventTime(unsigned long now, FrameEventTimeType type)
|
---|
582 | {
|
---|
583 | // Calculate the average time passed between events of the given type
|
---|
584 | // during the last 0.5 seconds.
|
---|
585 |
|
---|
586 | std::deque<unsigned long>& times = mEventTimes[type];
|
---|
587 | times.push_back(now);
|
---|
588 |
|
---|
589 | if(times.size() == 1)
|
---|
590 | return 0;
|
---|
591 |
|
---|
592 | // Times up to 0.5 seconds old should be kept
|
---|
593 | unsigned long discardThreshold = 500;
|
---|
594 |
|
---|
595 | // Find the oldest time to keep
|
---|
596 | std::deque<unsigned long>::iterator it = times.begin(),
|
---|
597 | end = times.end()-2; // We need at least two times
|
---|
598 | while(it != end)
|
---|
599 | {
|
---|
600 | if (now - *it > discardThreshold)
|
---|
601 | ++it;
|
---|
602 | else
|
---|
603 | break;
|
---|
604 | }
|
---|
605 |
|
---|
606 | // Remove old times
|
---|
607 | times.erase(times.begin(), it);
|
---|
608 |
|
---|
609 | return Real(times.back() - times.front()) / ((times.size()-1) * 1000);
|
---|
610 | }
|
---|
611 | //-----------------------------------------------------------------------
|
---|
612 | void Root::queueEndRendering(void)
|
---|
613 | {
|
---|
614 | mQueuedEnd = true;
|
---|
615 | }
|
---|
616 | //-----------------------------------------------------------------------
|
---|
617 | void Root::startRendering(void)
|
---|
618 | {
|
---|
619 | assert(mActiveRenderer != 0);
|
---|
620 |
|
---|
621 | mActiveRenderer->_initRenderTargets();
|
---|
622 |
|
---|
623 | // Clear event times
|
---|
624 | for(int i=0; i!=3; ++i)
|
---|
625 | mEventTimes[i].clear();
|
---|
626 |
|
---|
627 | // Infinite loop, until broken out of by frame listeners
|
---|
628 | // or break out by calling queueEndRendering()
|
---|
629 | mQueuedEnd = false;
|
---|
630 | while( !mQueuedEnd )
|
---|
631 | {
|
---|
632 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
---|
633 | // Pump events on Win32
|
---|
634 | MSG msg;
|
---|
635 | while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
|
---|
636 | {
|
---|
637 | TranslateMessage( &msg );
|
---|
638 | DispatchMessage( &msg );
|
---|
639 | }
|
---|
640 | #endif
|
---|
641 |
|
---|
642 | if (!renderOneFrame())
|
---|
643 | break;
|
---|
644 | }
|
---|
645 |
|
---|
646 |
|
---|
647 | }
|
---|
648 | //-----------------------------------------------------------------------
|
---|
649 | bool Root::renderOneFrame(void)
|
---|
650 | {
|
---|
651 | if(!_fireFrameStarted())
|
---|
652 | return false;
|
---|
653 |
|
---|
654 | _updateAllRenderTargets();
|
---|
655 |
|
---|
656 | return _fireFrameEnded();
|
---|
657 | }
|
---|
658 | //-----------------------------------------------------------------------
|
---|
659 | void Root::shutdown(void)
|
---|
660 | {
|
---|
661 | SceneManagerEnumerator::getSingleton().shutdownAll();
|
---|
662 | ShadowVolumeExtrudeProgram::shutdown();
|
---|
663 | mResourceBackgroundQueue->shutdown();
|
---|
664 | ResourceGroupManager::getSingleton().shutdownAll();
|
---|
665 |
|
---|
666 | LogManager::getSingleton().logMessage("*-*-* OGRE Shutdown");
|
---|
667 | }
|
---|
668 | //-----------------------------------------------------------------------
|
---|
669 | void Root::loadPlugins( const String& pluginsfile )
|
---|
670 | {
|
---|
671 | StringVector pluginList;
|
---|
672 | String pluginDir;
|
---|
673 | ConfigFile cfg;
|
---|
674 |
|
---|
675 | try {
|
---|
676 | cfg.load( pluginsfile );
|
---|
677 | }
|
---|
678 | catch (Exception)
|
---|
679 | {
|
---|
680 | LogManager::getSingleton().logMessage(pluginsfile + " not found, automatic plugin loading disabled.");
|
---|
681 | return;
|
---|
682 | }
|
---|
683 |
|
---|
684 | pluginDir = cfg.getSetting("PluginFolder"); // Ignored on Mac OS X, uses Resources/ directory
|
---|
685 | pluginList = cfg.getMultiSetting("Plugin");
|
---|
686 |
|
---|
687 | char last_char = pluginDir[pluginDir.length()-1];
|
---|
688 | if (last_char != '/' && last_char != '\\')
|
---|
689 | {
|
---|
690 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
---|
691 | pluginDir += "\\";
|
---|
692 | #elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
|
---|
693 | pluginDir += "/";
|
---|
694 | #endif
|
---|
695 | }
|
---|
696 |
|
---|
697 | for( StringVector::iterator it = pluginList.begin(); it != pluginList.end(); ++it )
|
---|
698 | {
|
---|
699 | loadPlugin(pluginDir + (*it));
|
---|
700 | }
|
---|
701 |
|
---|
702 | }
|
---|
703 | //-----------------------------------------------------------------------
|
---|
704 | void Root::shutdownPlugins(void)
|
---|
705 | {
|
---|
706 | std::vector<DynLib*>::reverse_iterator i;
|
---|
707 |
|
---|
708 | // NB Shutdown plugins in reverse order to enforce dependencies
|
---|
709 | for (i = mPluginLibs.rbegin(); i != mPluginLibs.rend(); ++i)
|
---|
710 | {
|
---|
711 | // Call plugin shutdown (optional)
|
---|
712 | DLL_STOP_PLUGIN pFunc = (DLL_STOP_PLUGIN)(*i)->getSymbol("dllShutdownPlugin");
|
---|
713 | if (pFunc)
|
---|
714 | {
|
---|
715 | pFunc();
|
---|
716 | }
|
---|
717 |
|
---|
718 | }
|
---|
719 | }
|
---|
720 | //-----------------------------------------------------------------------
|
---|
721 | void Root::unloadPlugins(void)
|
---|
722 | {
|
---|
723 | std::vector<DynLib*>::reverse_iterator i;
|
---|
724 |
|
---|
725 | // NB Unload plugins in reverse order to enforce dependencies
|
---|
726 | for (i = mPluginLibs.rbegin(); i != mPluginLibs.rend(); ++i)
|
---|
727 | {
|
---|
728 | // Call plugin shutdown
|
---|
729 | DLL_STOP_PLUGIN pFunc = (DLL_STOP_PLUGIN)(*i)->getSymbol("dllStopPlugin");
|
---|
730 | pFunc();
|
---|
731 | // Unload library & destroy
|
---|
732 | DynLibManager::getSingleton().unload(*i);
|
---|
733 |
|
---|
734 | }
|
---|
735 |
|
---|
736 | mPluginLibs.clear();
|
---|
737 |
|
---|
738 | }
|
---|
739 | //-----------------------------------------------------------------------
|
---|
740 | void Root::addResourceLocation(const String& name, const String& locType,
|
---|
741 | const String& groupName, bool recursive)
|
---|
742 | {
|
---|
743 | ResourceGroupManager::getSingleton().addResourceLocation(
|
---|
744 | name, locType, groupName, recursive);
|
---|
745 | }
|
---|
746 | //-----------------------------------------------------------------------
|
---|
747 | void Root::removeResourceLocation(const String& name, const String& groupName)
|
---|
748 | {
|
---|
749 | ResourceGroupManager::getSingleton().removeResourceLocation(
|
---|
750 | name, groupName);
|
---|
751 | }
|
---|
752 | //-----------------------------------------------------------------------
|
---|
753 | void Root::convertColourValue(const ColourValue& colour, uint32* pDest)
|
---|
754 | {
|
---|
755 | assert(mActiveRenderer != 0);
|
---|
756 | mActiveRenderer->convertColourValue(colour, pDest);
|
---|
757 | }
|
---|
758 | //-----------------------------------------------------------------------
|
---|
759 | RenderWindow* Root::getAutoCreatedWindow(void)
|
---|
760 | {
|
---|
761 | return mAutoWindow;
|
---|
762 | }
|
---|
763 | //-----------------------------------------------------------------------
|
---|
764 | RenderWindow* Root::createRenderWindow(const String &name, unsigned int width, unsigned int height,
|
---|
765 | bool fullScreen, const NameValuePairList *miscParams)
|
---|
766 | {
|
---|
767 | if (!mActiveRenderer)
|
---|
768 | {
|
---|
769 | OGRE_EXCEPT(Exception::ERR_NO_RENDERSYSTEM_SELECTED,
|
---|
770 | "Cannot create window - no render "
|
---|
771 | "system has been selected.", "Root::createRenderWindow");
|
---|
772 | }
|
---|
773 | RenderWindow* ret;
|
---|
774 | ret = mActiveRenderer->createRenderWindow(name, width, height, fullScreen, miscParams);
|
---|
775 |
|
---|
776 | // Initialisation for classes dependent on first window created
|
---|
777 | if(!mFirstTimePostWindowInit)
|
---|
778 | {
|
---|
779 | oneTimePostWindowInit();
|
---|
780 | ret->_setPrimary();
|
---|
781 | }
|
---|
782 |
|
---|
783 | return ret;
|
---|
784 |
|
---|
785 | }
|
---|
786 | //-----------------------------------------------------------------------
|
---|
787 | void Root::detachRenderTarget(RenderTarget* target)
|
---|
788 | {
|
---|
789 | if (!mActiveRenderer)
|
---|
790 | {
|
---|
791 | OGRE_EXCEPT(Exception::ERR_NO_RENDERSYSTEM_SELECTED,
|
---|
792 | "Cannot create window - no render "
|
---|
793 | "system has been selected.", "Root::destroyRenderWindow");
|
---|
794 | }
|
---|
795 |
|
---|
796 | mActiveRenderer->detachRenderTarget( target->getName() );
|
---|
797 | }
|
---|
798 | //-----------------------------------------------------------------------
|
---|
799 | void Root::detachRenderTarget(const String &name)
|
---|
800 | {
|
---|
801 | if (!mActiveRenderer)
|
---|
802 | {
|
---|
803 | OGRE_EXCEPT(Exception::ERR_NO_RENDERSYSTEM_SELECTED,
|
---|
804 | "Cannot create window - no render "
|
---|
805 | "system has been selected.", "Root::destroyRenderWindow");
|
---|
806 | }
|
---|
807 |
|
---|
808 | mActiveRenderer->detachRenderTarget( name );
|
---|
809 | }
|
---|
810 | //-----------------------------------------------------------------------
|
---|
811 | RenderTarget* Root::getRenderTarget(const String &name)
|
---|
812 | {
|
---|
813 | if (!mActiveRenderer)
|
---|
814 | {
|
---|
815 | OGRE_EXCEPT(Exception::ERR_NO_RENDERSYSTEM_SELECTED,
|
---|
816 | "Cannot create window - no render "
|
---|
817 | "system has been selected.", "Root::getRenderWindow");
|
---|
818 | }
|
---|
819 |
|
---|
820 | return mActiveRenderer->getRenderTarget(name);
|
---|
821 | }
|
---|
822 | //-----------------------------------------------------------------------
|
---|
823 | void Root::loadPlugin(const String& pluginName)
|
---|
824 | {
|
---|
825 | // Load plugin library
|
---|
826 | DynLib* lib = DynLibManager::getSingleton().load( pluginName );
|
---|
827 | // Store for later unload
|
---|
828 | mPluginLibs.push_back(lib);
|
---|
829 |
|
---|
830 | // Call startup function
|
---|
831 | DLL_START_PLUGIN pFunc = (DLL_START_PLUGIN)lib->getSymbol("dllStartPlugin");
|
---|
832 |
|
---|
833 | if (!pFunc)
|
---|
834 | OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot find symbol dllStartPlugin in library " + pluginName,
|
---|
835 | "Root::loadPlugins");
|
---|
836 | pFunc();
|
---|
837 | }
|
---|
838 | //-----------------------------------------------------------------------
|
---|
839 | void Root::unloadPlugin(const String& pluginName)
|
---|
840 | {
|
---|
841 | std::vector<DynLib*>::iterator i;
|
---|
842 |
|
---|
843 | for (i = mPluginLibs.begin(); i != mPluginLibs.end(); ++i)
|
---|
844 | {
|
---|
845 | if ((*i)->getName() == pluginName)
|
---|
846 | {
|
---|
847 | // Call plugin shutdown
|
---|
848 | DLL_STOP_PLUGIN pFunc = (DLL_STOP_PLUGIN)(*i)->getSymbol("dllStopPlugin");
|
---|
849 | pFunc();
|
---|
850 | // Unload library (destroyed by DynLibManager)
|
---|
851 | DynLibManager::getSingleton().unload(*i);
|
---|
852 | mPluginLibs.erase(i);
|
---|
853 | return;
|
---|
854 | }
|
---|
855 |
|
---|
856 | }
|
---|
857 | }
|
---|
858 | //-----------------------------------------------------------------------
|
---|
859 | Timer* Root::getTimer(void)
|
---|
860 | {
|
---|
861 | return mTimer;
|
---|
862 | }
|
---|
863 | //-----------------------------------------------------------------------
|
---|
864 | void Root::oneTimePostWindowInit(void)
|
---|
865 | {
|
---|
866 | if (!mFirstTimePostWindowInit)
|
---|
867 | {
|
---|
868 | // Initialise material manager
|
---|
869 | mMaterialManager->initialise();
|
---|
870 | // Init particle systems manager
|
---|
871 | mParticleManager->_initialise();
|
---|
872 | // Init mesh manager
|
---|
873 | MeshManager::getSingleton()._initialise();
|
---|
874 | mFirstTimePostWindowInit = true;
|
---|
875 | }
|
---|
876 |
|
---|
877 | }
|
---|
878 | //-----------------------------------------------------------------------
|
---|
879 | void Root::_updateAllRenderTargets(void)
|
---|
880 | {
|
---|
881 | // delegate
|
---|
882 | mActiveRenderer->_updateAllRenderTargets();
|
---|
883 | }
|
---|
884 | //-----------------------------------------------------------------------
|
---|
885 | void Root::clearEventTimes(void)
|
---|
886 | {
|
---|
887 | // Clear event times
|
---|
888 | for(int i=0; i<3; ++i)
|
---|
889 | mEventTimes[i].clear();
|
---|
890 | }
|
---|
891 | }
|
---|