Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreRoot.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 37.8 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29// Ogre includes
30#include "OgreStableHeaders.h"
31
32#include "OgreRoot.h"
33
34#include "OgreRenderSystem.h"
35#include "OgreRenderWindow.h"
36#include "OgreException.h"
37#include "OgreControllerManager.h"
38#include "OgreLogManager.h"
39#include "OgreMath.h"
40#include "OgreDynLibManager.h"
41#include "OgreDynLib.h"
42#include "OgreConfigFile.h"
43#include "OgreMaterialManager.h"
44#include "OgreMeshManager.h"
45#include "OgreTextureManager.h"
46#include "OgreParticleSystemManager.h"
47#include "OgreSkeletonManager.h"
48#include "OgreOverlayElementFactory.h"
49#include "OgreOverlayManager.h"
50#include "OgreProfiler.h"
51#include "OgreErrorDialog.h"
52#include "OgreConfigDialog.h"
53#include "OgreStringConverter.h"
54#include "OgreArchiveManager.h"
55#include "OgrePlugin.h"
56#include "OgreZip.h"
57#include "OgreFileSystem.h"
58#include "OgreShadowVolumeExtrudeProgram.h"
59#include "OgreResourceBackgroundQueue.h"
60#include "OgreEntity.h"
61#include "OgreBillboardSet.h"
62#include "OgreBillboardChain.h"
63#include "OgreRibbonTrail.h"
64#include "OgreLight.h"
65#include "OgreManualObject.h"
66#include "OgreRenderQueueInvocation.h"
67#include "OgrePlatformInformation.h"
68#include "OgreConvexBody.h"
69       
70#if OGRE_NO_FREEIMAGE == 0
71#include "OgreFreeImageCodec.h"
72#endif
73#if OGRE_NO_DEVIL == 0
74#include "OgreILCodecs.h"
75#endif
76#if OGRE_NO_DDS_CODEC == 0
77#include "OgreDDSCodec.h"
78#endif
79
80#include "OgreFontManager.h"
81#include "OgreHardwareBufferManager.h"
82
83#include "OgreOverlay.h"
84#include "OgreHighLevelGpuProgramManager.h"
85
86#include "OgreExternalTextureSourceManager.h"
87#include "OgreCompositorManager.h"
88
89#include "OgreWindowEventUtilities.h"
90
91namespace Ogre {
92    //-----------------------------------------------------------------------
93    template<> Root* Singleton<Root>::ms_Singleton = 0;
94    Root* Root::getSingletonPtr(void)
95    {
96        return ms_Singleton;
97    }
98    Root& Root::getSingleton(void)
99    {
100        assert( ms_Singleton );  return ( *ms_Singleton );
101    }
102
103    typedef void (*DLL_START_PLUGIN)(void);
104    typedef void (*DLL_STOP_PLUGIN)(void);
105
106
107    //-----------------------------------------------------------------------
108    Root::Root(const String& pluginFileName, const String& configFileName, 
109                const String& logFileName)
110      : mLogManager(0), mCurrentFrame(0), mFrameSmoothingTime(0.0f),
111          mNextMovableObjectTypeFlag(1), mIsInitialised(false)
112    {
113        // superclass will do singleton checking
114        String msg;
115
116        // Init
117        mActiveRenderer = 0;
118        mVersion = StringConverter::toString(OGRE_VERSION_MAJOR) + "." +
119            StringConverter::toString(OGRE_VERSION_MINOR) + "." +
120            StringConverter::toString(OGRE_VERSION_PATCH) + 
121                        OGRE_VERSION_SUFFIX + " " +
122            "(" + OGRE_VERSION_NAME + ")";
123                mConfigFileName = configFileName;
124
125                // Create log manager and default log file if there is no log manager yet
126                if(LogManager::getSingletonPtr() == 0)
127                {
128                        mLogManager = new LogManager();
129                        mLogManager->createLog(logFileName, true, true);
130                }
131
132        // Dynamic library manager
133        mDynLibManager = new DynLibManager();
134
135        mArchiveManager = new ArchiveManager();
136
137                // ResourceGroupManager
138                mResourceGroupManager = new ResourceGroupManager();
139
140                // ResourceBackgroundQueue
141                mResourceBackgroundQueue = new ResourceBackgroundQueue();
142
143                // Create SceneManager enumerator (note - will be managed by singleton)
144        mSceneManagerEnum = new SceneManagerEnumerator();
145        mCurrentSceneManager = NULL;
146
147                mShadowTextureManager = new ShadowTextureManager();
148
149        // ..material manager
150        mMaterialManager = new MaterialManager();
151
152        // Mesh manager
153        mMeshManager = new MeshManager();
154
155        // Skeleton manager
156        mSkeletonManager = new SkeletonManager();
157
158        // ..particle system manager
159        mParticleManager = new ParticleSystemManager();
160
161        mTimer = new Timer();
162
163        // Overlay manager
164        mOverlayManager = new OverlayManager();
165
166        mPanelFactory = new PanelOverlayElementFactory();
167        mOverlayManager->addOverlayElementFactory(mPanelFactory);
168
169        mBorderPanelFactory = new BorderPanelOverlayElementFactory();
170        mOverlayManager->addOverlayElementFactory(mBorderPanelFactory);
171
172        mTextAreaFactory = new TextAreaOverlayElementFactory();
173        mOverlayManager->addOverlayElementFactory(mTextAreaFactory);
174        // Font manager
175        mFontManager = new FontManager();
176
177#if OGRE_PROFILING
178        // Profiler
179        mProfiler = new Profiler();
180                Profiler::getSingleton().setTimer(mTimer);
181#endif
182        mFileSystemArchiveFactory = new FileSystemArchiveFactory();
183        ArchiveManager::getSingleton().addArchiveFactory( mFileSystemArchiveFactory );
184        mZipArchiveFactory = new ZipArchiveFactory();
185        ArchiveManager::getSingleton().addArchiveFactory( mZipArchiveFactory );
186#if OGRE_NO_FREEIMAGE == 0
187                // Register image codecs
188                FreeImageCodec::startup();
189#endif
190#if OGRE_NO_DEVIL == 0
191            // Register image codecs
192            ILCodecs::registerCodecs();
193#endif
194#if OGRE_NO_DDS_CODEC == 0
195                // Register image codecs
196                DDSCodec::startup();
197#endif
198
199        mHighLevelGpuProgramManager = new HighLevelGpuProgramManager();
200
201                mExternalTextureSourceManager = new ExternalTextureSourceManager();
202        mCompositorManager = new CompositorManager();
203
204        // Auto window
205        mAutoWindow = 0;
206
207                // instantiate and register base movable factories
208                mEntityFactory = new EntityFactory();
209                addMovableObjectFactory(mEntityFactory);
210                mLightFactory = new LightFactory();
211                addMovableObjectFactory(mLightFactory);
212                mBillboardSetFactory = new BillboardSetFactory();
213                addMovableObjectFactory(mBillboardSetFactory);
214                mManualObjectFactory = new ManualObjectFactory();
215                addMovableObjectFactory(mManualObjectFactory);
216                mBillboardChainFactory = new BillboardChainFactory();
217                addMovableObjectFactory(mBillboardChainFactory);
218                mRibbonTrailFactory = new RibbonTrailFactory();
219                addMovableObjectFactory(mRibbonTrailFactory);
220
221                // Load plugins
222        if (!pluginFileName.empty())
223            loadPlugins(pluginFileName);
224
225                LogManager::getSingleton().logMessage("*-*-* OGRE Initialising");
226        msg = "*-*-* Version " + mVersion;
227        LogManager::getSingleton().logMessage(msg);
228
229        // Can't create managers until initialised
230        mControllerManager = 0;
231
232        mFirstTimePostWindowInit = false;
233
234    }
235
236    //-----------------------------------------------------------------------
237    Root::~Root()
238    {
239        shutdown();
240        delete mSceneManagerEnum;
241                delete mShadowTextureManager;
242
243                destroyAllRenderQueueInvocationSequences();
244        delete mCompositorManager;
245                delete mExternalTextureSourceManager;
246#if OGRE_NO_FREEIMAGE == 0
247                FreeImageCodec::shutdown();
248#endif
249#if OGRE_NO_DEVIL == 0
250        ILCodecs::deleteCodecs();
251#endif
252#if OGRE_NO_DDS_CODEC == 0
253                DDSCodec::shutdown();
254#endif
255#if OGRE_PROFILING
256        delete mProfiler;
257#endif
258        delete mOverlayManager;
259        delete mFontManager;
260        delete mArchiveManager;
261        delete mZipArchiveFactory;
262        delete mFileSystemArchiveFactory;
263        delete mSkeletonManager;
264        delete mMeshManager;
265        delete mParticleManager;
266
267        if( mControllerManager )
268            delete mControllerManager;
269        if (mHighLevelGpuProgramManager)
270            delete mHighLevelGpuProgramManager;
271
272        delete mTextAreaFactory;
273        delete mBorderPanelFactory;
274        delete mPanelFactory;
275
276        unloadPlugins();
277        delete mMaterialManager;
278        Pass::processPendingPassUpdates(); // make sure passes are cleaned
279                delete mResourceBackgroundQueue;
280        delete mResourceGroupManager;
281
282                delete mEntityFactory;
283                delete mLightFactory;
284                delete mBillboardSetFactory;
285                delete mManualObjectFactory;
286                delete mBillboardChainFactory;
287                delete mRibbonTrailFactory;
288
289        delete mTimer;
290
291        delete mDynLibManager;
292        delete mLogManager;
293
294                mAutoWindow = 0;
295                mFirstTimePostWindowInit = false;
296
297
298        StringInterface::cleanupDictionary ();
299    }
300
301    //-----------------------------------------------------------------------
302    void Root::saveConfig(void)
303    {
304        if (mConfigFileName.empty ())
305            return;
306
307                std::ofstream of(mConfigFileName.c_str());
308
309        if (!of)
310            OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, "Cannot create settings file.",
311            "Root::saveConfig");
312
313        if (mActiveRenderer)
314        {
315            of << "Render System=" << mActiveRenderer->getName() << std::endl;
316        }
317        else
318        {
319            of << "Render System=" << std::endl;
320        }
321
322        for (RenderSystemList::const_iterator pRend = getAvailableRenderers()->begin(); pRend != getAvailableRenderers()->end(); ++pRend)
323        {
324            RenderSystem* rs = *pRend;
325            of << std::endl;
326            of << "[" << rs->getName() << "]" << std::endl;
327            const ConfigOptionMap& opts = rs->getConfigOptions();
328            for (ConfigOptionMap::const_iterator pOpt = opts.begin(); pOpt != opts.end(); ++pOpt)
329            {
330                                of << pOpt->first << "=" << pOpt->second.currentValue << std::endl;
331            }
332        }
333
334        of.close();
335
336    }
337    //-----------------------------------------------------------------------
338    bool Root::restoreConfig(void)
339    {
340        if (mConfigFileName.empty ())
341            return true;
342
343        // Restores configuration from saved state
344        // Returns true if a valid saved configuration is
345        //   available, and false if no saved config is
346        //   stored, or if there has been a problem
347        ConfigFile cfg;
348        //RenderSystemList::iterator pRend;
349
350        try {
351            // Don't trim whitespace
352            cfg.load(mConfigFileName, "\t:=", false);
353        }
354        catch (Exception& e)
355        {
356            if (e.getNumber() == Exception::ERR_FILE_NOT_FOUND)
357            {
358                return false;
359            }
360            else
361            {
362                throw;
363            }
364        }
365
366        ConfigFile::SectionIterator iSection = cfg.getSectionIterator();
367        while (iSection.hasMoreElements())
368        {
369            const String& renderSystem = iSection.peekNextKey();
370            const ConfigFile::SettingsMultiMap& settings = *iSection.getNext();
371
372            RenderSystem* rs = getRenderSystemByName(renderSystem);
373            if (!rs)
374            {
375                // Unrecognised render system
376                continue;
377            }
378
379            ConfigFile::SettingsMultiMap::const_iterator i;
380            for (i = settings.begin(); i != settings.end(); ++i)
381            {
382                rs->setConfigOption(i->first, i->second);
383            }
384        }
385
386        RenderSystem* rs = getRenderSystemByName(cfg.getSetting("Render System"));
387        if (!rs)
388        {
389            // Unrecognised render system
390            return false;
391        }
392
393        setRenderSystem(rs);
394
395        // Successful load
396        return true;
397
398    }
399
400    //-----------------------------------------------------------------------
401    bool Root::showConfigDialog(void)
402    {
403        // Displays the standard config dialog
404        // Will use stored defaults if available
405        ConfigDialog* dlg;
406        bool isOk;
407
408        restoreConfig();
409
410        dlg = new ConfigDialog();
411
412        if ((isOk = dlg->display()))
413            saveConfig();
414
415        delete dlg;
416        return isOk;
417    }
418
419    //-----------------------------------------------------------------------
420    RenderSystemList* Root::getAvailableRenderers(void)
421    {
422        // Returns a vector of renders
423
424        return &mRenderers;
425
426    }
427
428    //-----------------------------------------------------------------------
429    RenderSystem* Root::getRenderSystemByName(const String& name)
430    {
431        if (name.empty())
432        {
433            // No render system
434            return NULL;
435        }
436
437        RenderSystemList::const_iterator pRend;
438        for (pRend = getAvailableRenderers()->begin(); pRend != getAvailableRenderers()->end(); ++pRend)
439        {
440            RenderSystem* rs = *pRend;
441            if (rs->getName() == name)
442                return rs;
443        }
444
445        // Unrecognised render system
446        return NULL;
447    }
448
449    //-----------------------------------------------------------------------
450    void Root::setRenderSystem(RenderSystem* system)
451    {
452        // Sets the active rendering system
453        // Can be called direct or will be called by
454        //   standard config dialog
455
456        // Is there already an active renderer?
457        // If so, disable it and init the new one
458        if( mActiveRenderer && mActiveRenderer != system )
459        {
460            mActiveRenderer->shutdown();
461        }
462
463        mActiveRenderer = system;
464        // Tell scene managers
465        SceneManagerEnumerator::getSingleton().setRenderSystem(system);
466
467    }
468    //-----------------------------------------------------------------------
469    void Root::addRenderSystem(RenderSystem *newRend)
470    {
471        mRenderers.push_back(newRend);
472    }
473    //-----------------------------------------------------------------------
474        void Root::_setCurrentSceneManager(SceneManager* sm)
475        {
476                mCurrentSceneManager = sm;
477        }
478    //-----------------------------------------------------------------------
479    RenderSystem* Root::getRenderSystem(void)
480    {
481        // Gets the currently active renderer
482        return mActiveRenderer;
483
484    }
485
486    //-----------------------------------------------------------------------
487    RenderWindow* Root::initialise(bool autoCreateWindow, const String& windowTitle)
488    {
489        if (!mActiveRenderer)
490            OGRE_EXCEPT(Exception::ERR_INVALID_STATE,
491            "Cannot initialise - no render "
492            "system has been selected.", "Root::initialise");
493
494        if (!mControllerManager)
495                        mControllerManager = new ControllerManager();
496
497                PlatformInformation::log(LogManager::getSingleton().getDefaultLog());
498                mAutoWindow =  mActiveRenderer->initialise(autoCreateWindow, windowTitle);
499
500
501        if (autoCreateWindow && !mFirstTimePostWindowInit)
502        {
503            oneTimePostWindowInit();
504            mAutoWindow->_setPrimary();
505        }
506
507        // Initialise timer
508        mTimer->reset();
509
510                // Init pools
511                ConvexBody::_initialisePool();
512
513                mIsInitialised = true;
514
515        return mAutoWindow;
516
517    }
518    //-----------------------------------------------------------------------
519    String Root::getErrorDescription(long errorNumber)
520    {
521
522        // Pass to render system
523        if (mActiveRenderer)
524            return mActiveRenderer->getErrorDescription(errorNumber);
525        else
526            return "";
527
528    }
529        //-----------------------------------------------------------------------
530        void Root::addSceneManagerFactory(SceneManagerFactory* fact)
531        {
532                mSceneManagerEnum->addFactory(fact);
533        }
534        //-----------------------------------------------------------------------
535        void Root::removeSceneManagerFactory(SceneManagerFactory* fact)
536        {
537                mSceneManagerEnum->removeFactory(fact);
538        }
539        //-----------------------------------------------------------------------
540        const SceneManagerMetaData* Root::getSceneManagerMetaData(const String& typeName) const
541        {
542                return mSceneManagerEnum->getMetaData(typeName);
543        }
544        //-----------------------------------------------------------------------
545        SceneManagerEnumerator::MetaDataIterator
546        Root::getSceneManagerMetaDataIterator(void) const
547        {
548                return mSceneManagerEnum->getMetaDataIterator();
549
550        }
551        //-----------------------------------------------------------------------
552        SceneManager* Root::createSceneManager(const String& typeName, 
553                const String& instanceName)
554        {
555                return mSceneManagerEnum->createSceneManager(typeName, instanceName);
556        }
557        //-----------------------------------------------------------------------
558        SceneManager* Root::createSceneManager(SceneTypeMask typeMask, 
559                const String& instanceName)
560        {
561                return mSceneManagerEnum->createSceneManager(typeMask, instanceName);
562        }
563        //-----------------------------------------------------------------------
564        void Root::destroySceneManager(SceneManager* sm)
565        {
566                mSceneManagerEnum->destroySceneManager(sm);
567        }
568        //-----------------------------------------------------------------------
569        SceneManager* Root::getSceneManager(const String& instanceName) const
570        {
571                return mSceneManagerEnum->getSceneManager(instanceName);
572        }
573        //-----------------------------------------------------------------------
574        SceneManagerEnumerator::SceneManagerIterator Root::getSceneManagerIterator(void)
575        {
576                return mSceneManagerEnum->getSceneManagerIterator();
577        }
578    //-----------------------------------------------------------------------
579    TextureManager* Root::getTextureManager(void)
580    {
581        return &TextureManager::getSingleton();
582    }
583    //-----------------------------------------------------------------------
584    MeshManager* Root::getMeshManager(void)
585    {
586        return &MeshManager::getSingleton();
587    }
588    //-----------------------------------------------------------------------
589    void Root::addFrameListener(FrameListener* newListener)
590    {
591                // Check if the specified listener is scheduled for removal
592                std::set<FrameListener *>::iterator i = mRemovedFrameListeners.find(newListener);
593
594                // If yes, cancel the removal. Otherwise add it to other listeners.
595                if (i != mRemovedFrameListeners.end())
596                        mRemovedFrameListeners.erase(*i);
597                else
598                        mFrameListeners.insert(newListener); // Insert, unique only (set)
599    }
600
601    //-----------------------------------------------------------------------
602    void Root::removeFrameListener(FrameListener* oldListener)
603    {
604        // Remove, 1 only (set)
605        mRemovedFrameListeners.insert(oldListener);
606    }
607    //-----------------------------------------------------------------------
608    bool Root::_fireFrameStarted(FrameEvent& evt)
609    {
610        // Increment frame number
611        ++mCurrentFrame;
612
613        // Remove all marked listeners
614        std::set<FrameListener*>::iterator i;
615        for (i = mRemovedFrameListeners.begin();
616            i != mRemovedFrameListeners.end(); i++)
617        {
618            mFrameListeners.erase(*i);
619        }
620        mRemovedFrameListeners.clear();
621
622        // Tell all listeners
623        for (i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i)
624        {
625            if (!(*i)->frameStarted(evt))
626                return false;
627        }
628
629        return true;
630
631    }
632    //-----------------------------------------------------------------------
633    bool Root::_fireFrameEnded(FrameEvent& evt)
634    {
635        // Remove all marked listeners
636        std::set<FrameListener*>::iterator i;
637        for (i = mRemovedFrameListeners.begin();
638            i != mRemovedFrameListeners.end(); i++)
639        {
640            mFrameListeners.erase(*i);
641        }
642        mRemovedFrameListeners.clear();
643
644        // Tell all listeners
645                bool ret = true;
646        for (i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i)
647        {
648            if (!(*i)->frameEnded(evt))
649                        {
650                ret = false;
651                                break;
652                        }
653        }
654
655        // Tell buffer manager to free temp buffers used this frame
656        if (HardwareBufferManager::getSingletonPtr())
657            HardwareBufferManager::getSingleton()._releaseBufferCopies();
658
659                // Also tell the ResourceBackgroundQueue to propagate background load events
660                ResourceBackgroundQueue::getSingleton()._fireBackgroundLoadingComplete();
661
662        return ret;
663    }
664    //-----------------------------------------------------------------------
665    bool Root::_fireFrameStarted()
666    {
667        unsigned long now = mTimer->getMilliseconds();
668        FrameEvent evt;
669        evt.timeSinceLastEvent = calculateEventTime(now, FETT_ANY);
670        evt.timeSinceLastFrame = calculateEventTime(now, FETT_STARTED);
671
672        return _fireFrameStarted(evt);
673    }
674    //-----------------------------------------------------------------------
675    bool Root::_fireFrameEnded()
676    {
677        unsigned long now = mTimer->getMilliseconds();
678        FrameEvent evt;
679        evt.timeSinceLastEvent = calculateEventTime(now, FETT_ANY);
680        evt.timeSinceLastFrame = calculateEventTime(now, FETT_ENDED);
681
682        return _fireFrameEnded(evt);
683    }
684    //-----------------------------------------------------------------------
685    Real Root::calculateEventTime(unsigned long now, FrameEventTimeType type)
686    {
687        // Calculate the average time passed between events of the given type
688        // during the last mFrameSmoothingTime seconds.
689
690        std::deque<unsigned long>& times = mEventTimes[type];
691        times.push_back(now);
692
693        if(times.size() == 1)
694            return 0;
695
696        // Times up to mFrameSmoothingTime seconds old should be kept
697        unsigned long discardThreshold =
698                        static_cast<unsigned long>(mFrameSmoothingTime * 1000.0f);
699
700        // Find the oldest time to keep
701        std::deque<unsigned long>::iterator it = times.begin(),
702            end = times.end()-2; // We need at least two times
703        while(it != end)
704        {
705            if (now - *it > discardThreshold)
706                ++it;
707            else
708                break;
709        }
710
711        // Remove old times
712        times.erase(times.begin(), it);
713
714        return Real(times.back() - times.front()) / ((times.size()-1) * 1000);
715    }
716    //-----------------------------------------------------------------------
717    void Root::queueEndRendering(void)
718    {
719            mQueuedEnd = true;
720    }
721    //-----------------------------------------------------------------------
722    void Root::startRendering(void)
723    {
724        assert(mActiveRenderer != 0);
725
726        mActiveRenderer->_initRenderTargets();
727
728        // Clear event times
729        for(int i=0; i!=3; ++i)
730            mEventTimes[i].clear();
731
732        // Infinite loop, until broken out of by frame listeners
733        // or break out by calling queueEndRendering()
734        mQueuedEnd = false;
735
736        while( !mQueuedEnd )
737        {
738                        //Pump messages in all registered RenderWindow windows
739                        WindowEventUtilities::messagePump();
740
741                        if (!renderOneFrame())
742                break;
743        }
744    }
745    //-----------------------------------------------------------------------
746    bool Root::renderOneFrame(void)
747    {
748        if(!_fireFrameStarted())
749            return false;
750
751        _updateAllRenderTargets();
752
753        return _fireFrameEnded();
754    }
755
756    //-----------------------------------------------------------------------
757    void Root::shutdown(void)
758    {
759                SceneManagerEnumerator::getSingleton().shutdownAll();
760                shutdownPlugins();
761
762        ShadowVolumeExtrudeProgram::shutdown();
763                mResourceBackgroundQueue->shutdown();
764        ResourceGroupManager::getSingleton().shutdownAll();
765
766                // Destroy pools
767                ConvexBody::_destroyPool();
768
769
770                mIsInitialised = false;
771
772                LogManager::getSingleton().logMessage("*-*-* OGRE Shutdown");
773    }
774    //-----------------------------------------------------------------------
775    void Root::loadPlugins( const String& pluginsfile )
776    {
777        StringVector pluginList;
778        String pluginDir;
779        ConfigFile cfg;
780
781                try {
782                cfg.load( pluginsfile );
783                }
784                catch (Exception)
785                {
786                        LogManager::getSingleton().logMessage(pluginsfile + " not found, automatic plugin loading disabled.");
787                        return;
788                }
789
790        pluginDir = cfg.getSetting("PluginFolder"); // Ignored on Mac OS X, uses Resources/ directory
791        pluginList = cfg.getMultiSetting("Plugin");
792
793        char last_char = pluginDir[pluginDir.length()-1];
794        if (last_char != '/' && last_char != '\\')
795        {
796#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
797            pluginDir += "\\";
798#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
799            pluginDir += "/";
800#endif
801        }
802
803        for( StringVector::iterator it = pluginList.begin(); it != pluginList.end(); ++it )
804        {
805                        loadPlugin(pluginDir + (*it));
806        }
807
808    }
809    //-----------------------------------------------------------------------
810        void Root::shutdownPlugins(void)
811        {
812                // NB Shutdown plugins in reverse order to enforce dependencies
813                for (PluginInstanceList::reverse_iterator i = mPlugins.rbegin(); i != mPlugins.rend(); ++i)
814                {
815                        (*i)->shutdown();
816                }
817        }
818        //-----------------------------------------------------------------------
819        void Root::initialisePlugins(void)
820        {
821                for (PluginInstanceList::iterator i = mPlugins.begin(); i != mPlugins.end(); ++i)
822                {
823                        (*i)->initialise();
824                }
825        }
826        //-----------------------------------------------------------------------
827        void Root::unloadPlugins(void)
828    {
829                // unload dynamic libs first
830        for (PluginLibList::reverse_iterator i = mPluginLibs.rbegin(); i != mPluginLibs.rend(); ++i)
831        {
832            // Call plugin shutdown
833            DLL_STOP_PLUGIN pFunc = (DLL_STOP_PLUGIN)(*i)->getSymbol("dllStopPlugin");
834                        // this will call uninstallPlugin
835            pFunc();
836            // Unload library & destroy
837            DynLibManager::getSingleton().unload(*i);
838
839        }
840                mPluginLibs.clear();
841
842                // now deal with any remaining plugins that were registered through other means
843                for (PluginInstanceList::reverse_iterator i = mPlugins.rbegin(); i != mPlugins.rend(); ++i)
844                {
845                        // Note this does NOT call uninstallPlugin - this shutdown is for the
846                        // detail objects
847                        (*i)->uninstall();
848                }
849                mPlugins.clear();
850
851    }
852    //-----------------------------------------------------------------------
853    void Root::addResourceLocation(const String& name, const String& locType,
854                const String& groupName, bool recursive)
855    {
856                ResourceGroupManager::getSingleton().addResourceLocation(
857                        name, locType, groupName, recursive);
858    }
859        //-----------------------------------------------------------------------
860        void Root::removeResourceLocation(const String& name, const String& groupName)
861        {
862                ResourceGroupManager::getSingleton().removeResourceLocation(
863                        name, groupName);
864        }
865    //-----------------------------------------------------------------------
866    void Root::convertColourValue(const ColourValue& colour, uint32* pDest)
867    {
868        assert(mActiveRenderer != 0);
869        mActiveRenderer->convertColourValue(colour, pDest);
870    }
871    //-----------------------------------------------------------------------
872    RenderWindow* Root::getAutoCreatedWindow(void)
873    {
874        return mAutoWindow;
875    }
876    //-----------------------------------------------------------------------
877        RenderWindow* Root::createRenderWindow(const String &name, unsigned int width, unsigned int height,
878                        bool fullScreen, const NameValuePairList *miscParams)
879        {
880        if (!mActiveRenderer)
881        {
882            OGRE_EXCEPT(Exception::ERR_INVALID_STATE,
883            "Cannot create window - no render "
884            "system has been selected.", "Root::createRenderWindow");
885        }
886        RenderWindow* ret;
887        ret = mActiveRenderer->createRenderWindow(name, width, height, fullScreen, miscParams);
888
889        // Initialisation for classes dependent on first window created
890        if(!mFirstTimePostWindowInit)
891        {
892            oneTimePostWindowInit();
893            ret->_setPrimary();
894        }
895
896        return ret;
897
898    }
899    //-----------------------------------------------------------------------
900    void Root::detachRenderTarget(RenderTarget* target)
901    {
902        if (!mActiveRenderer)
903        {
904            OGRE_EXCEPT(Exception::ERR_INVALID_STATE,
905            "Cannot create window - no render "
906            "system has been selected.", "Root::destroyRenderWindow");
907        }
908
909        mActiveRenderer->detachRenderTarget( target->getName() );
910    }
911    //-----------------------------------------------------------------------
912    void Root::detachRenderTarget(const String &name)
913    {
914        if (!mActiveRenderer)
915        {
916            OGRE_EXCEPT(Exception::ERR_INVALID_STATE,
917            "Cannot create window - no render "
918            "system has been selected.", "Root::destroyRenderWindow");
919        }
920
921        mActiveRenderer->detachRenderTarget( name );
922    }
923    //-----------------------------------------------------------------------
924    RenderTarget* Root::getRenderTarget(const String &name)
925    {
926        if (!mActiveRenderer)
927        {
928            OGRE_EXCEPT(Exception::ERR_INVALID_STATE,
929            "Cannot create window - no render "
930            "system has been selected.", "Root::getRenderWindow");
931        }
932
933        return mActiveRenderer->getRenderTarget(name);
934    }
935        //---------------------------------------------------------------------
936        void Root::installPlugin(Plugin* plugin)
937        {
938                LogManager::getSingleton().logMessage("Installing plugin: " + plugin->getName());
939
940                mPlugins.push_back(plugin);
941                plugin->install();
942
943                // if rendersystem is already initialised, call rendersystem init too
944                if (mIsInitialised)
945                {
946                        plugin->initialise();
947                }
948
949                LogManager::getSingleton().logMessage("Plugin successfully installed");
950        }
951        //---------------------------------------------------------------------
952        void Root::uninstallPlugin(Plugin* plugin)
953        {
954                LogManager::getSingleton().logMessage("Uninstalling plugin: " + plugin->getName());
955                PluginInstanceList::iterator i = 
956                        std::find(mPlugins.begin(), mPlugins.end(), plugin);
957                if (i != mPlugins.end())
958                {
959                        if (mIsInitialised)
960                                plugin->shutdown();
961                        plugin->uninstall();
962                        mPlugins.erase(i);
963                }
964                LogManager::getSingleton().logMessage("Plugin successfully uninstalled");
965
966        }
967    //-----------------------------------------------------------------------
968        void Root::loadPlugin(const String& pluginName)
969        {
970                // Load plugin library
971        DynLib* lib = DynLibManager::getSingleton().load( pluginName );
972                // Store for later unload
973                mPluginLibs.push_back(lib);
974
975                // Call startup function
976                DLL_START_PLUGIN pFunc = (DLL_START_PLUGIN)lib->getSymbol("dllStartPlugin");
977
978                if (!pFunc)
979                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot find symbol dllStartPlugin in library " + pluginName,
980                                "Root::loadPlugin");
981
982                // This must call installPlugin
983                pFunc();
984
985        }
986    //-----------------------------------------------------------------------
987        void Root::unloadPlugin(const String& pluginName)
988        {
989        PluginLibList::iterator i;
990
991        for (i = mPluginLibs.begin(); i != mPluginLibs.end(); ++i)
992        {
993                        if ((*i)->getName() == pluginName)
994                        {
995                                // Call plugin shutdown
996                                DLL_STOP_PLUGIN pFunc = (DLL_STOP_PLUGIN)(*i)->getSymbol("dllStopPlugin");
997                                // this must call uninstallPlugin
998                                pFunc();
999                                // Unload library (destroyed by DynLibManager)
1000                                DynLibManager::getSingleton().unload(*i);
1001                                mPluginLibs.erase(i);
1002                                return;
1003                        }
1004
1005        }
1006        }
1007    //-----------------------------------------------------------------------
1008    Timer* Root::getTimer(void)
1009    {
1010        return mTimer;
1011    }
1012    //-----------------------------------------------------------------------
1013    void Root::oneTimePostWindowInit(void)
1014    {
1015        if (!mFirstTimePostWindowInit)
1016        {
1017                        // Background loader
1018                        mResourceBackgroundQueue->initialise();
1019                        // Initialise material manager
1020                        mMaterialManager->initialise();
1021            // Init particle systems manager
1022            mParticleManager->_initialise();
1023                        // Init mesh manager
1024                        MeshManager::getSingleton()._initialise();
1025                        // Init plugins - after window creation so rsys resources available
1026                        initialisePlugins();
1027            mFirstTimePostWindowInit = true;
1028        }
1029
1030    }
1031    //-----------------------------------------------------------------------
1032    void Root::_updateAllRenderTargets(void)
1033    {
1034        // delegate
1035        mActiveRenderer->_updateAllRenderTargets();
1036    }
1037        //-----------------------------------------------------------------------
1038        void Root::clearEventTimes(void)
1039        {
1040                // Clear event times
1041                for(int i=0; i<3; ++i)
1042                        mEventTimes[i].clear();
1043        }
1044        //---------------------------------------------------------------------
1045        void Root::addMovableObjectFactory(MovableObjectFactory* fact,
1046                bool overrideExisting)
1047        {
1048                MovableObjectFactoryMap::iterator facti = mMovableObjectFactoryMap.find(
1049                        fact->getType());
1050                if (!overrideExisting && facti != mMovableObjectFactoryMap.end())
1051                {
1052                        OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM,
1053                                "A factory of type '" + fact->getType() + "' already exists.",
1054                                "Root::addMovableObjectFactory");
1055                }
1056
1057                if (fact->requestTypeFlags())
1058                {
1059                        if (facti != mMovableObjectFactoryMap.end() && facti->second->requestTypeFlags())
1060                        {
1061                                // Copy type flags from the factory we're replacing
1062                                fact->_notifyTypeFlags(facti->second->getTypeFlags());
1063                        }
1064                        else
1065                        {
1066                                // Allocate new
1067                                fact->_notifyTypeFlags(_allocateNextMovableObjectTypeFlag());
1068                        }
1069                }
1070
1071                // Save
1072                mMovableObjectFactoryMap[fact->getType()] = fact;
1073
1074                LogManager::getSingleton().logMessage("MovableObjectFactory for type '" +
1075                        fact->getType() + "' registered.");
1076
1077        }
1078        //---------------------------------------------------------------------
1079        bool Root::hasMovableObjectFactory(const String& typeName) const
1080        {
1081                return !(mMovableObjectFactoryMap.find(typeName) == mMovableObjectFactoryMap.end());
1082        }
1083        //---------------------------------------------------------------------
1084        MovableObjectFactory* Root::getMovableObjectFactory(const String& typeName)
1085        {
1086                MovableObjectFactoryMap::iterator i =
1087                        mMovableObjectFactoryMap.find(typeName);
1088                if (i == mMovableObjectFactoryMap.end())
1089                {
1090                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
1091                                "MovableObjectFactory of type " + typeName + " does not exist",
1092                                "Root::getMovableObjectFactory");
1093                }
1094                return i->second;
1095        }
1096        //---------------------------------------------------------------------
1097        uint32 Root::_allocateNextMovableObjectTypeFlag(void)
1098        {
1099                if (mNextMovableObjectTypeFlag == SceneManager::USER_TYPE_MASK_LIMIT)
1100                {
1101                        OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM,
1102                                "Cannot allocate a type flag since "
1103                                "all the available flags have been used.",
1104                                "Root::_allocateNextMovableObjectTypeFlag");
1105
1106                }
1107                uint32 ret = mNextMovableObjectTypeFlag;
1108                mNextMovableObjectTypeFlag <<= 1;
1109                return ret;
1110
1111        }
1112        //---------------------------------------------------------------------
1113        void Root::removeMovableObjectFactory(MovableObjectFactory* fact)
1114        {
1115                MovableObjectFactoryMap::iterator i = mMovableObjectFactoryMap.find(
1116                        fact->getType());
1117                if (i != mMovableObjectFactoryMap.end())
1118                {
1119                        mMovableObjectFactoryMap.erase(i);
1120                }
1121
1122        }
1123        //---------------------------------------------------------------------
1124        Root::MovableObjectFactoryIterator
1125        Root::getMovableObjectFactoryIterator(void) const
1126        {
1127                return MovableObjectFactoryIterator(mMovableObjectFactoryMap.begin(),
1128                        mMovableObjectFactoryMap.end());
1129
1130        }
1131        //---------------------------------------------------------------------
1132        RenderQueueInvocationSequence* Root::createRenderQueueInvocationSequence(
1133                const String& name)
1134        {
1135                RenderQueueInvocationSequenceMap::iterator i =
1136                        mRQSequenceMap.find(name);
1137                if (i != mRQSequenceMap.end())
1138                {
1139                        OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM,
1140                                "RenderQueueInvocationSequence with the name " + name +
1141                                        " already exists.",
1142                                "Root::createRenderQueueInvocationSequence");
1143                }
1144                RenderQueueInvocationSequence* ret = new RenderQueueInvocationSequence(name);
1145                mRQSequenceMap[name] = ret;
1146                return ret;
1147        }
1148        //---------------------------------------------------------------------
1149        RenderQueueInvocationSequence* Root::getRenderQueueInvocationSequence(
1150                const String& name)
1151        {
1152                RenderQueueInvocationSequenceMap::iterator i =
1153                        mRQSequenceMap.find(name);
1154                if (i == mRQSequenceMap.end())
1155                {
1156                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
1157                                "RenderQueueInvocationSequence with the name " + name +
1158                                " not found.",
1159                                "Root::getRenderQueueInvocationSequence");
1160                }
1161                return i->second;
1162        }
1163        //---------------------------------------------------------------------
1164        void Root::destroyRenderQueueInvocationSequence(
1165                const String& name)
1166        {
1167                RenderQueueInvocationSequenceMap::iterator i =
1168                        mRQSequenceMap.find(name);
1169                if (i != mRQSequenceMap.end())
1170                {
1171                        delete i->second;
1172                        mRQSequenceMap.erase(i);
1173                }
1174        }
1175        //---------------------------------------------------------------------
1176        void Root::destroyAllRenderQueueInvocationSequences(void)
1177        {
1178                for (RenderQueueInvocationSequenceMap::iterator i = mRQSequenceMap.begin();
1179                        i != mRQSequenceMap.end(); ++i)
1180                {
1181                        delete i->second;
1182                }
1183                mRQSequenceMap.clear();
1184        }
1185        //---------------------------------------------------------------------
1186
1187
1188
1189}
Note: See TracBrowser for help on using the repository browser.