From 49df07ea7f34c0aa952f53311bcc5e0c71198f1d Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 15 May 2015 00:41:21 +0200 Subject: [PATCH] Implement UI scaling factor --- apps/openmw/mwgui/windowbase.cpp | 7 +-- apps/openmw/mwgui/windowmanagerimp.cpp | 10 +++- apps/openmw/mwinput/inputmanagerimp.cpp | 56 +++++++++---------- apps/openmw/mwinput/inputmanagerimp.hpp | 8 ++- components/myguiplatform/myguiplatform.hpp | 4 +- .../myguiplatform/myguirendermanager.cpp | 40 ++----------- .../myguiplatform/myguirendermanager.hpp | 6 +- components/myguiplatform/myguitexture.cpp | 2 +- files/settings-default.cfg | 2 + 9 files changed, 61 insertions(+), 74 deletions(-) diff --git a/apps/openmw/mwgui/windowbase.cpp b/apps/openmw/mwgui/windowbase.cpp index 8fdcf6b20..c3be3539e 100644 --- a/apps/openmw/mwgui/windowbase.cpp +++ b/apps/openmw/mwgui/windowbase.cpp @@ -1,6 +1,7 @@ #include "windowbase.hpp" #include +#include #include @@ -48,11 +49,7 @@ void WindowBase::center() { // Centre dialog - // MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize(); - // Note by scrawl: The following works more reliably in the case when the window was _just_ - // resized and MyGUI RenderManager doesn't know about the new size yet - MyGUI::IntSize gameWindowSize = MyGUI::IntSize(Settings::Manager::getInt("resolution x", "Video"), - Settings::Manager::getInt("resolution y", "Video")); + MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize(); MyGUI::IntCoord coord = mMainWidget->getCoord(); coord.left = (gameWindowSize.width - coord.width)/2; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 3bedb5d5e..aef37809b 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -182,7 +182,8 @@ namespace MWGui , mFPS(0.0f) , mFallbackMap(fallbackMap) { - mGuiPlatform = new osgMyGUI::Platform(viewer, guiRoot, resourceSystem->getTextureManager()); + float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); + mGuiPlatform = new osgMyGUI::Platform(viewer, guiRoot, resourceSystem->getTextureManager(), uiScale); mGuiPlatform->initialise(resourcePath, logpath); mGui = new MyGUI::Gui; @@ -1104,6 +1105,13 @@ namespace MWGui void WindowManager::windowResized(int x, int y) { + mGuiPlatform->getRenderManagerPtr()->setViewSize(x, y); + + // scaled size + const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); + x = viewSize.width; + y = viewSize.height; + sizeVideo(x, y); if (!mHud) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 6abd3c0c9..7a3dd5e18 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -123,8 +123,8 @@ namespace MWInput , mGuiCursorEnabled(true) , mDetectingKeyboard(false) , mOverencumberedMessageDelay(0.f) - , mMouseX(0) - , mMouseY(0) + , mGuiCursorX(0) + , mGuiCursorY(0) , mMouseWheel(0) , mUserFileExists(userFileExists) , mAlwaysRunActive(Settings::Manager::getBool("always run", "Input")) @@ -132,13 +132,8 @@ namespace MWInput , mSneaking(false) , mAttemptJump(false) , mFakeDeviceID(1) + , mInvUiScalingFactor(1.f) { - int w,h; - SDL_GetWindowSize(window, &w, &h); - - mMouseX = w / 2.f; - mMouseY = h / 2.f; - mInputManager = new SDLUtil::InputWrapper(window, viewer, grab); mInputManager->setMouseEventCallback (this); mInputManager->setKeyboardEventCallback (this); @@ -193,6 +188,16 @@ namespace MWInput //ICS_LOG(std::string("Unusable controller plugged in: ")+SDL_JoystickNameForIndex(i)); } } + + float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); + if (uiScale != 0.f) + mInvUiScalingFactor = 1.f / uiScale; + + int w,h; + SDL_GetWindowSize(window, &w, &h); + + mGuiCursorX = mInvUiScalingFactor * w / 2.f; + mGuiCursorY = mInvUiScalingFactor * h / 2.f; } void InputManager::clear() @@ -394,7 +399,7 @@ namespace MWInput //cursor is if( !is_relative && was_relative != is_relative ) { - mInputManager->warpMouse(static_cast(mMouseX), static_cast(mMouseY)); + mInputManager->warpMouse(static_cast(mGuiCursorX/mInvUiScalingFactor), static_cast(mGuiCursorY/mInvUiScalingFactor)); } } @@ -406,7 +411,7 @@ namespace MWInput mInputManager->capture(disableEvents); // inject some fake mouse movement to force updating MyGUI's widget states - MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX), int(mMouseY), mMouseWheel); + MyGUI::InputManager::getInstance().injectMouseMove( int(mGuiCursorX), int(mGuiCursorY), mMouseWheel); if (mControlsDisabled) { @@ -430,15 +435,15 @@ namespace MWInput // We keep track of our own mouse position, so that moving the mouse while in // game mode does not move the position of the GUI cursor - mMouseX += xAxis * dt * 1500.0f; - mMouseY += yAxis * dt * 1500.0f; + mGuiCursorX += xAxis * dt * 1500.0f * mInvUiScalingFactor; + mGuiCursorY += yAxis * dt * 1500.0f * mInvUiScalingFactor; mMouseWheel -= static_cast(zAxis * dt * 1500.0f); - mMouseX = std::max(0.f, std::min(mMouseX, float(viewSize.width))); - mMouseY = std::max(0.f, std::min(mMouseY, float(viewSize.height))); + mGuiCursorX = std::max(0.f, std::min(mGuiCursorX, float(viewSize.width))); + mGuiCursorY = std::max(0.f, std::min(mGuiCursorY, float(viewSize.height))); - MyGUI::InputManager::getInstance().injectMouseMove(static_cast(mMouseX), static_cast(mMouseY), mMouseWheel); - mInputManager->warpMouse(static_cast(mMouseX), static_cast(mMouseY)); + MyGUI::InputManager::getInstance().injectMouseMove(static_cast(mGuiCursorX), static_cast(mGuiCursorY), mMouseWheel); + mInputManager->warpMouse(static_cast(mGuiCursorX/mInvUiScalingFactor), static_cast(mGuiCursorY/mInvUiScalingFactor)); } if (mMouseLookEnabled) { @@ -741,7 +746,7 @@ namespace MWInput if (id == SDL_BUTTON_LEFT || id == SDL_BUTTON_RIGHT) // MyGUI only uses these mouse events { guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); - guiMode = MyGUI::InputManager::getInstance().injectMousePress(static_cast(mMouseX), static_cast(mMouseY), sdlButtonToMyGUI(id)) && guiMode; + guiMode = MyGUI::InputManager::getInstance().injectMousePress(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(id)) && guiMode; if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) { MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType(false); @@ -768,7 +773,7 @@ namespace MWInput mInputBinder->mouseReleased (arg, id); } else { bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); - guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(static_cast(mMouseX), static_cast(mMouseY), sdlButtonToMyGUI(id)) && guiMode; + guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(id)) && guiMode; if(mInputBinder->detectingBindingState()) return; // don't allow same mouseup to bind as initiated bind @@ -786,19 +791,14 @@ namespace MWInput if (mGuiCursorEnabled) { - const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); - // We keep track of our own mouse position, so that moving the mouse while in // game mode does not move the position of the GUI cursor - mMouseX = static_cast(arg.x); - mMouseY = static_cast(arg.y); - - mMouseX = std::max(0.f, std::min(mMouseX, float(viewSize.width))); - mMouseY = std::max(0.f, std::min(mMouseY, float(viewSize.height))); + mGuiCursorX = static_cast(arg.x) * mInvUiScalingFactor; + mGuiCursorY = static_cast(arg.y) * mInvUiScalingFactor; mMouseWheel = int(arg.z); - MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX), int(mMouseY), mMouseWheel); + MyGUI::InputManager::getInstance().injectMouseMove( int(mGuiCursorX), int(mGuiCursorY), mMouseWheel); } if (mMouseLookEnabled && !mControlsDisabled) @@ -840,7 +840,7 @@ namespace MWInput guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); if(!mInputBinder->detectingBindingState()) { - guiMode = MyGUI::InputManager::getInstance().injectMousePress(static_cast(mMouseX), static_cast(mMouseY), + guiMode = MyGUI::InputManager::getInstance().injectMousePress(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI((arg.button == SDL_CONTROLLER_BUTTON_B) ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT)) && guiMode; if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) { @@ -872,7 +872,7 @@ namespace MWInput else if(arg.button == SDL_CONTROLLER_BUTTON_A || arg.button == SDL_CONTROLLER_BUTTON_B) { bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); - guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(static_cast(mMouseX), static_cast(mMouseY), sdlButtonToMyGUI((arg.button == SDL_CONTROLLER_BUTTON_B) ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT)) && guiMode; + guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI((arg.button == SDL_CONTROLLER_BUTTON_B) ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT)) && guiMode; if(mInputBinder->detectingBindingState()) return; // don't allow same mouseup to bind as initiated bind diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 6b636058f..aec640736 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -187,8 +187,8 @@ namespace MWInput float mOverencumberedMessageDelay; - float mMouseX; - float mMouseY; + float mGuiCursorX; + float mGuiCursorY; int mMouseWheel; bool mUserFileExists; bool mAlwaysRunActive; @@ -198,7 +198,11 @@ namespace MWInput std::map mControlSwitch; + float mInvUiScalingFactor; + private: + void convertMousePosForMyGUI(int& x, int& y); + MyGUI::MouseButton sdlButtonToMyGUI(Uint8 button); virtual std::string sdlControllerAxisToString(int axis); diff --git a/components/myguiplatform/myguiplatform.hpp b/components/myguiplatform/myguiplatform.hpp index c0c9e0ce4..513267c99 100644 --- a/components/myguiplatform/myguiplatform.hpp +++ b/components/myguiplatform/myguiplatform.hpp @@ -14,14 +14,14 @@ namespace osgMyGUI class Platform { public: - Platform(osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::TextureManager* textureManager) + Platform(osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::TextureManager* textureManager, float uiScalingFactor) : mRenderManager(nullptr) , mDataManager(nullptr) , mLogManager(nullptr) , mLogFacility(nullptr) { mLogManager = new MyGUI::LogManager(); - mRenderManager = new RenderManager(viewer, guiRoot, textureManager); + mRenderManager = new RenderManager(viewer, guiRoot, textureManager, uiScalingFactor); mDataManager = new DataManager(); } diff --git a/components/myguiplatform/myguirendermanager.cpp b/components/myguiplatform/myguirendermanager.cpp index 3caa61548..e2f2f9820 100644 --- a/components/myguiplatform/myguirendermanager.cpp +++ b/components/myguiplatform/myguirendermanager.cpp @@ -40,37 +40,6 @@ } \ } while(0) -namespace -{ - -// Proxy to forward an OSG resize event to RenderManager::setViewSize -class ResizeHandler : public osgGA::GUIEventHandler { - osgMyGUI::RenderManager *mParent; - - virtual bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa) - { - if(ea.getEventType() == osgGA::GUIEventAdapter::RESIZE) - { - int width = ea.getWindowWidth(); - int height = ea.getWindowHeight(); - mParent->setViewSize(width, height); - } - return false; - } - -public: - ResizeHandler(osgMyGUI::RenderManager *parent=nullptr) : mParent(parent) { } - ResizeHandler(const ResizeHandler ©, const osg::CopyOp ©op=osg::CopyOp::SHALLOW_COPY) - : osg::Object(copy, copyop), osgGA::GUIEventHandler(copy, copyop) - , mParent(copy.mParent) - { } - - META_Object(osgMyGUI, ResizeHandler) -}; - -} - - namespace osgMyGUI { @@ -322,13 +291,16 @@ void OSGVertexBuffer::create() // --------------------------------------------------------------------------- -RenderManager::RenderManager(osgViewer::Viewer *viewer, osg::Group *sceneroot, Resource::TextureManager* textureManager) +RenderManager::RenderManager(osgViewer::Viewer *viewer, osg::Group *sceneroot, Resource::TextureManager* textureManager, float scalingFactor) : mViewer(viewer) , mSceneRoot(sceneroot) , mTextureManager(textureManager) , mUpdate(false) , mIsInitialise(false) + , mInvScalingFactor(1.f) { + if (scalingFactor != 0.f) + mInvScalingFactor = 1.f / scalingFactor; } RenderManager::~RenderManager() @@ -380,7 +352,6 @@ void RenderManager::initialise() mGuiRoot = camera; mSceneRoot->addChild(mGuiRoot.get()); - mViewer->addEventHandler(new ResizeHandler(this)); osg::ref_ptr vp = mViewer->getCamera()->getViewport(); setViewSize(vp->width(), vp->height()); @@ -458,7 +429,8 @@ void RenderManager::setViewSize(int width, int height) if(height < 1) height = 1; mGuiRoot->setViewport(0, 0, width, height); - mViewSize.set(width, height); + + mViewSize.set(width * mInvScalingFactor, height * mInvScalingFactor); mInfo.maximumDepth = 1; mInfo.hOffset = 0; diff --git a/components/myguiplatform/myguirendermanager.hpp b/components/myguiplatform/myguirendermanager.hpp index afb07eaa6..d9fdc1834 100644 --- a/components/myguiplatform/myguirendermanager.hpp +++ b/components/myguiplatform/myguirendermanager.hpp @@ -46,15 +46,19 @@ class RenderManager : public MyGUI::RenderManager, public MyGUI::IRenderTarget osg::ref_ptr mGuiRoot; + float mInvScalingFactor; + void destroyAllResources(); public: - RenderManager(osgViewer::Viewer *viewer, osg::Group *sceneroot, Resource::TextureManager* textureManager); + RenderManager(osgViewer::Viewer *viewer, osg::Group *sceneroot, Resource::TextureManager* textureManager, float scalingFactor); virtual ~RenderManager(); void initialise(); void shutdown(); + void setScalingFactor(float factor); + static RenderManager& getInstance() { return *getInstancePtr(); } static RenderManager* getInstancePtr() { return static_cast(MyGUI::RenderManager::getInstancePtr()); } diff --git a/components/myguiplatform/myguitexture.cpp b/components/myguiplatform/myguitexture.cpp index 68408dd3a..2a32dd9f3 100644 --- a/components/myguiplatform/myguitexture.cpp +++ b/components/myguiplatform/myguitexture.cpp @@ -86,7 +86,7 @@ namespace osgMyGUI if (!mTextureManager) throw std::runtime_error("No texturemanager set"); - mTexture = mTextureManager->getTexture2D(fname, osg::Texture2D::CLAMP, osg::Texture2D::CLAMP); + mTexture = mTextureManager->getTexture2D(fname, osg::Texture2D::REPEAT, osg::Texture2D::REPEAT); // FIXME mFormat = MyGUI::PixelFormat::R8G8B8; diff --git a/files/settings-default.cfg b/files/settings-default.cfg index cbb3ff6b0..fc8571bf8 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -21,6 +21,8 @@ gamma = 1.00 contrast = 1.00 [GUI] +scaling factor = 1.0 + # 1 is fully opaque menu transparency = 0.84