From 83b6fcf22e1d6367eec2182958b3821907b5eb52 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 5 Mar 2014 22:24:05 +0100 Subject: [PATCH] Bug #416: Workaround for page flipping problem --- apps/openmw/mwgui/loadingscreen.cpp | 13 +++++++++++++ apps/openmw/mwworld/scene.cpp | 7 ++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 53a45db09..46c6aebdc 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -72,6 +72,10 @@ namespace MWGui void LoadingScreen::loadingOn() { + // Early-out if already on + if (mRectangle->getVisible()) + 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. // In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/ @@ -80,6 +84,15 @@ namespace MWGui mWindow->setVSyncEnabled(false); #endif + if (!mFirstLoad) + { + // When the loading screen is updated, we will disable render target clearing and only draw the loading bar itself. + // But if using page flipping, this can cause jitteriness as it will alternate between the last two rendered frames. + // Even though we attempt to disable vsync above, this may not work if it's forced on the driver level. + // Therefore render the same frame twice before activating the loading bar. + mWindow->update(); + } + setVisible(true); if (mFirstLoad) diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index caae72c13..3d4413a35 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -214,12 +214,13 @@ namespace MWWorld void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) { - mRendering.enableTerrain(true); Nif::NIFFile::CacheLock cachelock; Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen(); Loading::ScopedLoad load(loadingListener); + mRendering.enableTerrain(true); + std::string loadingExteriorText = "#{sLoadingMessage3}"; loadingListener->setLabel(loadingExteriorText); @@ -364,11 +365,11 @@ namespace MWWorld Nif::NIFFile::CacheLock lock; MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.5); - mRendering.enableTerrain(false); - Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen(); Loading::ScopedLoad load(loadingListener); + mRendering.enableTerrain(false); + std::string loadingInteriorText = "#{sLoadingMessage2}"; loadingListener->setLabel(loadingInteriorText);