You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw-tes3mp/apps/openmw/mwgui/loadingscreen.cpp

239 lines
8.2 KiB
C++

12 years ago
#include "loadingscreen.hpp"
#include <OgreRenderWindow.h>
12 years ago
#include <OgreCompositorManager.h>
#include <OgreCompositorChain.h>
#include <openengine/ogre/fader.hpp>
12 years ago
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
12 years ago
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/inputmanager.hpp"
12 years ago
namespace MWGui
{
LoadingScreen::LoadingScreen(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* rw)
12 years ago
: mSceneMgr(sceneMgr)
, mWindow(rw)
, WindowBase("openmw_loading_screen.layout")
12 years ago
, mLoadingOn(false)
, mLastRenderTime(0.f)
, mLastWallpaperChangeTime(0.f)
, mFirstLoad(true)
12 years ago
, mTotalRefsLoading(0)
, mCurrentCellLoading(0)
, mTotalCellsLoading(0)
, mCurrentRefLoading(0)
, mCurrentRefList(0)
12 years ago
{
getWidget(mLoadingText, "LoadingText");
getWidget(mProgressBar, "ProgressBar");
12 years ago
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);
12 years ago
}
LoadingScreen::~LoadingScreen()
{
12 years ago
delete mRectangle;
}
void LoadingScreen::onResChange(int w, int h)
{
setCoord(0,0,w,h);
12 years ago
}
void LoadingScreen::setLoadingProgress (const std::string& stage, int depth, int current, int total)
{
if (!mLoadingOn)
loadingOn();
const int numRefLists = 20;
12 years ago
if (depth == 0)
{
mCurrentCellLoading = current;
mTotalCellsLoading = total;
mCurrentRefLoading = 0;
mCurrentRefList = 0;
12 years ago
}
else if (depth == 1)
12 years ago
{
mCurrentRefLoading = current;
mTotalRefsLoading = total;
}
12 years ago
assert (mTotalCellsLoading != 0);
12 years ago
float refProgress;
if (mTotalRefsLoading <= 1)
refProgress = 1;
12 years ago
else
refProgress = float(mCurrentRefLoading) / float(mTotalRefsLoading-1);
refProgress += mCurrentRefList;
refProgress /= numRefLists;
assert(refProgress <= 1 && refProgress >= 0);
if (depth == 1 && mCurrentRefLoading == mTotalRefsLoading-1)
++mCurrentRefList;
12 years ago
float progress = (float(mCurrentCellLoading)+refProgress) / float(mTotalCellsLoading);
assert(progress <= 1 && progress >= 0);
mLoadingText->setCaption(stage);
mProgressBar->setProgressPosition (static_cast<size_t>(progress * 1000));
12 years ago
static float loadingScreenFps = 30.f;
12 years ago
if (mTimer.getMilliseconds () > mLastRenderTime + (1.f/loadingScreenFps) * 1000.f)
12 years ago
{
float dt = mTimer.getMilliseconds () - mLastRenderTime;
12 years ago
mLastRenderTime = mTimer.getMilliseconds ();
if (mFirstLoad && mTimer.getMilliseconds () > mLastWallpaperChangeTime + 3000*1)
{
mLastWallpaperChangeTime = mTimer.getMilliseconds ();
changeWallpaper();
}
12 years ago
// 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)
{
12 years ago
if (i > 0 && i < 96)
12 years ago
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);
12 years ago
12 years ago
Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0));
bool hasCompositor = chain->getCompositor ("gbufferFinalizer");
if (!hasCompositor)
{
mWindow->getViewport(0)->setClearEveryFrame(false);
12 years ago
}
else
{
if (!mFirstLoad)
12 years ago
{
mBackgroundMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(chain->getCompositor ("gbufferFinalizer")->getTextureInstance ("no_mrt_output", 0)->getName());
mRectangle->setVisible(true);
12 years ago
}
12 years ago
for (unsigned int i = 0; i<chain->getNumCompositors(); ++i)
{
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), chain->getCompositor(i)->getCompositor()->getName(), false);
}
}
MWBase::Environment::get().getWorld ()->getFader ()->update (dt);
12 years ago
mWindow->update();
12 years ago
if (!hasCompositor)
mWindow->getViewport(0)->setClearEveryFrame(true);
else
{
for (unsigned int i = 0; i<chain->getNumCompositors(); ++i)
{
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), chain->getCompositor(i)->getCompositor()->getName(), true);
}
}
12 years ago
12 years ago
mRectangle->setVisible(false);
12 years ago
// resume 3d rendering
mSceneMgr->clearSpecialCaseRenderQueues();
mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE);
}
}
12 years ago
void LoadingScreen::loadingDone()
{
loadingOff();
}
12 years ago
void LoadingScreen::loadingOn()
{
setVisible(true);
mLoadingOn = true;
if (mFirstLoad)
{
changeWallpaper();
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_LoadingWallpaper);
}
else
{
mBackgroundImage->setImageTexture("");
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Loading);
}
12 years ago
}
void LoadingScreen::loadingOff()
{
setVisible(false);
mLoadingOn = false;
mFirstLoad = false;
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Loading);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_LoadingWallpaper);
12 years ago
}
void LoadingScreen::changeWallpaper ()
{
if (mResources.empty())
{
Ogre::StringVector groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups ();
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 (rand() % mResources.size());
Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton ().load (randomSplash, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
mBackgroundImage->setImageTexture (randomSplash);
}
else
std::cerr << "No loading screens found!" << std::endl;
}
12 years ago
}