mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-25 11:26:37 +00:00 
			
		
		
		
	Port loading screen
This commit is contained in:
		
							parent
							
								
									92cbc13964
								
							
						
					
					
						commit
						351fd842fd
					
				
					 3 changed files with 77 additions and 96 deletions
				
			
		|  | @ -1,14 +1,6 @@ | ||||||
| #include "loadingscreen.hpp" | #include "loadingscreen.hpp" | ||||||
| 
 | 
 | ||||||
| #include <OgreRenderWindow.h> | #include <osgViewer/Viewer> | ||||||
| #include <OgreMaterialManager.h> |  | ||||||
| #include <OgreTechnique.h> |  | ||||||
| #include <OgreRectangle2D.h> |  | ||||||
| #include <OgreSceneNode.h> |  | ||||||
| #include <OgreTextureManager.h> |  | ||||||
| #include <OgreViewport.h> |  | ||||||
| #include <OgreHardwarePixelBuffer.h> |  | ||||||
| #include <OgreSceneManager.h> |  | ||||||
| 
 | 
 | ||||||
| #include <MyGUI_RenderManager.h> | #include <MyGUI_RenderManager.h> | ||||||
| #include <MyGUI_ScrollBar.h> | #include <MyGUI_ScrollBar.h> | ||||||
|  | @ -18,6 +10,7 @@ | ||||||
| #include <components/misc/rng.hpp> | #include <components/misc/rng.hpp> | ||||||
| 
 | 
 | ||||||
| #include <components/settings/settings.hpp> | #include <components/settings/settings.hpp> | ||||||
|  | #include <components/vfs/manager.hpp> | ||||||
| 
 | 
 | ||||||
| #include "../mwbase/environment.hpp" | #include "../mwbase/environment.hpp" | ||||||
| #include "../mwbase/world.hpp" | #include "../mwbase/world.hpp" | ||||||
|  | @ -26,15 +19,17 @@ | ||||||
| #include "../mwbase/windowmanager.hpp" | #include "../mwbase/windowmanager.hpp" | ||||||
| #include "../mwbase/inputmanager.hpp" | #include "../mwbase/inputmanager.hpp" | ||||||
| 
 | 
 | ||||||
|  | #include "../mwrender/vismask.hpp" | ||||||
|  | 
 | ||||||
| #include "backgroundimage.hpp" | #include "backgroundimage.hpp" | ||||||
| 
 | 
 | ||||||
| namespace MWGui | namespace MWGui | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|     LoadingScreen::LoadingScreen(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* rw) |     LoadingScreen::LoadingScreen(const VFS::Manager* vfs, osgViewer::Viewer* viewer) | ||||||
|         : mSceneMgr(sceneMgr) |         : WindowBase("openmw_loading_screen.layout") | ||||||
|         , mWindow(rw) |         , mVFS(vfs) | ||||||
|         , WindowBase("openmw_loading_screen.layout") |         , mViewer(viewer) | ||||||
|         , mLastRenderTime(0) |         , mLastRenderTime(0) | ||||||
|         , mLastWallpaperChangeTime(0) |         , mLastWallpaperChangeTime(0) | ||||||
|         , mProgress(0) |         , mProgress(0) | ||||||
|  | @ -52,6 +47,32 @@ namespace MWGui | ||||||
|             MyGUI::Align::Stretch, "Menu"); |             MyGUI::Align::Stretch, "Menu"); | ||||||
| 
 | 
 | ||||||
|         setVisible(false); |         setVisible(false); | ||||||
|  | 
 | ||||||
|  |         findSplashScreens(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void LoadingScreen::findSplashScreens() | ||||||
|  |     { | ||||||
|  |         const std::map<std::string, VFS::File*>& index = mVFS->getIndex(); | ||||||
|  |         std::string pattern = "Splash/"; | ||||||
|  |         mVFS->normalizeFilename(pattern); | ||||||
|  | 
 | ||||||
|  |         std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(pattern); | ||||||
|  |         while (found != index.end()) | ||||||
|  |         { | ||||||
|  |             const std::string& name = found->first; | ||||||
|  |             if (name.size() >= pattern.size() && name.substr(0, pattern.size()) == pattern) | ||||||
|  |             { | ||||||
|  |                 size_t pos = name.find_last_of('.'); | ||||||
|  |                 if (pos != std::string::npos && name.compare(pos, name.size()-pos, ".tga") == 0) | ||||||
|  |                     mSplashScreens.push_back(found->first); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |                 break; | ||||||
|  |             ++found; | ||||||
|  |         } | ||||||
|  |         if (mSplashScreens.empty()) | ||||||
|  |             std::cerr << "No splash screens found!" << std::endl; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void LoadingScreen::setLabel(const std::string &label) |     void LoadingScreen::setLabel(const std::string &label) | ||||||
|  | @ -80,17 +101,13 @@ namespace MWGui | ||||||
|         if (mMainWidget->getVisible()) |         if (mMainWidget->getVisible()) | ||||||
|             return; |             return; | ||||||
| 
 | 
 | ||||||
|         // Temporarily turn off VSync, we want to do actual loading rather than waiting for the screen to sync.
 |  | ||||||
|         // Threaded loading would be even better, of course - especially because some drivers force VSync to on and we can't change it.
 |  | ||||||
|         mVSyncWasEnabled = mWindow->isVSyncEnabled(); |  | ||||||
|         mWindow->setVSyncEnabled(false); |  | ||||||
| 
 |  | ||||||
|         bool showWallpaper = (MWBase::Environment::get().getStateManager()->getState() |         bool showWallpaper = (MWBase::Environment::get().getStateManager()->getState() | ||||||
|                 == MWBase::StateManager::State_NoGame); |                 == MWBase::StateManager::State_NoGame); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|         if (!showWallpaper) |         if (!showWallpaper) | ||||||
|         { |         { | ||||||
|  |             // TODO
 | ||||||
|  |             /*
 | ||||||
|             mBackgroundImage->setImageTexture(""); |             mBackgroundImage->setImageTexture(""); | ||||||
|             int width = mWindow->getWidth(); |             int width = mWindow->getWidth(); | ||||||
|             int height = mWindow->getHeight(); |             int height = mWindow->getHeight(); | ||||||
|  | @ -111,6 +128,7 @@ namespace MWGui | ||||||
|             mWindow->copyContentsToMemory(texture->getBuffer()->lock(Ogre::Image::Box(0,0,width,height), Ogre::HardwareBuffer::HBL_DISCARD)); |             mWindow->copyContentsToMemory(texture->getBuffer()->lock(Ogre::Image::Box(0,0,width,height), Ogre::HardwareBuffer::HBL_DISCARD)); | ||||||
|             texture->getBuffer()->unlock(); |             texture->getBuffer()->unlock(); | ||||||
|             mBackgroundImage->setBackgroundImage(texture->getName(), false, false); |             mBackgroundImage->setBackgroundImage(texture->getName(), false, false); | ||||||
|  |             */ | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         setVisible(true); |         setVisible(true); | ||||||
|  | @ -125,9 +143,6 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|     void LoadingScreen::loadingOff() |     void LoadingScreen::loadingOff() | ||||||
|     { |     { | ||||||
|         // Re-enable vsync now.
 |  | ||||||
|         mWindow->setVSyncEnabled(mVSyncWasEnabled); |  | ||||||
| 
 |  | ||||||
|         setVisible(false); |         setVisible(false); | ||||||
| 
 | 
 | ||||||
|         MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Loading); |         MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Loading); | ||||||
|  | @ -136,29 +151,15 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|     void LoadingScreen::changeWallpaper () |     void LoadingScreen::changeWallpaper () | ||||||
|     { |     { | ||||||
|         if (mResources.empty()) |         if (!mSplashScreens.empty()) | ||||||
|         { |         { | ||||||
|             Ogre::StringVector groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups (); |             std::string const & randomSplash = mSplashScreens.at(Misc::Rng::rollDice(mSplashScreens.size())); | ||||||
|             for (Ogre::StringVector::iterator it = groups.begin(); it != groups.end(); ++it) |  | ||||||
|             { |  | ||||||
|                 Ogre::StringVectorPtr resourcesInThisGroup = Ogre::ResourceGroupManager::getSingleton ().findResourceNames (*it, "Splash/*.tga"); |  | ||||||
|                 mResources.insert(mResources.end(), resourcesInThisGroup->begin(), resourcesInThisGroup->end()); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!mResources.empty()) |  | ||||||
|         { |  | ||||||
|             std::string const & randomSplash = mResources.at(Misc::Rng::rollDice(mResources.size())); |  | ||||||
| 
 |  | ||||||
|             Ogre::TextureManager::getSingleton ().load (randomSplash, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); |  | ||||||
| 
 | 
 | ||||||
|             // TODO: add option (filename pattern?) to use image aspect ratio instead of 4:3
 |             // TODO: add option (filename pattern?) to use image aspect ratio instead of 4:3
 | ||||||
|             // we can't do this by default, because the Morrowind splash screens are 1024x1024, but should be displayed as 4:3
 |             // we can't do this by default, because the Morrowind splash screens are 1024x1024, but should be displayed as 4:3
 | ||||||
|             bool stretch = Settings::Manager::getBool("stretch menu background", "GUI"); |             bool stretch = Settings::Manager::getBool("stretch menu background", "GUI"); | ||||||
|             mBackgroundImage->setBackgroundImage(randomSplash, true, stretch); |             mBackgroundImage->setBackgroundImage(randomSplash, true, stretch); | ||||||
|         } |         } | ||||||
|         else |  | ||||||
|             std::cerr << "No loading screens found!" << std::endl; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void LoadingScreen::setProgressRange (size_t range) |     void LoadingScreen::setProgressRange (size_t range) | ||||||
|  | @ -190,7 +191,7 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|     void LoadingScreen::indicateProgress() |     void LoadingScreen::indicateProgress() | ||||||
|     { |     { | ||||||
|         float time = (mTimer.getMilliseconds() % 2001) / 1000.f; |         float time = (static_cast<int>(mTimer.time_m()) % 2001) / 1000.f; | ||||||
|         if (time > 1) |         if (time > 1) | ||||||
|             time = (time-2)*-1; |             time = (time-2)*-1; | ||||||
| 
 | 
 | ||||||
|  | @ -203,43 +204,32 @@ namespace MWGui | ||||||
|     { |     { | ||||||
|         const float loadingScreenFps = 20.f; |         const float loadingScreenFps = 20.f; | ||||||
| 
 | 
 | ||||||
|         if (mTimer.getMilliseconds () > mLastRenderTime + (1.f/loadingScreenFps) * 1000.f) |         if (mTimer.time_m() > mLastRenderTime + (1.f/loadingScreenFps) * 1000.f) | ||||||
|         { |         { | ||||||
|             mLastRenderTime = mTimer.getMilliseconds (); |             mLastRenderTime = mTimer.time_m(); | ||||||
| 
 | 
 | ||||||
|             bool showWallpaper = (MWBase::Environment::get().getStateManager()->getState() |             bool showWallpaper = (MWBase::Environment::get().getStateManager()->getState() | ||||||
|                     == MWBase::StateManager::State_NoGame); |                     == MWBase::StateManager::State_NoGame); | ||||||
| 
 | 
 | ||||||
|             if (showWallpaper && mTimer.getMilliseconds () > mLastWallpaperChangeTime + 5000*1) |             if (showWallpaper && mTimer.time_m() > mLastWallpaperChangeTime + 5000*1) | ||||||
|             { |             { | ||||||
|                 mLastWallpaperChangeTime = mTimer.getMilliseconds (); |                 mLastWallpaperChangeTime = mTimer.time_m(); | ||||||
|                 changeWallpaper(); |                 changeWallpaper(); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Turn off rendering except the GUI
 |             // Turn off rendering except the GUI
 | ||||||
|             mSceneMgr->clearSpecialCaseRenderQueues(); |             int oldUpdateMask = mViewer->getUpdateVisitor()->getTraversalMask(); | ||||||
|             // SCRQM_INCLUDE with RENDER_QUEUE_OVERLAY does not work.
 |             int oldCullMask = mViewer->getCamera()->getCullMask(); | ||||||
|             for (int i = 0; i < Ogre::RENDER_QUEUE_MAX; ++i) |             mViewer->getUpdateVisitor()->setTraversalMask(MWRender::Mask_GUI); | ||||||
|             { |             mViewer->getCamera()->setCullMask(MWRender::Mask_GUI); | ||||||
|                 if (i > 0 && i < 96) |  | ||||||
|                     mSceneMgr->addSpecialCaseRenderQueue(i); |  | ||||||
|             } |  | ||||||
|             mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); |  | ||||||
| 
 | 
 | ||||||
|             MWBase::Environment::get().getInputManager()->update(0, true, true); |             //MWBase::Environment::get().getInputManager()->update(0, true, true);
 | ||||||
| 
 | 
 | ||||||
|             // First, swap buffers from last draw, then, queue an update of the
 |             mViewer->frame(); | ||||||
|             // window contents, but don't swap buffers (which would have
 |  | ||||||
|             // caused a sync / flush and would be expensive).
 |  | ||||||
|             // We're doing this so we can do some actual loading while the GPU is busy with the render.
 |  | ||||||
|             // This means the render is lagging a frame behind, but this is hardly noticable.
 |  | ||||||
|             mWindow->swapBuffers(); |  | ||||||
| 
 |  | ||||||
|             mWindow->update(false); |  | ||||||
| 
 | 
 | ||||||
|             // resume 3d rendering
 |             // resume 3d rendering
 | ||||||
|             mSceneMgr->clearSpecialCaseRenderQueues(); |             mViewer->getUpdateVisitor()->setTraversalMask(oldUpdateMask); | ||||||
|             mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); |             mViewer->getCamera()->setCullMask(oldCullMask); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,16 +1,20 @@ | ||||||
| #ifndef MWGUI_LOADINGSCREEN_H | #ifndef MWGUI_LOADINGSCREEN_H | ||||||
| #define MWGUI_LOADINGSCREEN_H | #define MWGUI_LOADINGSCREEN_H | ||||||
| 
 | 
 | ||||||
| #include <OgreTimer.h> | #include <osg/Timer> | ||||||
| #include <OgreStringVector.h> | #include <osg/ref_ptr> | ||||||
| 
 | 
 | ||||||
| #include "windowbase.hpp" | #include "windowbase.hpp" | ||||||
| 
 | 
 | ||||||
| #include <components/loadinglistener/loadinglistener.hpp> | #include <components/loadinglistener/loadinglistener.hpp> | ||||||
| 
 | 
 | ||||||
| namespace Ogre | namespace osgViewer | ||||||
| { | { | ||||||
|     class SceneManager; |     class Viewer; | ||||||
|  | } | ||||||
|  | namespace VFS | ||||||
|  | { | ||||||
|  |     class Manager; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| namespace MWGui | namespace MWGui | ||||||
|  | @ -20,6 +24,9 @@ namespace MWGui | ||||||
|     class LoadingScreen : public WindowBase, public Loading::Listener |     class LoadingScreen : public WindowBase, public Loading::Listener | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|  |         LoadingScreen(const VFS::Manager* vfs, osgViewer::Viewer* viewer); | ||||||
|  |         virtual ~LoadingScreen(); | ||||||
|  | 
 | ||||||
|         virtual void setLabel (const std::string& label); |         virtual void setLabel (const std::string& label); | ||||||
| 
 | 
 | ||||||
|         /// Indicate that some progress has been made, without specifying how much
 |         /// Indicate that some progress has been made, without specifying how much
 | ||||||
|  | @ -34,21 +41,18 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|         virtual void setVisible(bool visible); |         virtual void setVisible(bool visible); | ||||||
| 
 | 
 | ||||||
|         LoadingScreen(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* rw); |  | ||||||
|         virtual ~LoadingScreen(); |  | ||||||
| 
 |  | ||||||
|         void setLoadingProgress (const std::string& stage, int depth, int current, int total); |         void setLoadingProgress (const std::string& stage, int depth, int current, int total); | ||||||
|         void loadingDone(); |         void loadingDone(); | ||||||
| 
 | 
 | ||||||
|         void updateWindow(Ogre::RenderWindow* rw) { mWindow = rw; } |  | ||||||
| 
 |  | ||||||
|     private: |     private: | ||||||
|         Ogre::SceneManager* mSceneMgr; |         void findSplashScreens(); | ||||||
|         Ogre::RenderWindow* mWindow; | 
 | ||||||
|  |         const VFS::Manager* mVFS; | ||||||
|  |         osg::ref_ptr<osgViewer::Viewer> mViewer; | ||||||
| 
 | 
 | ||||||
|         unsigned long mLastWallpaperChangeTime; |         unsigned long mLastWallpaperChangeTime; | ||||||
|         unsigned long mLastRenderTime; |         unsigned long mLastRenderTime; | ||||||
|         Ogre::Timer mTimer; |         osg::Timer mTimer; | ||||||
| 
 | 
 | ||||||
|         size_t mProgress; |         size_t mProgress; | ||||||
| 
 | 
 | ||||||
|  | @ -58,7 +62,7 @@ namespace MWGui | ||||||
|         MyGUI::ScrollBar* mProgressBar; |         MyGUI::ScrollBar* mProgressBar; | ||||||
|         BackgroundImage* mBackgroundImage; |         BackgroundImage* mBackgroundImage; | ||||||
| 
 | 
 | ||||||
|         Ogre::StringVector mResources; |         std::vector<std::string> mSplashScreens; | ||||||
| 
 | 
 | ||||||
|         bool mVSyncWasEnabled; |         bool mVSyncWasEnabled; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -213,9 +213,9 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|         MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer"); |         MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer"); | ||||||
|         MyGUI::ResourceManager::getInstance().load("core.xml"); |         MyGUI::ResourceManager::getInstance().load("core.xml"); | ||||||
| #if 0 | 
 | ||||||
|         mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow ()); |         mLoadingScreen = new LoadingScreen(mResourceSystem->getVFS(), mViewer); | ||||||
| #endif | 
 | ||||||
|         //set up the hardware cursor manager
 |         //set up the hardware cursor manager
 | ||||||
|         //mCursorManager = new SFO::SDLCursorManager();
 |         //mCursorManager = new SFO::SDLCursorManager();
 | ||||||
| 
 | 
 | ||||||
|  | @ -1173,8 +1173,8 @@ namespace MWGui | ||||||
|         if (!mGuiModes.empty()) |         if (!mGuiModes.empty()) | ||||||
|             mGuiModes.pop_back(); |             mGuiModes.pop_back(); | ||||||
| 
 | 
 | ||||||
|         bool gameMode = !isGuiMode(); |         //bool gameMode = !isGuiMode();
 | ||||||
|         MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode); |         //MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode);
 | ||||||
| 
 | 
 | ||||||
|         updateVisible(); |         updateVisible(); | ||||||
|     } |     } | ||||||
|  | @ -1190,8 +1190,8 @@ namespace MWGui | ||||||
|                 ++it; |                 ++it; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         bool gameMode = !isGuiMode(); |         //bool gameMode = !isGuiMode();
 | ||||||
|         MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode); |         //MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode);
 | ||||||
| 
 | 
 | ||||||
|         updateVisible(); |         updateVisible(); | ||||||
|     } |     } | ||||||
|  | @ -1541,22 +1541,9 @@ namespace MWGui | ||||||
|         mHud->setEnemy(enemy); |         mHud->setEnemy(enemy); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     class DummyListener : public Loading::Listener |  | ||||||
|     { |  | ||||||
|     public: |  | ||||||
|         virtual void setLabel (const std::string& label){} |  | ||||||
|         virtual void loadingOn(){} |  | ||||||
|         virtual void loadingOff(){} |  | ||||||
|         virtual void indicateProgress (){} |  | ||||||
|         virtual void setProgressRange (size_t range){} |  | ||||||
|         virtual void setProgress (size_t value){} |  | ||||||
|         virtual void increaseProgress (size_t increase = 1){} |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     Loading::Listener* WindowManager::getLoadingScreen() |     Loading::Listener* WindowManager::getLoadingScreen() | ||||||
|     { |     { | ||||||
|         static DummyListener listener; |         return mLoadingScreen; | ||||||
|         return &listener; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void WindowManager::startRecharge(MWWorld::Ptr soulgem) |     void WindowManager::startRecharge(MWWorld::Ptr soulgem) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue