From e08f6c9ce3866204fcd6fd5bf3cd83c3c36a2e44 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 6 Mar 2014 04:01:25 +0100 Subject: [PATCH] Bug #416: Copy framebuffer to a texture instead of not clearing Potentially faster than the previous workaround, and should work for triple buffering too. --- apps/openmw/mwgui/loadingscreen.cpp | 35 +++++++++++++++++------------ 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 46c6aebdc..37e29591b 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -86,11 +87,26 @@ namespace MWGui 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(); + mBackgroundImage->setImageTexture(""); + int width = mWindow->getWidth(); + int height = mWindow->getHeight(); + const std::string textureName = "@loading_background"; + Ogre::TexturePtr texture; + texture = Ogre::TextureManager::getSingleton().getByName(textureName); + if (texture.isNull()) + { + texture = Ogre::TextureManager::getSingleton().createManual(textureName, + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Ogre::TEX_TYPE_2D, + width, height, 0, mWindow->suggestPixelFormat(), Ogre::TU_DYNAMIC_WRITE_ONLY); + } + texture->unload(); + texture->setWidth(width); + texture->setHeight(height); + texture->createInternalResources(); + mWindow->copyContentsToMemory(texture->getBuffer()->lock(Ogre::Image::Box(0,0,width,height), Ogre::HardwareBuffer::HBL_DISCARD)); + texture->getBuffer()->unlock(); + mBackgroundImage->setImageTexture(texture->getName()); } setVisible(true); @@ -99,10 +115,6 @@ namespace MWGui { changeWallpaper(); } - else - { - mBackgroundImage->setImageTexture(""); - } MWBase::Environment::get().getWindowManager()->pushGuiMode(mFirstLoad ? GM_LoadingWallpaper : GM_Loading); } @@ -216,8 +228,6 @@ namespace MWGui MWBase::Environment::get().getInputManager()->update(0, true); - mWindow->getViewport(0)->setClearEveryFrame(false); - // First, swap buffers from last draw, then, queue an update of the // window contents, but don't swap buffers (which would have // caused a sync / flush and would be expensive). @@ -227,9 +237,6 @@ namespace MWGui mWindow->update(false); - mWindow->getViewport(0)->setClearEveryFrame(true); - - mRectangle->setVisible(false); // resume 3d rendering