From 0330d3d61e911ea1b27ba72b14d4aaf41717dc02 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 7 Jun 2015 21:21:57 +0200 Subject: [PATCH] Restore the "transparent" loading screen --- apps/openmw/mwgui/loadingscreen.cpp | 69 ++++++++++++++++++++--------- apps/openmw/mwgui/loadingscreen.hpp | 11 +++++ 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index f6a9f5ccd..774faa003 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -2,6 +2,8 @@ #include +#include + #include #include #include @@ -9,6 +11,8 @@ #include +#include + #include #include @@ -96,6 +100,28 @@ namespace MWGui mBackgroundImage->setVisible(visible); } + class CopyFramebufferToTextureCallback : public osg::Camera::DrawCallback + { + public: + CopyFramebufferToTextureCallback(osg::Texture2D* texture, int w, int h) + : mTexture(texture), mWidth(w), mHeight(h) + { + } + + virtual void operator () (osg::RenderInfo& renderInfo) const + { + mTexture->copyTexImage2D(*renderInfo.getState(), 0, 0, mWidth, mHeight); + + // Callback removes itself when done + if (renderInfo.getCurrentCamera()) + renderInfo.getCurrentCamera()->setInitialDrawCallback(NULL); + } + + private: + osg::ref_ptr mTexture; + int mWidth, mHeight; + }; + void LoadingScreen::loadingOn() { mLoadingOnTime = mTimer.time_m(); @@ -114,29 +140,30 @@ namespace MWGui if (!showWallpaper) { - // TODO - /* - 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()) + // Copy the current framebuffer onto a texture and display that texture as the background image + // Note, we could also set the camera to disable clearing and have the background image transparent, + // but then we get shaking effects on buffer swaps. + + if (!mTexture) { - 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); + mTexture = new osg::Texture2D; + mTexture->setInternalFormat(GL_RGB); + mTexture->setResizeNonPowerOfTwoHint(false); } - 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->setBackgroundImage(texture->getName(), false, false); - */ + + int width = mViewer->getCamera()->getViewport()->width(); + int height = mViewer->getCamera()->getViewport()->height(); + mViewer->getCamera()->setInitialDrawCallback(new CopyFramebufferToTextureCallback(mTexture, width, height)); + + if (!mGuiTexture.get()) + { + mGuiTexture.reset(new osgMyGUI::OSGTexture(mTexture)); + } + + mBackgroundImage->setBackgroundImage(""); + + mBackgroundImage->setRenderItemTexture(mGuiTexture.get()); + mBackgroundImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 1.f, 1.f, 0.f)); } setVisible(true); diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index baacc7133..194535eee 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -12,6 +12,12 @@ namespace osgViewer { class Viewer; } + +namespace osg +{ + class Texture2D; +} + namespace VFS { class Manager; @@ -67,6 +73,11 @@ namespace MWGui std::vector mSplashScreens; + // TODO: add releaseGLObjects() for mTexture + + osg::ref_ptr mTexture; + std::auto_ptr mGuiTexture; + void changeWallpaper(); void draw();