From f5810b8e1c7416dc5d71cef2ec99cd8fdb70da65 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 30 Mar 2014 23:04:12 +0200 Subject: [PATCH] Consider aspect ratio for loading screen background More consistent with the main menu. --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/backgroundimage.cpp | 63 ++++++++++++++++++++++++ apps/openmw/mwgui/backgroundimage.hpp | 37 ++++++++++++++ apps/openmw/mwgui/loadingscreen.cpp | 47 +++++++----------- apps/openmw/mwgui/loadingscreen.hpp | 9 ++-- apps/openmw/mwgui/mainmenu.cpp | 34 +++---------- apps/openmw/mwgui/mainmenu.hpp | 6 +-- apps/openmw/mwgui/windowmanagerimp.cpp | 2 + files/mygui/openmw_loading_screen.layout | 14 ++---- 9 files changed, 143 insertions(+), 71 deletions(-) create mode 100644 apps/openmw/mwgui/backgroundimage.cpp create mode 100644 apps/openmw/mwgui/backgroundimage.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 511435108..d1f7c45f3 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -33,7 +33,7 @@ add_openmw_dir (mwgui merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog - recharge mode videowidget + recharge mode videowidget backgroundimage ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwgui/backgroundimage.cpp b/apps/openmw/mwgui/backgroundimage.cpp new file mode 100644 index 000000000..1e87c0ff1 --- /dev/null +++ b/apps/openmw/mwgui/backgroundimage.cpp @@ -0,0 +1,63 @@ +#include "backgroundimage.hpp" + +#include + +namespace MWGui +{ + +void BackgroundImage::setBackgroundImage (const std::string& image, bool fixedRatio, bool correct) +{ + if (mChild) + { + MyGUI::Gui::getInstance().destroyWidget(mChild); + mChild = NULL; + } + if (correct) + { + setImageTexture("black.png"); + + if (fixedRatio) + mAspect = 4.0/3.0; + else + mAspect = 0; // TODO + + mChild = createWidgetReal("ImageBox", + MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Default); + mChild->setImageTexture(image); + + adjustSize(); + } + else + { + mAspect = 0; + setImageTexture(image); + } +} + +void BackgroundImage::adjustSize() +{ + if (mAspect == 0) + return; + + MyGUI::IntSize screenSize = getSize(); + + int leftPadding = std::max(0.0, (screenSize.width - screenSize.height * mAspect) / 2); + int topPadding = std::max(0.0, (screenSize.height - screenSize.width / mAspect) / 2); + + mChild->setCoord(leftPadding, topPadding, screenSize.width - leftPadding*2, screenSize.height - topPadding*2); +} + +void BackgroundImage::setSize (const MyGUI::IntSize& _value) +{ + MyGUI::Widget::setSize (_value); + adjustSize(); +} + +void BackgroundImage::setCoord (const MyGUI::IntCoord& _value) +{ + MyGUI::Widget::setCoord (_value); + adjustSize(); +} + + +} diff --git a/apps/openmw/mwgui/backgroundimage.hpp b/apps/openmw/mwgui/backgroundimage.hpp new file mode 100644 index 000000000..3d1a61eaf --- /dev/null +++ b/apps/openmw/mwgui/backgroundimage.hpp @@ -0,0 +1,37 @@ +#ifndef OPENMW_MWGUI_BACKGROUNDIMAGE_H +#define OPENMW_MWGUI_BACKGROUNDIMAGE_H + +#include + +namespace MWGui +{ + + /** + * @brief A variant of MyGUI::ImageBox with aspect ratio correction using black bars + */ + class BackgroundImage : public MyGUI::ImageBox + { + MYGUI_RTTI_DERIVED(BackgroundImage) + + public: + BackgroundImage() : mChild(NULL), mAspect(0) {} + + /** + * @param fixedRatio Use a fixed ratio of 4:3, regardless of the image dimensions + * @param correct Add black bars? + */ + void setBackgroundImage (const std::string& image, bool fixedRatio=true, bool correct=true); + + virtual void setSize (const MyGUI::IntSize &_value); + virtual void setCoord (const MyGUI::IntCoord &_value); + + private: + MyGUI::ImageBox* mChild; + double mAspect; + + void adjustSize(); + }; + +} + +#endif diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index b3f70a5ab..7917c75f3 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -9,14 +9,14 @@ #include #include -#include - #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/inputmanager.hpp" +#include "backgroundimage.hpp" + namespace MWGui { @@ -32,28 +32,13 @@ namespace MWGui { getWidget(mLoadingText, "LoadingText"); getWidget(mProgressBar, "ProgressBar"); - getWidget(mBackgroundImage, "BackgroundImage"); mProgressBar->setScrollViewPage(1); - 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); + mBackgroundImage = MyGUI::Gui::getInstance().createWidgetReal("ImageBox", 0,0,1,1, + MyGUI::Align::Stretch, "Menu"); + + setVisible(false); } void LoadingScreen::setLabel(const std::string &label) @@ -63,18 +48,25 @@ namespace MWGui LoadingScreen::~LoadingScreen() { - delete mRectangle; + } + + void LoadingScreen::setVisible(bool visible) + { + WindowBase::setVisible(visible); + mBackgroundImage->setVisible(visible); } void LoadingScreen::onResChange(int w, int h) { setCoord(0,0,w,h); + + mBackgroundImage->setCoord(MyGUI::IntCoord(0,0,w,h)); } void LoadingScreen::loadingOn() { // Early-out if already on - if (mRectangle->getVisible()) + if (mMainWidget->getVisible()) return; // Temporarily turn off VSync, we want to do actual loading rather than waiting for the screen to sync. @@ -106,7 +98,7 @@ namespace MWGui 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()); + mBackgroundImage->setBackgroundImage(texture->getName(), false, false); } setVisible(true); @@ -149,9 +141,10 @@ namespace MWGui { std::string const & randomSplash = mResources.at (rand() % mResources.size()); - Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton ().load (randomSplash, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + Ogre::TextureManager::getSingleton ().load (randomSplash, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); - mBackgroundImage->setImageTexture (randomSplash); + // TODO: add option (filename pattern?) to use image aspect ratio instead of 4:3 + mBackgroundImage->setBackgroundImage(randomSplash, true, true); } else std::cerr << "No loading screens found!" << std::endl; @@ -237,8 +230,6 @@ namespace MWGui mWindow->update(false); - mRectangle->setVisible(false); - // resume 3d rendering mSceneMgr->clearSpecialCaseRenderQueues(); mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index e91e5951d..55235173f 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -10,6 +10,8 @@ namespace MWGui { + class BackgroundImage; + class LoadingScreen : public WindowBase, public Loading::Listener { public: @@ -25,6 +27,8 @@ namespace MWGui virtual void setProgress (size_t value); virtual void increaseProgress (size_t increase); + virtual void setVisible(bool visible); + virtual void removeWallpaper(); LoadingScreen(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* rw); @@ -51,10 +55,7 @@ namespace MWGui MyGUI::TextBox* mLoadingText; MyGUI::ScrollBar* mProgressBar; - MyGUI::ImageBox* mBackgroundImage; - - Ogre::Rectangle2D* mRectangle; - Ogre::MaterialPtr mBackgroundMaterial; + BackgroundImage* mBackgroundImage; Ogre::StringVector mResources; diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 5257baf22..b6e3915bb 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -14,6 +14,8 @@ #include "savegamedialog.hpp" #include "confirmationdialog.hpp" +#include "imagebutton.hpp" +#include "backgroundimage.hpp" namespace MWGui { @@ -132,34 +134,14 @@ namespace MWGui void MainMenu::showBackground(bool show) { - if (mBackground) - { - MyGUI::Gui::getInstance().destroyWidget(mBackground); - mBackground = NULL; - } - if (show) + if (show && !mBackground) { - if (!mBackground) - { - mBackground = MyGUI::Gui::getInstance().createWidgetReal("ImageBox", 0,0,1,1, - MyGUI::Align::Stretch, "Menu"); - mBackground->setImageTexture("black.png"); - - // Use black bars to correct aspect ratio. The video player also does it, so we need to do it - // for mw_logo.bik to align correctly with menu_morrowind.dds. - MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize(); - - // No way to un-hardcode this right now, menu_morrowind.dds is 1024x512 but was designed for 4:3 - double imageaspect = 4.0/3.0; - - int leftPadding = std::max(0.0, (screenSize.width - screenSize.height * imageaspect) / 2); - int topPadding = std::max(0.0, (screenSize.height - screenSize.width / imageaspect) / 2); - - MyGUI::ImageBox* image = mBackground->createWidget("ImageBox", - leftPadding, topPadding, screenSize.width - leftPadding*2, screenSize.height - topPadding*2, MyGUI::Align::Default); - image->setImageTexture("textures\\menu_morrowind.dds"); - } + mBackground = MyGUI::Gui::getInstance().createWidgetReal("ImageBox", 0,0,1,1, + MyGUI::Align::Stretch, "Menu"); + mBackground->setBackgroundImage("textures\\menu_morrowind.dds"); } + if (mBackground) + mBackground->setVisible(show); } void MainMenu::updateMenu() diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index c571fda86..c27442536 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -3,11 +3,11 @@ #include -#include "imagebutton.hpp" - namespace MWGui { + class ImageButton; + class BackgroundImage; class SaveGameDialog; class MainMenu : public OEngine::GUI::Layout @@ -29,7 +29,7 @@ namespace MWGui MyGUI::Widget* mButtonBox; MyGUI::TextBox* mVersionText; - MyGUI::ImageBox* mBackground; + BackgroundImage* mBackground; std::map mButtons; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 1e019aaa9..db19070a6 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -61,6 +61,7 @@ #include "itemview.hpp" #include "fontloader.hpp" #include "videowidget.hpp" +#include "backgroundimage.hpp" namespace MWGui { @@ -160,6 +161,7 @@ namespace MWGui MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); BookPage::registerMyGUIComponents (); ItemView::registerComponents(); diff --git a/files/mygui/openmw_loading_screen.layout b/files/mygui/openmw_loading_screen.layout index 5fd3440f9..19649cfd2 100644 --- a/files/mygui/openmw_loading_screen.layout +++ b/files/mygui/openmw_loading_screen.layout @@ -4,17 +4,13 @@ - + - - - - - - - - + + + +