From 2b339f6c0fd9242cd5bf800e68963acfa3abf479 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 11 Sep 2012 16:37:54 +0200 Subject: [PATCH 1/5] loading screen --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/engine.cpp | 13 ++- apps/openmw/mwbase/inputmanager.hpp | 2 +- apps/openmw/mwbase/windowmanager.hpp | 2 + apps/openmw/mwgui/loadingscreen.cpp | 108 +++++++++++++++++++++++ apps/openmw/mwgui/loadingscreen.hpp | 44 +++++++++ apps/openmw/mwgui/windowmanagerimp.cpp | 11 +++ apps/openmw/mwgui/windowmanagerimp.hpp | 4 + apps/openmw/mwinput/inputmanagerimp.cpp | 5 +- apps/openmw/mwinput/inputmanagerimp.hpp | 2 +- apps/openmw/mwworld/scene.cpp | 68 ++++++++++++++ files/mygui/CMakeLists.txt | 1 + files/mygui/openmw_layers.xml | 1 + files/mygui/openmw_loading_screen.layout | 16 ++++ libs/openengine/gui/manager.cpp | 50 ++++++----- libs/openengine/gui/manager.hpp | 35 +++++--- 16 files changed, 314 insertions(+), 50 deletions(-) create mode 100644 apps/openmw/mwgui/loadingscreen.cpp create mode 100644 apps/openmw/mwgui/loadingscreen.hpp create mode 100644 files/mygui/openmw_loading_screen.layout diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 4cf3bd7fde..cffbc60c71 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -29,7 +29,7 @@ add_openmw_dir (mwgui map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list formatting inventorywindow container hud countdialog tradewindow settingswindow confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu - itemselection spellbuyingwindow + itemselection spellbuyingwindow loadingscreen ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 171fcde7c6..82bd3b69bc 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -67,7 +67,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) mEnvironment.setFrameDuration (evt.timeSinceLastFrame); // update input - MWBase::Environment::get().getInputManager()->update(evt.timeSinceLastFrame); + MWBase::Environment::get().getInputManager()->update(evt.timeSinceLastFrame, false); // sound if (mUseSound) @@ -351,6 +351,11 @@ void OMW::Engine::go() mEnvironment.setJournal (new MWDialogue::Journal); mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions)); + // Sets up the input system + mEnvironment.setInputManager (new MWInput::InputManager (*mOgre, + MWBase::Environment::get().getWorld()->getPlayer(), + *MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser, keybinderUserExists)); + // load cell ESM::Position pos; pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; @@ -370,12 +375,6 @@ void OMW::Engine::go() MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, pos); } - // Sets up the input system - - mEnvironment.setInputManager (new MWInput::InputManager (*mOgre, - MWBase::Environment::get().getWorld()->getPlayer(), - *MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser, keybinderUserExists)); - std::cout << "\nPress Q/ESC or close window to exit.\n"; mOgre->getRoot()->addFrameListener (this); diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index 4245012291..8293cbfa7e 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -22,7 +22,7 @@ namespace MWBase virtual ~InputManager() {} - virtual void update(float dt) = 0; + virtual void update(float dt, bool loading) = 0; virtual void changeInputMode(bool guiMode) = 0; diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 14b1051e84..bd8b7eb181 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -216,6 +216,8 @@ namespace MWBase virtual void processChangedSettings(const Settings::CategorySettingVector& changed) = 0; virtual void executeInConsole (const std::string& path) = 0; + + virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total) = 0; }; } diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp new file mode 100644 index 0000000000..efda76caa0 --- /dev/null +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -0,0 +1,108 @@ +#include "loadingscreen.hpp" + +#include +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" + +namespace MWGui +{ + + LoadingScreen::LoadingScreen(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* rw, MWBase::WindowManager& parWindowManager) + : mSceneMgr(sceneMgr) + , mWindow(rw) + , WindowBase("openmw_loading_screen.layout", parWindowManager) + , mLoadingOn(false) + , mLastRenderTime(0.f) + { + getWidget(mLoadingText, "LoadingText"); + } + + LoadingScreen::~LoadingScreen() + { + } + + void LoadingScreen::setLoadingProgress (const std::string& stage, int depth, int current, int total) + { + if (!mLoadingOn) + loadingOn(); + + if (depth == 0) + { + mCurrentCellLoading = current; + mTotalCellsLoading = total; + + mCurrentRefLoading = 0; + + } + if (depth == 1) + { + mCurrentRefLoading = current; + mTotalRefsLoading = total; + } + + if (mTotalCellsLoading == 0) + { + loadingOff(); + return; + } + + float refProgress; + if (mTotalRefsLoading <= 1) + refProgress = 0; + else + refProgress = float(mCurrentRefLoading) / float(mTotalRefsLoading-1); + + float progress = (float(mCurrentCellLoading)+refProgress) / float(mTotalCellsLoading); + assert(progress <= 1 && progress >= 0); + if (progress >= 1) + { + loadingOff(); + return; + } + + mLoadingText->setCaption(stage + "... " + Ogre::StringConverter::toString(progress)); + + static float loadingScreenFps = 40.f; + + //if (mTimer.getMilliseconds () > mLastRenderTime + (1.f/loadingScreenFps) * 1000.f) + { + mLastRenderTime = mTimer.getMilliseconds (); + + + // Turn off rendering except the GUI + mSceneMgr->clearSpecialCaseRenderQueues(); + // SCRQM_INCLUDE with RENDER_QUEUE_OVERLAY does not work. + for (int i = 0; i < Ogre::RENDER_QUEUE_MAX; ++i) + { + if (i > 10 && i < 90) + mSceneMgr->addSpecialCaseRenderQueue(i); + } + mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); + + // always update input before rendering something, otherwise mygui goes crazy when something was entered in the frame before + // (e.g. when using "coc" console command, it would enter an infinite loop and crash due to overflow) + MWBase::Environment::get().getInputManager()->update(0, true); + + mWindow->update(); + + // resume 3d rendering + mSceneMgr->clearSpecialCaseRenderQueues(); + mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); + } + } + + void LoadingScreen::loadingOn() + { + setVisible(true); + mLoadingOn = true; + } + + + void LoadingScreen::loadingOff() + { + setVisible(false); + mLoadingOn = false; + } +} diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp new file mode 100644 index 0000000000..199bde3726 --- /dev/null +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -0,0 +1,44 @@ +#ifndef MWGUI_LOADINGSCREEN_H +#define MWGUI_LOADINGSCREEN_H + +#include +#include + +#include "window_base.hpp" + +namespace MWGui +{ + + class LoadingScreen : public WindowBase + { + public: + LoadingScreen(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* rw, MWBase::WindowManager& parWindowManager); + virtual ~LoadingScreen(); + + void setLoadingProgress (const std::string& stage, int depth, int current, int total); + + private: + Ogre::SceneManager* mSceneMgr; + Ogre::RenderWindow* mWindow; + + unsigned long mLastRenderTime; + Ogre::Timer mTimer; + + MyGUI::TextBox* mLoadingText; + + int mCurrentCellLoading; + int mTotalCellsLoading; + int mCurrentRefLoading; + int mTotalRefsLoading; + + + bool mLoadingOn; + + void loadingOn(); + void loadingOff(); + }; + +} + + +#endif diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 02718f365b..196e898b09 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -43,6 +43,7 @@ #include "alchemywindow.hpp" #include "spellwindow.hpp" #include "quickkeysmenu.hpp" +#include "loadingscreen.hpp" using namespace MWGui; @@ -67,6 +68,7 @@ WindowManager::WindowManager( , mConfirmationDialog(NULL) , mAlchemyWindow(NULL) , mSpellWindow(NULL) + , mLoadingScreen(NULL) , mCharGen(NULL) , mPlayerClass() , mPlayerName() @@ -146,6 +148,9 @@ WindowManager::WindowManager( mSpellWindow = new SpellWindow(*this); mQuickKeysMenu = new QuickKeysMenu(*this); + mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this); + mLoadingScreen->setCoord (0,0,w,h); + mInputBlocker = mGui->createWidget("",0,0,w,h,MyGUI::Align::Default,"Windows",""); // The HUD is always on @@ -679,6 +684,7 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector mBookWindow->center(); mQuickKeysMenu->center(); mSpellBuyingWindow->center(); + mLoadingScreen->setCoord (0,0,x,y); mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y)); mInputBlocker->setSize(MyGUI::IntSize(x,y)); } @@ -897,3 +903,8 @@ void WindowManager::toggleHud () mHudEnabled = !mHudEnabled; mHud->setVisible (mHudEnabled); } + +void WindowManager::setLoadingProgress (const std::string& stage, int depth, int current, int total) +{ + mLoadingScreen->setLoadingProgress (stage, depth, current, total); +} diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index a91478bbc2..5327bb8689 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -61,6 +61,7 @@ namespace MWGui class SettingsWindow; class AlchemyWindow; class QuickKeysMenu; + class LoadingScreen; class WindowManager : public MWBase::WindowManager { @@ -195,6 +196,8 @@ namespace MWGui virtual void executeInConsole (const std::string& path); + virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total); + private: OEngine::GUI::MyGUIManager *mGuiManager; HUD *mHud; @@ -219,6 +222,7 @@ namespace MWGui AlchemyWindow* mAlchemyWindow; SpellWindow* mSpellWindow; QuickKeysMenu* mQuickKeysMenu; + LoadingScreen* mLoadingScreen; CharacterCreation* mCharGen; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 022d7df3c1..b198785d2f 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -233,14 +233,15 @@ namespace MWInput } } - void InputManager::update(float dt) + void InputManager::update(float dt, bool loading) { // Tell OIS to handle all input events mKeyboard->capture(); mMouse->capture(); // update values of channels (as a result of pressed keys) - mInputCtrl->update(dt); + if (!loading) + mInputCtrl->update(dt); // Update windows/gui as a result of input events // For instance this could mean opening a new window/dialog, diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 9963c73c21..7d03f1d5bf 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -66,7 +66,7 @@ namespace MWInput virtual ~InputManager(); - virtual void update(float dt); + virtual void update(float dt, bool loading); virtual void changeInputMode(bool guiMode); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index eb03e9a7bd..bcf4a2002d 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -25,9 +25,14 @@ namespace const MWWorld::Class& class_ = MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.list.begin(), &cell)); + int numRefs = cellRefList.list.size(); + int current = 0; for (typename T::List::iterator it = cellRefList.list.begin(); it != cellRefList.list.end(); it++) { + MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 1, current, numRefs); + ++current; + if (it->mData.getCount() || it->mData.isEnabled()) { MWWorld::Ptr ptr (&*it, &cell); @@ -175,6 +180,26 @@ namespace MWWorld CellStoreCollection::iterator active = mActiveCells.begin(); + // get the number of cells to unload + int numUnload = 0; + while (active!=mActiveCells.end()) + { + if (!((*active)->cell->data.flags & ESM::Cell::Interior)) + { + if (std::abs (X-(*active)->cell->data.gridX)<=1 && + std::abs (Y-(*active)->cell->data.gridY)<=1) + { + // keep cells within the new 3x3 grid + ++active; + continue; + } + } + ++active; + ++numUnload; + } + + int current = 0; + active = mActiveCells.begin(); while (active!=mActiveCells.end()) { if (!((*active)->cell->data.flags & ESM::Cell::Interior)) @@ -188,10 +213,35 @@ namespace MWWorld } } + MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload); unloadCell (active++); + ++current; } + int numLoad = 0; + // get the number of cells to load + for (int x=X-1; x<=X+1; ++x) + for (int y=Y-1; y<=Y+1; ++y) + { + CellStoreCollection::iterator iter = mActiveCells.begin(); + + while (iter!=mActiveCells.end()) + { + assert (!((*iter)->cell->data.flags & ESM::Cell::Interior)); + + if (x==(*iter)->cell->data.gridX && + y==(*iter)->cell->data.gridY) + break; + + ++iter; + } + + if (iter==mActiveCells.end()) + ++numLoad; + } + // Load cells + current = 0; for (int x=X-1; x<=X+1; ++x) for (int y=Y-1; y<=Y+1; ++y) { @@ -212,7 +262,9 @@ namespace MWWorld { CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(x, y); + MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 0, current, numLoad); loadCell (cell); + ++current; } } @@ -275,14 +327,30 @@ namespace MWWorld // remove active CellStoreCollection::iterator active = mActiveCells.begin(); + // count number of cells to unload + int numUnload = 0; while (active!=mActiveCells.end()) { + ++active; + ++numUnload; + } + + // unload + int current = 0; + active = mActiveCells.begin(); + while (active!=mActiveCells.end()) + { + MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload); + unloadCell (active++); + ++current; } // Load cell. std::cout << "cellName:" << cellName << std::endl; + + MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 0, 0, 1); loadCell (cell); // adjust player diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index 82fb64c76d..fdf447e690 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -71,6 +71,7 @@ set(MYGUI_FILES openmw_itemselection_dialog.layout openmw_magicselection_dialog.layout openmw_spell_buying_window.layout + openmw_loading_screen.layout smallbars.png VeraMono.ttf markers.png diff --git a/files/mygui/openmw_layers.xml b/files/mygui/openmw_layers.xml index 7a8d586d2e..33a3ca40c7 100644 --- a/files/mygui/openmw_layers.xml +++ b/files/mygui/openmw_layers.xml @@ -8,5 +8,6 @@ + diff --git a/files/mygui/openmw_loading_screen.layout b/files/mygui/openmw_loading_screen.layout new file mode 100644 index 0000000000..1b99c91bdc --- /dev/null +++ b/files/mygui/openmw_loading_screen.layout @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/libs/openengine/gui/manager.cpp b/libs/openengine/gui/manager.cpp index 58929ba8b5..acb4ed9df7 100644 --- a/libs/openengine/gui/manager.cpp +++ b/libs/openengine/gui/manager.cpp @@ -8,41 +8,43 @@ using namespace OEngine::GUI; void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging, const std::string& logDir) { - assert(wnd); - assert(mgr); + assert(wnd); + assert(mgr); - using namespace MyGUI; + mSceneMgr = mgr; - // Enable/disable MyGUI logging to stdout. (Logging to MyGUI.log is - // still enabled.) In order to do this we have to initialize the log - // manager before the main gui system itself, otherwise the main - // object will get the chance to spit out a few messages before we - // can able to disable it. + using namespace MyGUI; - std::string theLogFile = std::string(MYGUI_PLATFORM_LOG_FILENAME); - if(!logDir.empty()) - theLogFile.insert(0, logDir); + // Enable/disable MyGUI logging to stdout. (Logging to MyGUI.log is + // still enabled.) In order to do this we have to initialize the log + // manager before the main gui system itself, otherwise the main + // object will get the chance to spit out a few messages before we + // can able to disable it. - // Set up OGRE platform. We might make this more generic later. - mPlatform = new OgrePlatform(); - LogManager::getInstance().setSTDOutputEnabled(logging); - mPlatform->initialise(wnd, mgr, "General", theLogFile); + std::string theLogFile = std::string(MYGUI_PLATFORM_LOG_FILENAME); + if(!logDir.empty()) + theLogFile.insert(0, logDir); + + // Set up OGRE platform. We might make this more generic later. + mPlatform = new OgrePlatform(); + LogManager::getInstance().setSTDOutputEnabled(logging); + mPlatform->initialise(wnd, mgr, "General", theLogFile); - // Create GUI - mGui = new Gui(); - mGui->initialise("core.xml"); + // Create GUI + mGui = new Gui(); + mGui->initialise("core.xml"); } void MyGUIManager::shutdown() { mGui->shutdown (); - delete mGui; - if(mPlatform) + delete mGui; + if(mPlatform) { - mPlatform->shutdown(); - delete mPlatform; + mPlatform->shutdown(); + delete mPlatform; } - mGui = NULL; - mPlatform = NULL; + mGui = NULL; + mPlatform = NULL; } diff --git a/libs/openengine/gui/manager.hpp b/libs/openengine/gui/manager.hpp index 781685acfe..1ec2e2fcf3 100644 --- a/libs/openengine/gui/manager.hpp +++ b/libs/openengine/gui/manager.hpp @@ -16,21 +16,28 @@ namespace Ogre namespace OEngine { namespace GUI { - class MyGUIManager - { - MyGUI::OgrePlatform *mPlatform; - MyGUI::Gui *mGui; + class MyGUIManager + { + MyGUI::OgrePlatform *mPlatform; + MyGUI::Gui *mGui; + Ogre::SceneManager* mSceneMgr; - public: - MyGUIManager() : mPlatform(NULL), mGui(NULL) {} - MyGUIManager(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging=false, const std::string& logDir = std::string("")) - { setup(wnd,mgr,logging, logDir); } - ~MyGUIManager() { shutdown(); } + public: + MyGUIManager() : mPlatform(NULL), mGui(NULL) {} + MyGUIManager(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging=false, const std::string& logDir = std::string("")) + { + setup(wnd,mgr,logging, logDir); + } + ~MyGUIManager() + { + shutdown(); + } - void setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging=false, const std::string& logDir = std::string("")); - void shutdown(); + void setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging=false, const std::string& logDir = std::string("")); + void shutdown(); - MyGUI::Gui *getGui() { return mGui; } - }; -}} + MyGUI::Gui *getGui() { return mGui; } + }; +} +} #endif From 369db182deb613835966ed6ab0cc47817df980fe Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 11 Sep 2012 16:53:49 +0200 Subject: [PATCH 2/5] actual progress bar, performance optimization --- apps/openmw/mwgui/loadingscreen.cpp | 12 +++++++----- apps/openmw/mwgui/loadingscreen.hpp | 1 + files/mygui/openmw_loading_screen.layout | 7 +++++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index efda76caa0..79cbd4752e 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -17,6 +17,7 @@ namespace MWGui , mLastRenderTime(0.f) { getWidget(mLoadingText, "LoadingText"); + getWidget(mProgressBar, "ProgressBar"); } LoadingScreen::~LoadingScreen() @@ -50,10 +51,10 @@ namespace MWGui float refProgress; if (mTotalRefsLoading <= 1) - refProgress = 0; + refProgress = 1; else refProgress = float(mCurrentRefLoading) / float(mTotalRefsLoading-1); - +std::cout << refProgress << " (" << mCurrentRefLoading << ", " << mTotalRefsLoading-1 << std::endl; float progress = (float(mCurrentCellLoading)+refProgress) / float(mTotalCellsLoading); assert(progress <= 1 && progress >= 0); if (progress >= 1) @@ -62,11 +63,12 @@ namespace MWGui return; } - mLoadingText->setCaption(stage + "... " + Ogre::StringConverter::toString(progress)); + mLoadingText->setCaption(stage + "... "); + mProgressBar->setProgressPosition (static_cast(progress * 1000)); - static float loadingScreenFps = 40.f; + static float loadingScreenFps = 30.f; - //if (mTimer.getMilliseconds () > mLastRenderTime + (1.f/loadingScreenFps) * 1000.f) + if (mTimer.getMilliseconds () > mLastRenderTime + (1.f/loadingScreenFps) * 1000.f) { mLastRenderTime = mTimer.getMilliseconds (); diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index 199bde3726..ec01714f82 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -25,6 +25,7 @@ namespace MWGui Ogre::Timer mTimer; MyGUI::TextBox* mLoadingText; + MyGUI::ProgressBar* mProgressBar; int mCurrentCellLoading; int mTotalCellsLoading; diff --git a/files/mygui/openmw_loading_screen.layout b/files/mygui/openmw_loading_screen.layout index 1b99c91bdc..7096115f63 100644 --- a/files/mygui/openmw_loading_screen.layout +++ b/files/mygui/openmw_loading_screen.layout @@ -6,8 +6,11 @@ - - + + + + + From d5a08e31e7548b8fc6798fc1552152fe5b552902 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 11 Sep 2012 17:36:20 +0200 Subject: [PATCH 3/5] scene does not disappear anymore during load --- apps/openmw/mwgui/loadingscreen.cpp | 19 +++++++++++++++---- apps/openmw/mwgui/loadingscreen.hpp | 1 + apps/openmw/mwworld/scene.cpp | 4 ++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 79cbd4752e..848cc1c719 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -29,15 +29,17 @@ namespace MWGui if (!mLoadingOn) loadingOn(); + const int numRefLists = 20; + if (depth == 0) { mCurrentCellLoading = current; mTotalCellsLoading = total; mCurrentRefLoading = 0; - + mCurrentRefList = 0; } - if (depth == 1) + else if (depth == 1) { mCurrentRefLoading = current; mTotalRefsLoading = total; @@ -54,7 +56,14 @@ namespace MWGui refProgress = 1; else refProgress = float(mCurrentRefLoading) / float(mTotalRefsLoading-1); -std::cout << refProgress << " (" << mCurrentRefLoading << ", " << mTotalRefsLoading-1 << std::endl; + refProgress += mCurrentRefList; + refProgress /= numRefLists; + + assert(refProgress <= 1 && refProgress >= 0); + + if (depth == 1 && mCurrentRefLoading == mTotalRefsLoading-1) + ++mCurrentRefList; + float progress = (float(mCurrentCellLoading)+refProgress) / float(mTotalCellsLoading); assert(progress <= 1 && progress >= 0); if (progress >= 1) @@ -78,7 +87,7 @@ std::cout << refProgress << " (" << mCurrentRefLoading << ", " << mTotalRefsLoa // SCRQM_INCLUDE with RENDER_QUEUE_OVERLAY does not work. for (int i = 0; i < Ogre::RENDER_QUEUE_MAX; ++i) { - if (i > 10 && i < 90) + if (i > 0 && i < 90) mSceneMgr->addSpecialCaseRenderQueue(i); } mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); @@ -87,7 +96,9 @@ std::cout << refProgress << " (" << mCurrentRefLoading << ", " << mTotalRefsLoa // (e.g. when using "coc" console command, it would enter an infinite loop and crash due to overflow) MWBase::Environment::get().getInputManager()->update(0, true); + mWindow->getViewport(0)->setClearEveryFrame(false); mWindow->update(); + mWindow->getViewport(0)->setClearEveryFrame(true); // resume 3d rendering mSceneMgr->clearSpecialCaseRenderQueues(); diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index ec01714f82..2256bca6b1 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -31,6 +31,7 @@ namespace MWGui int mTotalCellsLoading; int mCurrentRefLoading; int mTotalRefsLoading; + int mCurrentRefList; bool mLoadingOn; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index bcf4a2002d..c3843b831c 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -50,6 +50,10 @@ namespace } } } + else + { + MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 1, 0, 1); + } } } From a8d9aa98b1be801e5f67b0553067f4438299f983 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 11 Sep 2012 19:18:26 +0200 Subject: [PATCH 4/5] some fixes --- apps/openmw/mwgui/loadingscreen.cpp | 67 ++++++++++++++++++++++- apps/openmw/mwgui/loadingscreen.hpp | 7 ++- apps/openmw/mwgui/windowmanagerimp.cpp | 4 +- apps/openmw/mwrender/renderingmanager.cpp | 1 + files/mygui/openmw_loading_screen.layout | 14 +++-- 5 files changed, 82 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 848cc1c719..d93cc50c36 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -2,6 +2,11 @@ #include #include +#include +#include +#include + + #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" @@ -18,10 +23,37 @@ namespace MWGui { getWidget(mLoadingText, "LoadingText"); getWidget(mProgressBar, "ProgressBar"); + getWidget(mBackgroundImage, "BackgroundImage"); + + + mBackgroundMaterial = Ogre::MaterialManager::getSingleton().create("BackgroundMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + mBackgroundMaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false); + mBackgroundMaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); + mBackgroundMaterial->getTechnique(0)->getPass(0)->createTextureUnitState(""); + + mRectangle = new Ogre::Rectangle2D(true); + mRectangle->setCorners(-1.0, 1.0, 1.0, -1.0); + mRectangle->setMaterial("BackgroundMaterial"); + // Render the background before everything else + mRectangle->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY-1); + // Use infinite AAB to always stay visible + Ogre::AxisAlignedBox aabInf; + aabInf.setInfinite(); + mRectangle->setBoundingBox(aabInf); + // Attach background to the scene + Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + node->attachObject(mRectangle); + mRectangle->setVisible(false); } LoadingScreen::~LoadingScreen() { + delete mRectangle; + } + + void LoadingScreen::onResChange(int w, int h) + { + setCoord(0,0,w,h); } void LoadingScreen::setLoadingProgress (const std::string& stage, int depth, int current, int total) @@ -87,7 +119,7 @@ namespace MWGui // SCRQM_INCLUDE with RENDER_QUEUE_OVERLAY does not work. for (int i = 0; i < Ogre::RENDER_QUEUE_MAX; ++i) { - if (i > 0 && i < 90) + if (i > 0 && i < 96) mSceneMgr->addSpecialCaseRenderQueue(i); } mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); @@ -96,9 +128,38 @@ namespace MWGui // (e.g. when using "coc" console command, it would enter an infinite loop and crash due to overflow) MWBase::Environment::get().getInputManager()->update(0, true); - mWindow->getViewport(0)->setClearEveryFrame(false); + Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0)); + + bool hasCompositor = chain->getCompositor ("gbufferFinalizer"); + + + if (!hasCompositor) + { + mWindow->getViewport(0)->setClearEveryFrame(false); + } + else + { + mBackgroundMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(chain->getCompositor ("gbufferFinalizer")->getTextureInstance ("no_mrt_output", 0)->getName()); + mRectangle->setVisible(true); + + for (unsigned int i = 0; igetNumCompositors(); ++i) + { + Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), chain->getCompositor(i)->getCompositor()->getName(), false); + } + } + mWindow->update(); - mWindow->getViewport(0)->setClearEveryFrame(true); + + if (!hasCompositor) + mWindow->getViewport(0)->setClearEveryFrame(true); + else + { + for (unsigned int i = 0; igetNumCompositors(); ++i) + { + Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), chain->getCompositor(i)->getCompositor()->getName(), true); + } + mRectangle->setVisible(false); + } // resume 3d rendering mSceneMgr->clearSpecialCaseRenderQueues(); diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index 2256bca6b1..abd59db499 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -8,7 +8,6 @@ namespace MWGui { - class LoadingScreen : public WindowBase { public: @@ -17,6 +16,8 @@ namespace MWGui void setLoadingProgress (const std::string& stage, int depth, int current, int total); + void onResChange(int w, int h); + private: Ogre::SceneManager* mSceneMgr; Ogre::RenderWindow* mWindow; @@ -26,6 +27,7 @@ namespace MWGui MyGUI::TextBox* mLoadingText; MyGUI::ProgressBar* mProgressBar; + MyGUI::ImageBox* mBackgroundImage; int mCurrentCellLoading; int mTotalCellsLoading; @@ -33,6 +35,9 @@ namespace MWGui int mTotalRefsLoading; int mCurrentRefList; + Ogre::Rectangle2D* mRectangle; + Ogre::MaterialPtr mBackgroundMaterial; + bool mLoadingOn; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 196e898b09..8d12950a0b 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -149,7 +149,7 @@ WindowManager::WindowManager( mQuickKeysMenu = new QuickKeysMenu(*this); mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this); - mLoadingScreen->setCoord (0,0,w,h); + mLoadingScreen->onResChange (w,h); mInputBlocker = mGui->createWidget("",0,0,w,h,MyGUI::Align::Default,"Windows",""); @@ -684,7 +684,7 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector mBookWindow->center(); mQuickKeysMenu->center(); mSpellBuyingWindow->center(); - mLoadingScreen->setCoord (0,0,x,y); + mLoadingScreen->onResChange (x,y); mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y)); mInputBlocker->setSize(MyGUI::IntSize(x,y)); } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index e983353cb0..70d7de5529 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -734,6 +734,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false"); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); mObjects.rebuildStaticGeometry (); + mRendering.getViewport ()->setClearEveryFrame (true); } else if (it->second == "underwater effect" && it->first == "Water") { diff --git a/files/mygui/openmw_loading_screen.layout b/files/mygui/openmw_loading_screen.layout index 7096115f63..6862702ca1 100644 --- a/files/mygui/openmw_loading_screen.layout +++ b/files/mygui/openmw_loading_screen.layout @@ -4,13 +4,17 @@ - + - - + + + + + + + + - - From e9e30c0fce60482cc11f46c5021e383dd26e6565 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 11 Sep 2012 20:34:54 +0200 Subject: [PATCH 5/5] fixed a memory leak --- apps/openmw/mwgui/windowmanagerimp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 8d12950a0b..b29980b215 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -199,6 +199,7 @@ WindowManager::~WindowManager() delete mConfirmationDialog; delete mAlchemyWindow; delete mSpellWindow; + delete mLoadingScreen; cleanupGarbage();