1 /* 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 6 7 Copyright (c) 2000-2014 Torus Knot Software Ltd 8 9 Permission is hereby granted, free of charge, to any person obtaining a copy 10 of this software and associated documentation files (the "Software"), to deal 11 in the Software without restriction, including without limitation the rights 12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 copies of the Software, and to permit persons to whom the Software is 14 furnished to do so, subject to the following conditions: 15 16 The above copyright notice and this permission notice shall be included in 17 all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 THE SOFTWARE. 26 ----------------------------------------------------------------------------- 27 */ 28 // Ogre includes 29 #include "OgreStableHeaders.h" 30 31 #include "OgreRenderWindow.h" 32 #include "OgreControllerManager.h" 33 #include "OgreDynLibManager.h" 34 #include "OgreDynLib.h" 35 #include "OgreConfigFile.h" 36 #include "OgreRenderSystemCapabilitiesManager.h" 37 #include "OgreSkeletonManager.h" 38 #include "OgreConfigDialog.h" 39 #include "OgrePlugin.h" 40 #include "OgreShadowVolumeExtrudeProgram.h" 41 #include "OgreResourceBackgroundQueue.h" 42 #include "OgreEntity.h" 43 #include "OgreBillboardSet.h" 44 #include "OgreBillboardChain.h" 45 #include "OgreRibbonTrail.h" 46 #include "OgreLight.h" 47 #include "OgreRenderQueueInvocation.h" 48 #include "OgreConvexBody.h" 49 #include "OgreTimer.h" 50 #include "OgreFrameListener.h" 51 #include "OgreLodStrategyManager.h" 52 #include "OgreFileSystemLayer.h" 53 #include "OgreSceneLoaderManager.h" 54 55 #if OGRE_NO_DDS_CODEC == 0 56 #include "OgreDDSCodec.h" 57 #endif 58 59 #include "OgreHardwareBufferManager.h" 60 #include "OgreHighLevelGpuProgramManager.h" 61 #include "OgreExternalTextureSourceManager.h" 62 #include "OgreCompositorManager.h" 63 64 #if OGRE_NO_PVRTC_CODEC == 0 65 # include "OgrePVRTCCodec.h" 66 #endif 67 #if OGRE_NO_ETC_CODEC == 0 68 # include "OgreETCCodec.h" 69 #endif 70 #if OGRE_NO_ASTC_CODEC == 0 71 # include "OgreASTCCodec.h" 72 #endif 73 74 #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS 75 #include "macUtils.h" 76 #endif 77 78 #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID 79 #include "Android/OgreAndroidLogListener.h" 80 #endif 81 82 namespace Ogre { 83 //----------------------------------------------------------------------- 84 template<> Root* Singleton<Root>::msSingleton = 0; getSingletonPtr(void)85 Root* Root::getSingletonPtr(void) 86 { 87 return msSingleton; 88 } getSingleton(void)89 Root& Root::getSingleton(void) 90 { 91 assert( msSingleton ); return ( *msSingleton ); 92 } 93 94 typedef void (*DLL_START_PLUGIN)(void); 95 typedef void (*DLL_STOP_PLUGIN)(void); 96 97 //----------------------------------------------------------------------- Root(const String & pluginFileName,const String & configFileName,const String & logFileName)98 Root::Root(const String& pluginFileName, const String& configFileName, 99 const String& logFileName) 100 : mQueuedEnd(false) 101 , mNextFrame(0) 102 , mFrameSmoothingTime(0.0f) 103 , mRemoveQueueStructuresOnClear(false) 104 , mDefaultMinPixelSize(0) 105 , mNextMovableObjectTypeFlag(1) 106 , mIsInitialised(false) 107 , mIsBlendIndicesGpuRedundant(true) 108 , mIsBlendWeightsGpuRedundant(true) 109 { 110 // superclass will do singleton checking 111 112 // Init 113 mActiveRenderer = 0; 114 mVersion = StringConverter::toString(OGRE_VERSION_MAJOR) + "." + 115 StringConverter::toString(OGRE_VERSION_MINOR) + "." + 116 StringConverter::toString(OGRE_VERSION_PATCH) + 117 OGRE_VERSION_SUFFIX + " " + 118 "(" + OGRE_VERSION_NAME + ")"; 119 mConfigFileName = configFileName; 120 121 // Create log manager and default log file if there is no log manager yet 122 if(!LogManager::getSingletonPtr()) 123 { 124 mLogManager.reset(new LogManager()); 125 126 #if OGRE_PLATFORM == OGRE_PLATFORM_EMSCRIPTEN 127 // suppress writing log to Emscripten virtual FS, improves performance 128 mLogManager->createLog(logFileName, true, true, true); 129 #else 130 mLogManager->createLog(logFileName, true, true); 131 #endif 132 } 133 134 #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID 135 mAndroidLogger.reset(new AndroidLogListener()); 136 mLogManager->getDefaultLog()->addListener(mAndroidLogger.get()); 137 #endif 138 139 mDynLibManager.reset(new DynLibManager()); 140 mArchiveManager.reset(new ArchiveManager()); 141 mResourceGroupManager.reset(new ResourceGroupManager()); 142 143 // WorkQueue (note: users can replace this if they want) 144 DefaultWorkQueue* defaultQ = OGRE_NEW DefaultWorkQueue("Root"); 145 // never process responses in main thread for longer than 10ms by default 146 defaultQ->setResponseProcessingTimeLimit(10); 147 // match threads to hardware 148 int threadCount = OGRE_THREAD_HARDWARE_CONCURRENCY; 149 // but clamp it at 2 by default - we dont scale much beyond that currently 150 // yet it helps on android where it needlessly burns CPU 151 threadCount = Math::Clamp(threadCount, 1, 2); 152 defaultQ->setWorkerThreadCount(threadCount); 153 154 // only allow workers to access rendersystem if threadsupport is 1 155 defaultQ->setWorkersCanAccessRenderSystem(OGRE_THREAD_SUPPORT == 1); 156 mWorkQueue.reset(defaultQ); 157 158 // ResourceBackgroundQueue 159 mResourceBackgroundQueue.reset(new ResourceBackgroundQueue()); 160 161 // Create SceneManager enumerator (note - will be managed by singleton) 162 mSceneManagerEnum.reset(new SceneManagerEnumerator()); 163 mShadowTextureManager.reset(new ShadowTextureManager()); 164 mRenderSystemCapabilitiesManager.reset(new RenderSystemCapabilitiesManager()); 165 mMaterialManager.reset(new MaterialManager()); 166 mMeshManager.reset(new MeshManager()); 167 mSkeletonManager.reset(new SkeletonManager()); 168 mParticleManager.reset(new ParticleSystemManager()); 169 mTimer.reset(new Timer()); 170 mLodStrategyManager.reset(new LodStrategyManager()); 171 172 #if OGRE_PROFILING 173 // Profiler 174 mProfiler.reset(new Profiler()); 175 Profiler::getSingleton().setTimer(mTimer.get()); 176 #endif 177 178 179 mFileSystemArchiveFactory.reset(new FileSystemArchiveFactory()); 180 ArchiveManager::getSingleton().addArchiveFactory( mFileSystemArchiveFactory.get() ); 181 # if OGRE_NO_ZIP_ARCHIVE == 0 182 mZipArchiveFactory.reset(new ZipArchiveFactory()); 183 ArchiveManager::getSingleton().addArchiveFactory( mZipArchiveFactory.get() ); 184 mEmbeddedZipArchiveFactory.reset(new EmbeddedZipArchiveFactory()); 185 ArchiveManager::getSingleton().addArchiveFactory( mEmbeddedZipArchiveFactory.get() ); 186 # endif 187 188 #if OGRE_NO_DDS_CODEC == 0 189 // Register image codecs 190 DDSCodec::startup(); 191 #endif 192 #if OGRE_NO_PVRTC_CODEC == 0 193 PVRTCCodec::startup(); 194 #endif 195 #if OGRE_NO_ETC_CODEC == 0 196 ETCCodec::startup(); 197 #endif 198 #if OGRE_NO_ASTC_CODEC == 0 199 ASTCCodec::startup(); 200 #endif 201 202 mHighLevelGpuProgramManager.reset(new HighLevelGpuProgramManager()); 203 mExternalTextureSourceManager.reset(new ExternalTextureSourceManager()); 204 mCompositorManager.reset(new CompositorManager()); 205 mCompilerManager.reset(new ScriptCompilerManager()); 206 mSceneLoaderManager.reset(new SceneLoaderManager()); 207 208 // Auto window 209 mAutoWindow = 0; 210 211 // instantiate and register base movable factories 212 mEntityFactory.reset(new EntityFactory()); 213 addMovableObjectFactory(mEntityFactory.get()); 214 mLightFactory.reset(new LightFactory()); 215 addMovableObjectFactory(mLightFactory.get()); 216 mBillboardSetFactory.reset(new BillboardSetFactory()); 217 addMovableObjectFactory(mBillboardSetFactory.get()); 218 mManualObjectFactory.reset(new ManualObjectFactory()); 219 addMovableObjectFactory(mManualObjectFactory.get()); 220 mBillboardChainFactory.reset(new BillboardChainFactory()); 221 addMovableObjectFactory(mBillboardChainFactory.get()); 222 mRibbonTrailFactory.reset(new RibbonTrailFactory()); 223 addMovableObjectFactory(mRibbonTrailFactory.get()); 224 225 // Load plugins 226 if (!pluginFileName.empty()) 227 loadPlugins(pluginFileName); 228 229 LogManager::getSingleton().logMessage("*-*-* OGRE Initialising"); 230 LogManager::getSingleton().logMessage("*-*-* Version " + mVersion); 231 232 // Can't create managers until initialised 233 mControllerManager = 0; 234 235 mFirstTimePostWindowInit = false; 236 } 237 238 //----------------------------------------------------------------------- ~Root()239 Root::~Root() 240 { 241 shutdown(); 242 243 destroyAllRenderQueueInvocationSequences(); 244 245 #if OGRE_NO_DDS_CODEC == 0 246 DDSCodec::shutdown(); 247 #endif 248 #if OGRE_NO_PVRTC_CODEC == 0 249 PVRTCCodec::shutdown(); 250 #endif 251 #if OGRE_NO_ETC_CODEC == 0 252 ETCCodec::shutdown(); 253 #endif 254 #if OGRE_NO_ASTC_CODEC == 0 255 ASTCCodec::shutdown(); 256 #endif 257 mCompositorManager.reset(); // needs rendersystem 258 mParticleManager.reset(); // may use plugins 259 unloadPlugins(); 260 261 mAutoWindow = 0; 262 263 StringInterface::cleanupDictionary(); 264 265 #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID 266 mLogManager->getDefaultLog()->removeListener(mAndroidLogger.get()); 267 #endif 268 } 269 270 //----------------------------------------------------------------------- saveConfig(void)271 void Root::saveConfig(void) 272 { 273 #if OGRE_PLATFORM == OGRE_PLATFORM_EMSCRIPTEN 274 OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, "saveConfig is not supported", 275 "Root::saveConfig"); 276 #endif 277 #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS 278 // Check the Documents directory within the application sandbox 279 Ogre::String outBaseName, extension, configFileName; 280 Ogre::StringUtil::splitFilename(mConfigFileName, outBaseName, extension); 281 configFileName = iOSDocumentsDirectory() + "/" + outBaseName; 282 std::ofstream of(configFileName.c_str()); 283 if (of.is_open()) 284 mConfigFileName = configFileName; 285 else 286 mConfigFileName.clear(); 287 #else 288 if (mConfigFileName.empty()) 289 return; 290 291 std::ofstream of(mConfigFileName.c_str()); 292 #endif 293 if (!of) 294 OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, "Cannot create settings file.", 295 "Root::saveConfig"); 296 297 if (mActiveRenderer) 298 { 299 of << "Render System=" << mActiveRenderer->getName() << std::endl; 300 } 301 else 302 { 303 of << "Render System=" << std::endl; 304 } 305 306 for (RenderSystemList::const_iterator pRend = getAvailableRenderers().begin(); pRend != getAvailableRenderers().end(); ++pRend) 307 { 308 RenderSystem* rs = *pRend; 309 of << std::endl; 310 of << "[" << rs->getName() << "]" << std::endl; 311 const ConfigOptionMap& opts = rs->getConfigOptions(); 312 for (ConfigOptionMap::const_iterator pOpt = opts.begin(); pOpt != opts.end(); ++pOpt) 313 { 314 of << pOpt->first << "=" << pOpt->second.currentValue << std::endl; 315 } 316 } 317 318 of.close(); 319 320 } 321 //----------------------------------------------------------------------- restoreConfig(void)322 bool Root::restoreConfig(void) 323 { 324 #if OGRE_PLATFORM == OGRE_PLATFORM_EMSCRIPTEN 325 OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, "restoreConfig is not supported", 326 "Root::restoreConfig"); 327 #endif 328 329 #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS 330 // Read the config from Documents first(user config) if it exists on iOS. 331 // If it doesn't exist or is invalid then use mConfigFileName 332 333 Ogre::String outBaseName, extension, configFileName; 334 Ogre::StringUtil::splitFilename(mConfigFileName, outBaseName, extension); 335 configFileName = iOSDocumentsDirectory() + "/" + outBaseName; 336 337 std::ifstream fp; 338 fp.open(configFileName.c_str(), std::ios::in); 339 if(fp.is_open()) 340 { 341 // A config file exists in the users Documents dir, we'll use it 342 mConfigFileName = configFileName; 343 } 344 else 345 { 346 std::ifstream configFp; 347 348 // This might be the first run because there is no config file in the 349 // Documents directory. It could also mean that a config file isn't being used at all 350 351 // Try the path passed into initialise 352 configFp.open(mConfigFileName.c_str(), std::ios::in); 353 354 // If we can't open this file then we have no default config file to work with 355 // Use the documents dir then. 356 if(!configFp.is_open()) 357 { 358 // Check to see if one was included in the app bundle 359 mConfigFileName = macBundlePath() + "/ogre.cfg"; 360 361 configFp.open(mConfigFileName.c_str(), std::ios::in); 362 363 // If we can't open this file then we have no default config file to work with 364 // Use the Documents dir then. 365 if(!configFp.is_open()) 366 mConfigFileName = configFileName; 367 } 368 369 configFp.close(); 370 } 371 372 fp.close(); 373 #endif 374 375 if (mConfigFileName.empty ()) 376 return true; 377 378 // Restores configuration from saved state 379 // Returns true if a valid saved configuration is 380 // available, and false if no saved config is 381 // stored, or if there has been a problem 382 ConfigFile cfg; 383 384 try { 385 // Don't trim whitespace 386 cfg.load(mConfigFileName, "\t:=", false); 387 } 388 catch (FileNotFoundException&) 389 { 390 return false; 391 } 392 393 ConfigFile::SettingsBySection_::const_iterator seci; 394 for(seci = cfg.getSettingsBySection().begin(); seci != cfg.getSettingsBySection().end(); ++seci) { 395 const ConfigFile::SettingsMultiMap& settings = seci->second; 396 const String& renderSystem = seci->first; 397 398 RenderSystem* rs = getRenderSystemByName(renderSystem); 399 if (!rs) 400 { 401 // Unrecognised render system 402 continue; 403 } 404 405 ConfigFile::SettingsMultiMap::const_iterator i; 406 for (i = settings.begin(); i != settings.end(); ++i) 407 { 408 rs->setConfigOption(i->first, i->second); 409 } 410 } 411 412 RenderSystem* rs = getRenderSystemByName(cfg.getSetting("Render System")); 413 if (!rs) 414 { 415 // Unrecognised render system 416 return false; 417 } 418 419 String err = rs->validateConfigOptions(); 420 if (err.length() > 0) 421 return false; 422 423 setRenderSystem(rs); 424 425 // Successful load 426 return true; 427 428 } 429 430 //----------------------------------------------------------------------- showConfigDialog(ConfigDialog * dialog)431 bool Root::showConfigDialog(ConfigDialog* dialog) { 432 if(dialog) { 433 restoreConfig(); 434 435 if (dialog->display()) { 436 saveConfig(); 437 return true; 438 } 439 440 return false; 441 } 442 443 // just select the first available render system 444 if (!mRenderers.empty()) 445 { 446 setRenderSystem(mRenderers.front()); 447 return true; 448 } 449 450 return false; 451 } 452 453 //----------------------------------------------------------------------- getAvailableRenderers(void)454 const RenderSystemList& Root::getAvailableRenderers(void) 455 { 456 // Returns a vector of renders 457 458 return mRenderers; 459 460 } 461 462 //----------------------------------------------------------------------- getRenderSystemByName(const String & name)463 RenderSystem* Root::getRenderSystemByName(const String& name) 464 { 465 if (name.empty()) 466 { 467 // No render system 468 return NULL; 469 } 470 471 RenderSystemList::const_iterator pRend; 472 for (pRend = getAvailableRenderers().begin(); pRend != getAvailableRenderers().end(); ++pRend) 473 { 474 RenderSystem* rs = *pRend; 475 if (rs->getName() == name) 476 return rs; 477 } 478 479 // Unrecognised render system 480 return NULL; 481 } 482 483 //----------------------------------------------------------------------- setRenderSystem(RenderSystem * system)484 void Root::setRenderSystem(RenderSystem* system) 485 { 486 // Sets the active rendering system 487 // Can be called direct or will be called by 488 // standard config dialog 489 490 // Is there already an active renderer? 491 // If so, disable it and init the new one 492 if( mActiveRenderer && mActiveRenderer != system ) 493 { 494 mActiveRenderer->shutdown(); 495 } 496 497 mActiveRenderer = system; 498 // Tell scene managers 499 if(mSceneManagerEnum) 500 mSceneManagerEnum->setRenderSystem(system); 501 502 if(RenderSystem::Listener* ls = RenderSystem::getSharedListener()) 503 ls->eventOccurred("RenderSystemChanged"); 504 } 505 //----------------------------------------------------------------------- addRenderSystem(RenderSystem * newRend)506 void Root::addRenderSystem(RenderSystem *newRend) 507 { 508 mRenderers.push_back(newRend); 509 } 510 //----------------------------------------------------------------------- _getCurrentSceneManager(void) const511 SceneManager* Root::_getCurrentSceneManager(void) const 512 { 513 if (mSceneManagerStack.empty()) 514 return 0; 515 else 516 return mSceneManagerStack.back(); 517 } 518 //----------------------------------------------------------------------- _pushCurrentSceneManager(SceneManager * sm)519 void Root::_pushCurrentSceneManager(SceneManager* sm) 520 { 521 mSceneManagerStack.push_back(sm); 522 } 523 //----------------------------------------------------------------------- _popCurrentSceneManager(SceneManager * sm)524 void Root::_popCurrentSceneManager(SceneManager* sm) 525 { 526 assert (_getCurrentSceneManager() == sm && "Mismatched push/pop of SceneManager"); 527 528 mSceneManagerStack.pop_back(); 529 } 530 //----------------------------------------------------------------------- getRenderSystem(void)531 RenderSystem* Root::getRenderSystem(void) 532 { 533 // Gets the currently active renderer 534 return mActiveRenderer; 535 536 } 537 538 //----------------------------------------------------------------------- initialise(bool autoCreateWindow,const String & windowTitle,const String & customCapabilitiesConfig)539 RenderWindow* Root::initialise(bool autoCreateWindow, const String& windowTitle, const String& customCapabilitiesConfig) 540 { 541 if (!mActiveRenderer) 542 OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 543 "Cannot initialise - no render " 544 "system has been selected.", "Root::initialise"); 545 546 if (!mControllerManager) 547 mControllerManager.reset(new ControllerManager()); 548 549 // .rendercaps manager 550 RenderSystemCapabilitiesManager& rscManager = RenderSystemCapabilitiesManager::getSingleton(); 551 // caller wants to load custom RenderSystemCapabilities form a config file 552 if(!customCapabilitiesConfig.empty()) 553 { 554 ConfigFile cfg; 555 cfg.load(customCapabilitiesConfig, "\t:=", false); 556 557 // Capabilities Database setting must be in the same format as 558 // resources.cfg in Ogre examples. 559 const ConfigFile::SettingsMultiMap& dbs = cfg.getSettings("Capabilities Database"); 560 for(ConfigFile::SettingsMultiMap::const_iterator it = dbs.begin(); it != dbs.end(); ++it) 561 { 562 const String& archType = it->first; 563 #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS 564 String filename = it->second; 565 566 // Only adjust relative directories 567 if (!StringUtil::startsWith(filename, "/", false)) 568 { 569 filename = StringUtil::replaceAll(filename, "../", ""); 570 filename = String(macBundlePath() + "/Contents/Resources/" + filename); 571 } 572 #else 573 String filename = it->second; 574 #endif 575 576 rscManager.parseCapabilitiesFromArchive(filename, archType, true); 577 } 578 579 String capsName = cfg.getSetting("Custom Capabilities"); 580 // The custom capabilities have been parsed, let's retrieve them 581 RenderSystemCapabilities* rsc = rscManager.loadParsedCapabilities(capsName); 582 if(rsc == 0) 583 { 584 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 585 String("Cannot load a RenderSystemCapability named ") + capsName, 586 "Root::initialise"); 587 } 588 589 // Tell RenderSystem to use the comon rsc 590 useCustomRenderSystemCapabilities(rsc); 591 } 592 593 594 PlatformInformation::log(LogManager::getSingleton().getDefaultLog()); 595 mAutoWindow = mActiveRenderer->_initialise(autoCreateWindow, windowTitle); 596 597 598 if (autoCreateWindow && !mFirstTimePostWindowInit) 599 { 600 oneTimePostWindowInit(); 601 mAutoWindow->_setPrimary(); 602 } 603 604 // Initialise timer 605 mTimer->reset(); 606 607 // Init pools 608 ConvexBody::_initialisePool(); 609 610 mIsInitialised = true; 611 612 return mAutoWindow; 613 614 } 615 //----------------------------------------------------------------------- useCustomRenderSystemCapabilities(RenderSystemCapabilities * capabilities)616 void Root::useCustomRenderSystemCapabilities(RenderSystemCapabilities* capabilities) 617 { 618 mActiveRenderer->useCustomRenderSystemCapabilities(capabilities); 619 } 620 //----------------------------------------------------------------------- addSceneManagerFactory(SceneManagerFactory * fact)621 void Root::addSceneManagerFactory(SceneManagerFactory* fact) 622 { 623 mSceneManagerEnum->addFactory(fact); 624 } 625 //----------------------------------------------------------------------- removeSceneManagerFactory(SceneManagerFactory * fact)626 void Root::removeSceneManagerFactory(SceneManagerFactory* fact) 627 { 628 mSceneManagerEnum->removeFactory(fact); 629 } 630 //----------------------------------------------------------------------- getSceneManagerMetaData(const String & typeName) const631 const SceneManagerMetaData* Root::getSceneManagerMetaData(const String& typeName) const 632 { 633 return mSceneManagerEnum->getMetaData(typeName); 634 } 635 //----------------------------------------------------------------------- 636 SceneManagerEnumerator::MetaDataIterator getSceneManagerMetaDataIterator(void) const637 Root::getSceneManagerMetaDataIterator(void) const 638 { 639 return mSceneManagerEnum->getMetaDataIterator(); 640 } 641 //----------------------------------------------------------------------- 642 const SceneManagerEnumerator::MetaDataList& getSceneManagerMetaData(void) const643 Root::getSceneManagerMetaData(void) const 644 { 645 return mSceneManagerEnum->getMetaData(); 646 } 647 //----------------------------------------------------------------------- createSceneManager(const String & typeName,const String & instanceName)648 SceneManager* Root::createSceneManager(const String& typeName, 649 const String& instanceName) 650 { 651 return mSceneManagerEnum->createSceneManager(typeName, instanceName); 652 } 653 //----------------------------------------------------------------------- destroySceneManager(SceneManager * sm)654 void Root::destroySceneManager(SceneManager* sm) 655 { 656 mSceneManagerEnum->destroySceneManager(sm); 657 } 658 //----------------------------------------------------------------------- getSceneManager(const String & instanceName) const659 SceneManager* Root::getSceneManager(const String& instanceName) const 660 { 661 return mSceneManagerEnum->getSceneManager(instanceName); 662 } 663 //--------------------------------------------------------------------- hasSceneManager(const String & instanceName) const664 bool Root::hasSceneManager(const String& instanceName) const 665 { 666 return mSceneManagerEnum->hasSceneManager(instanceName); 667 } 668 //----------------------------------------------------------------------- getSceneManagerIterator(void)669 SceneManagerEnumerator::SceneManagerIterator Root::getSceneManagerIterator(void) 670 { 671 return mSceneManagerEnum->getSceneManagerIterator(); 672 } 673 //----------------------------------------------------------------------- getSceneManagers(void) const674 const SceneManagerEnumerator::Instances& Root::getSceneManagers(void) const 675 { 676 return mSceneManagerEnum->getSceneManagers(); 677 } 678 //----------------------------------------------------------------------- getTextureManager(void)679 TextureManager* Root::getTextureManager(void) 680 { 681 return &TextureManager::getSingleton(); 682 } 683 //----------------------------------------------------------------------- getMeshManager(void)684 MeshManager* Root::getMeshManager(void) 685 { 686 return &MeshManager::getSingleton(); 687 } 688 //----------------------------------------------------------------------- addFrameListener(FrameListener * newListener)689 void Root::addFrameListener(FrameListener* newListener) 690 { 691 mRemovedFrameListeners.erase(newListener); 692 mAddedFrameListeners.insert(newListener); 693 } 694 //----------------------------------------------------------------------- removeFrameListener(FrameListener * oldListener)695 void Root::removeFrameListener(FrameListener* oldListener) 696 { 697 mAddedFrameListeners.erase(oldListener); 698 mRemovedFrameListeners.insert(oldListener); 699 } 700 //----------------------------------------------------------------------- _syncAddedRemovedFrameListeners()701 void Root::_syncAddedRemovedFrameListeners() 702 { 703 for (std::set<FrameListener*>::iterator i = mRemovedFrameListeners.begin(); i != mRemovedFrameListeners.end(); ++i) 704 mFrameListeners.erase(*i); 705 mRemovedFrameListeners.clear(); 706 707 for (std::set<FrameListener*>::iterator i = mAddedFrameListeners.begin(); i != mAddedFrameListeners.end(); ++i) 708 mFrameListeners.insert(*i); 709 mAddedFrameListeners.clear(); 710 } 711 //----------------------------------------------------------------------- _fireFrameStarted(FrameEvent & evt)712 bool Root::_fireFrameStarted(FrameEvent& evt) 713 { 714 OgreProfileBeginGroup("Frame", OGREPROF_GENERAL); 715 _syncAddedRemovedFrameListeners(); 716 717 // Tell all listeners 718 for (std::set<FrameListener*>::iterator i = mFrameListeners.begin(); i != mFrameListeners.end(); ++i) 719 { 720 if(mRemovedFrameListeners.find(*i) != mRemovedFrameListeners.end()) 721 continue; 722 723 if (!(*i)->frameStarted(evt)) 724 return false; 725 } 726 727 return true; 728 } 729 //----------------------------------------------------------------------- _fireFrameRenderingQueued(FrameEvent & evt)730 bool Root::_fireFrameRenderingQueued(FrameEvent& evt) 731 { 732 // Increment next frame number 733 ++mNextFrame; 734 _syncAddedRemovedFrameListeners(); 735 736 // Tell all listeners 737 for (std::set<FrameListener*>::iterator i = mFrameListeners.begin(); i != mFrameListeners.end(); ++i) 738 { 739 if(mRemovedFrameListeners.find(*i) != mRemovedFrameListeners.end()) 740 continue; 741 742 if (!(*i)->frameRenderingQueued(evt)) 743 return false; 744 } 745 746 return true; 747 } 748 //----------------------------------------------------------------------- _fireFrameEnded(FrameEvent & evt)749 bool Root::_fireFrameEnded(FrameEvent& evt) 750 { 751 _syncAddedRemovedFrameListeners(); 752 753 // Tell all listeners 754 bool ret = true; 755 for (std::set<FrameListener*>::iterator i = mFrameListeners.begin(); i != mFrameListeners.end(); ++i) 756 { 757 if(mRemovedFrameListeners.find(*i) != mRemovedFrameListeners.end()) 758 continue; 759 760 if (!(*i)->frameEnded(evt)) 761 { 762 ret = false; 763 break; 764 } 765 } 766 767 // Tell buffer manager to free temp buffers used this frame 768 if (HardwareBufferManager::getSingletonPtr()) 769 HardwareBufferManager::getSingleton()._releaseBufferCopies(); 770 771 // Tell the queue to process responses 772 mWorkQueue->processResponses(); 773 774 OgreProfileEndGroup("Frame", OGREPROF_GENERAL); 775 776 return ret; 777 } 778 //----------------------------------------------------------------------- _fireFrameStarted()779 bool Root::_fireFrameStarted() 780 { 781 FrameEvent evt; 782 populateFrameEvent(FETT_STARTED, evt); 783 784 return _fireFrameStarted(evt); 785 } 786 //----------------------------------------------------------------------- _fireFrameRenderingQueued()787 bool Root::_fireFrameRenderingQueued() 788 { 789 FrameEvent evt; 790 populateFrameEvent(FETT_QUEUED, evt); 791 792 return _fireFrameRenderingQueued(evt); 793 } 794 //----------------------------------------------------------------------- _fireFrameEnded()795 bool Root::_fireFrameEnded() 796 { 797 FrameEvent evt; 798 populateFrameEvent(FETT_ENDED, evt); 799 return _fireFrameEnded(evt); 800 } 801 //--------------------------------------------------------------------- populateFrameEvent(FrameEventTimeType type,FrameEvent & evtToUpdate)802 void Root::populateFrameEvent(FrameEventTimeType type, FrameEvent& evtToUpdate) 803 { 804 unsigned long now = mTimer->getMilliseconds(); 805 evtToUpdate.timeSinceLastEvent = calculateEventTime(now, FETT_ANY); 806 evtToUpdate.timeSinceLastFrame = calculateEventTime(now, type); 807 } 808 //----------------------------------------------------------------------- calculateEventTime(unsigned long now,FrameEventTimeType type)809 Real Root::calculateEventTime(unsigned long now, FrameEventTimeType type) 810 { 811 // Calculate the average time passed between events of the given type 812 // during the last mFrameSmoothingTime seconds. 813 814 EventTimesQueue& times = mEventTimes[type]; 815 times.push_back(now); 816 817 if(times.size() == 1) 818 return 0; 819 820 // Times up to mFrameSmoothingTime seconds old should be kept 821 unsigned long discardThreshold = 822 static_cast<unsigned long>(mFrameSmoothingTime * 1000.0f); 823 824 // Find the oldest time to keep 825 EventTimesQueue::iterator it = times.begin(), 826 end = times.end()-2; // We need at least two times 827 while(it != end) 828 { 829 if (now - *it > discardThreshold) 830 ++it; 831 else 832 break; 833 } 834 835 // Remove old times 836 times.erase(times.begin(), it); 837 838 return Real(times.back() - times.front()) / ((times.size()-1) * 1000); 839 } 840 //----------------------------------------------------------------------- queueEndRendering(bool state)841 void Root::queueEndRendering(bool state /* = true */) 842 { 843 mQueuedEnd = state; 844 } 845 //----------------------------------------------------------------------- endRenderingQueued(void)846 bool Root::endRenderingQueued(void) 847 { 848 return mQueuedEnd; 849 } 850 //----------------------------------------------------------------------- startRendering(void)851 void Root::startRendering(void) 852 { 853 OgreAssert(mActiveRenderer != 0, "no RenderSystem"); 854 855 mActiveRenderer->_initRenderTargets(); 856 857 // Clear event times 858 clearEventTimes(); 859 860 // Infinite loop, until broken out of by frame listeners 861 // or break out by calling queueEndRendering() 862 mQueuedEnd = false; 863 864 while( !mQueuedEnd ) 865 { 866 if (!renderOneFrame()) 867 break; 868 } 869 } 870 //----------------------------------------------------------------------- renderOneFrame(void)871 bool Root::renderOneFrame(void) 872 { 873 if(!_fireFrameStarted()) 874 return false; 875 876 if (!_updateAllRenderTargets()) 877 return false; 878 879 return _fireFrameEnded(); 880 } 881 //--------------------------------------------------------------------- renderOneFrame(Real timeSinceLastFrame)882 bool Root::renderOneFrame(Real timeSinceLastFrame) 883 { 884 FrameEvent evt; 885 evt.timeSinceLastFrame = timeSinceLastFrame; 886 887 unsigned long now = mTimer->getMilliseconds(); 888 evt.timeSinceLastEvent = calculateEventTime(now, FETT_ANY); 889 890 if(!_fireFrameStarted(evt)) 891 return false; 892 893 if (!_updateAllRenderTargets(evt)) 894 return false; 895 896 now = mTimer->getMilliseconds(); 897 evt.timeSinceLastEvent = calculateEventTime(now, FETT_ANY); 898 899 return _fireFrameEnded(evt); 900 } 901 //----------------------------------------------------------------------- shutdown(void)902 void Root::shutdown(void) 903 { 904 if(mActiveRenderer) 905 mActiveRenderer->_setViewport(NULL); 906 907 // Since background thread might be access resources, 908 // ensure shutdown before destroying resource manager. 909 mResourceBackgroundQueue->shutdown(); 910 mWorkQueue->shutdown(); 911 912 if(mSceneManagerEnum) 913 mSceneManagerEnum->shutdownAll(); 914 if(mFirstTimePostWindowInit) 915 { 916 shutdownPlugins(); 917 mParticleManager->removeAllTemplates(true); 918 mFirstTimePostWindowInit = false; 919 } 920 mSceneManagerEnum.reset(); 921 mShadowTextureManager.reset(); 922 923 ShadowVolumeExtrudeProgram::shutdown(); 924 ResourceGroupManager::getSingleton().shutdownAll(); 925 926 // Destroy pools 927 ConvexBody::_destroyPool(); 928 929 930 mIsInitialised = false; 931 932 LogManager::getSingleton().logMessage("*-*-* OGRE Shutdown"); 933 } 934 //----------------------------------------------------------------------- loadPlugins(const String & pluginsfile)935 void Root::loadPlugins( const String& pluginsfile ) 936 { 937 StringVector pluginList; 938 String pluginDir; 939 ConfigFile cfg; 940 941 try { 942 cfg.load( pluginsfile ); 943 } 944 catch (Exception& e) 945 { 946 LogManager::getSingleton().logMessage("automatic plugin loading disabled: "+e.getDescription()); 947 return; 948 } 949 950 pluginDir = cfg.getSetting("PluginFolder"); 951 pluginList = cfg.getMultiSetting("Plugin"); 952 953 StringUtil::trim(pluginDir); 954 if(pluginDir.empty() || pluginDir[0] == '.') 955 { 956 // resolve relative path with regards to configfile 957 String baseDir, filename; 958 StringUtil::splitFilename(pluginsfile, filename, baseDir); 959 pluginDir = baseDir + pluginDir; 960 } 961 962 pluginDir = FileSystemLayer::resolveBundlePath(pluginDir); 963 964 if (!pluginDir.empty() && *pluginDir.rbegin() != '/' && *pluginDir.rbegin() != '\\') 965 { 966 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT 967 pluginDir += "\\"; 968 #elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX 969 pluginDir += "/"; 970 #endif 971 } 972 973 for( StringVector::iterator it = pluginList.begin(); it != pluginList.end(); ++it ) 974 { 975 loadPlugin(pluginDir + (*it)); 976 } 977 978 } 979 //----------------------------------------------------------------------- shutdownPlugins(void)980 void Root::shutdownPlugins(void) 981 { 982 // NB Shutdown plugins in reverse order to enforce dependencies 983 for (PluginInstanceList::reverse_iterator i = mPlugins.rbegin(); i != mPlugins.rend(); ++i) 984 { 985 (*i)->shutdown(); 986 } 987 } 988 //----------------------------------------------------------------------- initialisePlugins(void)989 void Root::initialisePlugins(void) 990 { 991 for (PluginInstanceList::iterator i = mPlugins.begin(); i != mPlugins.end(); ++i) 992 { 993 (*i)->initialise(); 994 } 995 } 996 //----------------------------------------------------------------------- unloadPlugins(void)997 void Root::unloadPlugins(void) 998 { 999 #if OGRE_PLATFORM != OGRE_PLATFORM_EMSCRIPTEN 1000 // unload dynamic libs first 1001 for (PluginLibList::reverse_iterator i = mPluginLibs.rbegin(); i != mPluginLibs.rend(); ++i) 1002 { 1003 // Call plugin shutdown 1004 #ifdef __GNUC__ 1005 __extension__ 1006 #endif 1007 DLL_STOP_PLUGIN pFunc = reinterpret_cast<DLL_STOP_PLUGIN>((*i)->getSymbol("dllStopPlugin")); 1008 // this will call uninstallPlugin 1009 pFunc(); 1010 // Unload library & destroy 1011 DynLibManager::getSingleton().unload(*i); 1012 1013 } 1014 mPluginLibs.clear(); 1015 1016 // now deal with any remaining plugins that were registered through other means 1017 for (PluginInstanceList::reverse_iterator i = mPlugins.rbegin(); i != mPlugins.rend(); ++i) 1018 { 1019 // Note this does NOT call uninstallPlugin - this shutdown is for the 1020 // detail objects 1021 (*i)->uninstall(); 1022 } 1023 mPlugins.clear(); 1024 #endif 1025 } 1026 //--------------------------------------------------------------------- createFileStream(const String & filename,const String & groupName,bool overwrite,const String & locationPattern)1027 DataStreamPtr Root::createFileStream(const String& filename, const String& groupName, 1028 bool overwrite, const String& locationPattern) 1029 { 1030 // Does this file include path specifiers? 1031 String path, basename; 1032 StringUtil::splitFilename(filename, basename, path); 1033 1034 // no path elements, try the resource system first 1035 DataStreamPtr stream; 1036 if (path.empty()) 1037 { 1038 try 1039 { 1040 stream = ResourceGroupManager::getSingleton().createResource( 1041 filename, groupName, overwrite, locationPattern); 1042 } 1043 catch (...) {} 1044 1045 } 1046 1047 if (!stream) 1048 { 1049 // save direct in filesystem 1050 std::fstream* fs = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL); 1051 fs->open(filename.c_str(), std::ios::out | std::ios::binary); 1052 if (!*fs) 1053 { 1054 OGRE_DELETE_T(fs, basic_fstream, MEMCATEGORY_GENERAL); 1055 OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, 1056 "Can't open " + filename + " for writing"); 1057 } 1058 1059 stream = DataStreamPtr(OGRE_NEW FileStreamDataStream(filename, fs)); 1060 } 1061 1062 return stream; 1063 1064 } 1065 //--------------------------------------------------------------------- openFileStream(const String & filename,const String & groupName)1066 DataStreamPtr Root::openFileStream(const String& filename, const String& groupName) 1067 { 1068 auto ret = ResourceGroupManager::getSingleton().openResource(filename, groupName, NULL, false); 1069 if(ret) 1070 return ret; 1071 1072 // try direct 1073 std::ifstream *ifs = OGRE_NEW_T(std::ifstream, MEMCATEGORY_GENERAL); 1074 ifs->open(filename.c_str(), std::ios::in | std::ios::binary); 1075 if(!*ifs) 1076 { 1077 OGRE_DELETE_T(ifs, basic_ifstream, MEMCATEGORY_GENERAL); 1078 OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, "'" + filename + "' file not found!"); 1079 } 1080 return DataStreamPtr(OGRE_NEW FileStreamDataStream(filename, ifs)); 1081 } 1082 //----------------------------------------------------------------------- convertColourValue(const ColourValue & colour,uint32 * pDest)1083 void Root::convertColourValue(const ColourValue& colour, uint32* pDest) 1084 { 1085 assert(mActiveRenderer != 0); 1086 mActiveRenderer->convertColourValue(colour, pDest); 1087 } 1088 //----------------------------------------------------------------------- getAutoCreatedWindow(void)1089 RenderWindow* Root::getAutoCreatedWindow(void) 1090 { 1091 return mAutoWindow; 1092 } 1093 //----------------------------------------------------------------------- createRenderWindow(const String & name,unsigned int width,unsigned int height,bool fullScreen,const NameValuePairList * miscParams)1094 RenderWindow* Root::createRenderWindow(const String &name, unsigned int width, unsigned int height, 1095 bool fullScreen, const NameValuePairList *miscParams) 1096 { 1097 if (!mIsInitialised) 1098 { 1099 OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 1100 "Cannot create window - Root has not been initialised! " 1101 "Make sure to call Root::initialise before creating a window.", "Root::createRenderWindow"); 1102 } 1103 if (!mActiveRenderer) 1104 { 1105 OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 1106 "Cannot create window - no render " 1107 "system has been selected.", "Root::createRenderWindow"); 1108 } 1109 RenderWindow* ret; 1110 ret = mActiveRenderer->_createRenderWindow(name, width, height, fullScreen, miscParams); 1111 1112 // Initialisation for classes dependent on first window created 1113 if(!mFirstTimePostWindowInit) 1114 { 1115 oneTimePostWindowInit(); 1116 ret->_setPrimary(); 1117 } 1118 1119 return ret; 1120 1121 } 1122 //----------------------------------------------------------------------- createRenderWindows(const RenderWindowDescriptionList & renderWindowDescriptions,RenderWindowList & createdWindows)1123 bool Root::createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, 1124 RenderWindowList& createdWindows) 1125 { 1126 if (!mIsInitialised) 1127 { 1128 OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 1129 "Cannot create window - Root has not been initialised! " 1130 "Make sure to call Root::initialise before creating a window.", "Root::createRenderWindows"); 1131 } 1132 if (!mActiveRenderer) 1133 { 1134 OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 1135 "Cannot create render windows - no render " 1136 "system has been selected.", "Root::createRenderWindows"); 1137 } 1138 1139 bool success; 1140 1141 success = mActiveRenderer->_createRenderWindows(renderWindowDescriptions, createdWindows); 1142 if(success && !mFirstTimePostWindowInit) 1143 { 1144 oneTimePostWindowInit(); 1145 createdWindows[0]->_setPrimary(); 1146 } 1147 1148 return success; 1149 } 1150 //----------------------------------------------------------------------- detachRenderTarget(RenderTarget * target)1151 RenderTarget* Root::detachRenderTarget(RenderTarget* target) 1152 { 1153 if (!mActiveRenderer) 1154 { 1155 OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 1156 "Cannot detach target - no render " 1157 "system has been selected.", "Root::detachRenderTarget"); 1158 } 1159 1160 return mActiveRenderer->detachRenderTarget( target->getName() ); 1161 } 1162 //----------------------------------------------------------------------- detachRenderTarget(const String & name)1163 RenderTarget* Root::detachRenderTarget(const String &name) 1164 { 1165 if (!mActiveRenderer) 1166 { 1167 OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 1168 "Cannot detach target - no render " 1169 "system has been selected.", "Root::detachRenderTarget"); 1170 } 1171 1172 return mActiveRenderer->detachRenderTarget( name ); 1173 } 1174 //----------------------------------------------------------------------- destroyRenderTarget(RenderTarget * target)1175 void Root::destroyRenderTarget(RenderTarget* target) 1176 { 1177 detachRenderTarget(target); 1178 OGRE_DELETE target; 1179 } 1180 //----------------------------------------------------------------------- destroyRenderTarget(const String & name)1181 void Root::destroyRenderTarget(const String &name) 1182 { 1183 RenderTarget* target = getRenderTarget(name); 1184 destroyRenderTarget(target); 1185 } 1186 //----------------------------------------------------------------------- getRenderTarget(const String & name)1187 RenderTarget* Root::getRenderTarget(const String &name) 1188 { 1189 if (!mActiveRenderer) 1190 { 1191 OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 1192 "Cannot get target - no render " 1193 "system has been selected.", "Root::getRenderTarget"); 1194 } 1195 1196 return mActiveRenderer->getRenderTarget(name); 1197 } 1198 //--------------------------------------------------------------------- installPlugin(Plugin * plugin)1199 void Root::installPlugin(Plugin* plugin) 1200 { 1201 LogManager::getSingleton().logMessage("Installing plugin: " + plugin->getName()); 1202 1203 mPlugins.push_back(plugin); 1204 plugin->install(); 1205 1206 // if rendersystem is already initialised, call rendersystem init too 1207 if (mIsInitialised) 1208 { 1209 plugin->initialise(); 1210 } 1211 1212 LogManager::getSingleton().logMessage("Plugin successfully installed"); 1213 } 1214 //--------------------------------------------------------------------- uninstallPlugin(Plugin * plugin)1215 void Root::uninstallPlugin(Plugin* plugin) 1216 { 1217 LogManager::getSingleton().logMessage("Uninstalling plugin: " + plugin->getName()); 1218 PluginInstanceList::iterator i = 1219 std::find(mPlugins.begin(), mPlugins.end(), plugin); 1220 if (i != mPlugins.end()) 1221 { 1222 if (mIsInitialised) 1223 plugin->shutdown(); 1224 plugin->uninstall(); 1225 mPlugins.erase(i); 1226 } 1227 LogManager::getSingleton().logMessage("Plugin successfully uninstalled"); 1228 1229 } 1230 //----------------------------------------------------------------------- loadPlugin(const String & pluginName)1231 void Root::loadPlugin(const String& pluginName) 1232 { 1233 #if OGRE_PLATFORM != OGRE_PLATFORM_EMSCRIPTEN 1234 // Load plugin library 1235 DynLib* lib = DynLibManager::getSingleton().load( pluginName ); 1236 // Store for later unload 1237 // Check for existence, because if called 2+ times DynLibManager returns existing entry 1238 if (std::find(mPluginLibs.begin(), mPluginLibs.end(), lib) == mPluginLibs.end()) 1239 { 1240 mPluginLibs.push_back(lib); 1241 1242 // Call startup function 1243 #ifdef __GNUC__ 1244 __extension__ 1245 #endif 1246 DLL_START_PLUGIN pFunc = (DLL_START_PLUGIN)lib->getSymbol("dllStartPlugin"); 1247 1248 if (!pFunc) 1249 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot find symbol dllStartPlugin in library " + pluginName, 1250 "Root::loadPlugin"); 1251 1252 // This must call installPlugin 1253 pFunc(); 1254 } 1255 #endif 1256 } 1257 //----------------------------------------------------------------------- unloadPlugin(const String & pluginName)1258 void Root::unloadPlugin(const String& pluginName) 1259 { 1260 #if OGRE_PLATFORM != OGRE_PLATFORM_EMSCRIPTEN 1261 PluginLibList::iterator i; 1262 1263 for (i = mPluginLibs.begin(); i != mPluginLibs.end(); ++i) 1264 { 1265 if ((*i)->getName() == pluginName) 1266 { 1267 // Call plugin shutdown 1268 #ifdef __GNUC__ 1269 __extension__ 1270 #endif 1271 DLL_STOP_PLUGIN pFunc = (DLL_STOP_PLUGIN)(*i)->getSymbol("dllStopPlugin"); 1272 // this must call uninstallPlugin 1273 pFunc(); 1274 // Unload library (destroyed by DynLibManager) 1275 DynLibManager::getSingleton().unload(*i); 1276 mPluginLibs.erase(i); 1277 return; 1278 } 1279 1280 } 1281 #endif 1282 } 1283 //----------------------------------------------------------------------- getTimer(void)1284 Timer* Root::getTimer(void) 1285 { 1286 return mTimer.get(); 1287 } 1288 //----------------------------------------------------------------------- oneTimePostWindowInit(void)1289 void Root::oneTimePostWindowInit(void) 1290 { 1291 if (!mFirstTimePostWindowInit) 1292 { 1293 // Background loader 1294 mResourceBackgroundQueue->initialise(); 1295 mWorkQueue->startup(); 1296 // Initialise material manager 1297 mMaterialManager->initialise(); 1298 // Init particle systems manager 1299 mParticleManager->_initialise(); 1300 // Init mesh manager 1301 MeshManager::getSingleton()._initialise(); 1302 // Init plugins - after window creation so rsys resources available 1303 initialisePlugins(); 1304 mFirstTimePostWindowInit = true; 1305 } 1306 1307 } 1308 //----------------------------------------------------------------------- _updateAllRenderTargets(void)1309 bool Root::_updateAllRenderTargets(void) 1310 { 1311 // update all targets but don't swap buffers 1312 mActiveRenderer->_updateAllRenderTargets(false); 1313 // give client app opportunity to use queued GPU time 1314 bool ret = _fireFrameRenderingQueued(); 1315 // block for final swap 1316 mActiveRenderer->_swapAllRenderTargetBuffers(); 1317 1318 // This belongs here, as all render targets must be updated before events are 1319 // triggered, otherwise targets could be mismatched. This could produce artifacts, 1320 // for instance, with shadows. 1321 SceneManagerEnumerator::Instances::const_iterator it, end = getSceneManagers().end(); 1322 for (it = getSceneManagers().begin(); it != end; ++it) 1323 it->second->_handleLodEvents(); 1324 1325 return ret; 1326 } 1327 //--------------------------------------------------------------------- _updateAllRenderTargets(FrameEvent & evt)1328 bool Root::_updateAllRenderTargets(FrameEvent& evt) 1329 { 1330 // update all targets but don't swap buffers 1331 mActiveRenderer->_updateAllRenderTargets(false); 1332 // give client app opportunity to use queued GPU time 1333 bool ret = _fireFrameRenderingQueued(evt); 1334 // block for final swap 1335 mActiveRenderer->_swapAllRenderTargetBuffers(); 1336 1337 // This belongs here, as all render targets must be updated before events are 1338 // triggered, otherwise targets could be mismatched. This could produce artifacts, 1339 // for instance, with shadows. 1340 SceneManagerEnumerator::Instances::const_iterator it, end = getSceneManagers().end(); 1341 for (it = getSceneManagers().begin(); it != end; ++it) 1342 it->second->_handleLodEvents(); 1343 1344 return ret; 1345 } 1346 //----------------------------------------------------------------------- clearEventTimes(void)1347 void Root::clearEventTimes(void) 1348 { 1349 // Clear event times 1350 for(int i=0; i<FETT_COUNT; ++i) 1351 mEventTimes[i].clear(); 1352 } 1353 //--------------------------------------------------------------------- addMovableObjectFactory(MovableObjectFactory * fact,bool overrideExisting)1354 void Root::addMovableObjectFactory(MovableObjectFactory* fact, 1355 bool overrideExisting) 1356 { 1357 MovableObjectFactoryMap::iterator facti = mMovableObjectFactoryMap.find( 1358 fact->getType()); 1359 if (!overrideExisting && facti != mMovableObjectFactoryMap.end()) 1360 { 1361 OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, 1362 "A factory of type '" + fact->getType() + "' already exists.", 1363 "Root::addMovableObjectFactory"); 1364 } 1365 1366 if (fact->requestTypeFlags()) 1367 { 1368 if (facti != mMovableObjectFactoryMap.end() && facti->second->requestTypeFlags()) 1369 { 1370 // Copy type flags from the factory we're replacing 1371 fact->_notifyTypeFlags(facti->second->getTypeFlags()); 1372 } 1373 else 1374 { 1375 // Allocate new 1376 fact->_notifyTypeFlags(_allocateNextMovableObjectTypeFlag()); 1377 } 1378 } 1379 1380 // Save 1381 mMovableObjectFactoryMap[fact->getType()] = fact; 1382 1383 LogManager::getSingleton().logMessage("MovableObjectFactory for type '" + 1384 fact->getType() + "' registered."); 1385 1386 } 1387 //--------------------------------------------------------------------- hasMovableObjectFactory(const String & typeName) const1388 bool Root::hasMovableObjectFactory(const String& typeName) const 1389 { 1390 return !(mMovableObjectFactoryMap.find(typeName) == mMovableObjectFactoryMap.end()); 1391 } 1392 //--------------------------------------------------------------------- getMovableObjectFactory(const String & typeName)1393 MovableObjectFactory* Root::getMovableObjectFactory(const String& typeName) 1394 { 1395 MovableObjectFactoryMap::iterator i = 1396 mMovableObjectFactoryMap.find(typeName); 1397 if (i == mMovableObjectFactoryMap.end()) 1398 { 1399 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 1400 "MovableObjectFactory of type " + typeName + " does not exist", 1401 "Root::getMovableObjectFactory"); 1402 } 1403 return i->second; 1404 } 1405 //--------------------------------------------------------------------- _allocateNextMovableObjectTypeFlag(void)1406 uint32 Root::_allocateNextMovableObjectTypeFlag(void) 1407 { 1408 if (mNextMovableObjectTypeFlag == SceneManager::USER_TYPE_MASK_LIMIT) 1409 { 1410 OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, 1411 "Cannot allocate a type flag since " 1412 "all the available flags have been used.", 1413 "Root::_allocateNextMovableObjectTypeFlag"); 1414 1415 } 1416 uint32 ret = mNextMovableObjectTypeFlag; 1417 mNextMovableObjectTypeFlag <<= 1; 1418 return ret; 1419 1420 } 1421 //--------------------------------------------------------------------- removeMovableObjectFactory(MovableObjectFactory * fact)1422 void Root::removeMovableObjectFactory(MovableObjectFactory* fact) 1423 { 1424 MovableObjectFactoryMap::iterator i = mMovableObjectFactoryMap.find( 1425 fact->getType()); 1426 if (i != mMovableObjectFactoryMap.end()) 1427 { 1428 mMovableObjectFactoryMap.erase(i); 1429 } 1430 1431 } 1432 //--------------------------------------------------------------------- 1433 Root::MovableObjectFactoryIterator getMovableObjectFactoryIterator(void) const1434 Root::getMovableObjectFactoryIterator(void) const 1435 { 1436 return MovableObjectFactoryIterator(mMovableObjectFactoryMap.begin(), 1437 mMovableObjectFactoryMap.end()); 1438 1439 } 1440 //--------------------------------------------------------------------- createRenderQueueInvocationSequence(const String & name)1441 RenderQueueInvocationSequence* Root::createRenderQueueInvocationSequence( 1442 const String& name) 1443 { 1444 RenderQueueInvocationSequenceMap::iterator i = 1445 mRQSequenceMap.find(name); 1446 if (i != mRQSequenceMap.end()) 1447 { 1448 OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, 1449 "RenderQueueInvocationSequence with the name " + name + 1450 " already exists.", 1451 "Root::createRenderQueueInvocationSequence"); 1452 } 1453 RenderQueueInvocationSequence* ret = OGRE_NEW RenderQueueInvocationSequence(name); 1454 mRQSequenceMap[name] = ret; 1455 return ret; 1456 } 1457 //--------------------------------------------------------------------- getRenderQueueInvocationSequence(const String & name)1458 RenderQueueInvocationSequence* Root::getRenderQueueInvocationSequence( 1459 const String& name) 1460 { 1461 RenderQueueInvocationSequenceMap::iterator i = 1462 mRQSequenceMap.find(name); 1463 if (i == mRQSequenceMap.end()) 1464 { 1465 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 1466 "RenderQueueInvocationSequence with the name " + name + 1467 " not found.", 1468 "Root::getRenderQueueInvocationSequence"); 1469 } 1470 return i->second; 1471 } 1472 //--------------------------------------------------------------------- destroyRenderQueueInvocationSequence(const String & name)1473 void Root::destroyRenderQueueInvocationSequence( 1474 const String& name) 1475 { 1476 RenderQueueInvocationSequenceMap::iterator i = 1477 mRQSequenceMap.find(name); 1478 if (i != mRQSequenceMap.end()) 1479 { 1480 OGRE_DELETE i->second; 1481 mRQSequenceMap.erase(i); 1482 } 1483 } 1484 //--------------------------------------------------------------------- destroyAllRenderQueueInvocationSequences(void)1485 void Root::destroyAllRenderQueueInvocationSequences(void) 1486 { 1487 for (RenderQueueInvocationSequenceMap::iterator i = mRQSequenceMap.begin(); 1488 i != mRQSequenceMap.end(); ++i) 1489 { 1490 OGRE_DELETE i->second; 1491 } 1492 mRQSequenceMap.clear(); 1493 } 1494 1495 //--------------------------------------------------------------------- getDisplayMonitorCount() const1496 unsigned int Root::getDisplayMonitorCount() const 1497 { 1498 if (!mActiveRenderer) 1499 { 1500 OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 1501 "Cannot get display monitor count " 1502 "No render system has been selected.", "Root::getDisplayMonitorCount"); 1503 } 1504 1505 return mActiveRenderer->getDisplayMonitorCount(); 1506 1507 } 1508 //--------------------------------------------------------------------- setWorkQueue(WorkQueue * queue)1509 void Root::setWorkQueue(WorkQueue* queue) 1510 { 1511 if (mWorkQueue.get() != queue) 1512 { 1513 mWorkQueue.reset(queue); 1514 if (mIsInitialised) 1515 mWorkQueue->startup(); 1516 1517 } 1518 } 1519 1520 1521 1522 } 1523