diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index a935d7f900..94a064a6c8 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1098,12 +1098,21 @@ namespace MWGui void WindowManager::windowResized(int x, int y) { - // Note: this is a side effect of resolution change or window resize. - // There is no need to track these changes. Settings::Manager::setInt("resolution x", "Video", x); Settings::Manager::setInt("resolution y", "Video", y); - Settings::Manager::resetPendingChange("resolution x", "Video"); - Settings::Manager::resetPendingChange("resolution y", "Video"); + + // We only want to process changes to window-size related settings. + Settings::CategorySettingVector filter = {{"Video", "resolution x"}, + {"Video", "resolution y"}}; + + // If the HUD has not been initialised, the World singleton will not be available. + if (mHud) + { + MWBase::Environment::get().getWorld()->processChangedSettings( + Settings::Manager::getPendingChanges(filter)); + } + + Settings::Manager::resetPendingChanges(filter); mGuiPlatform->getRenderManagerPtr()->setViewSize(x, y); diff --git a/apps/openmw/mwrender/postprocessor.cpp b/apps/openmw/mwrender/postprocessor.cpp index b08cfe1f71..53fae4cd7d 100644 --- a/apps/openmw/mwrender/postprocessor.cpp +++ b/apps/openmw/mwrender/postprocessor.cpp @@ -14,7 +14,6 @@ #include #include "vismask.hpp" -#include "renderingmanager.hpp" namespace { @@ -132,11 +131,10 @@ namespace namespace MWRender { - PostProcessor::PostProcessor(RenderingManager& rendering, osgViewer::Viewer* viewer, osg::Group* rootNode) + PostProcessor::PostProcessor(osgViewer::Viewer* viewer, osg::Group* rootNode) : mViewer(viewer) , mRootNode(new osg::Group) , mDepthFormat(GL_DEPTH_COMPONENT24) - , mRendering(rendering) { bool softParticles = Settings::Manager::getBool("soft particles", "Shaders"); @@ -239,7 +237,6 @@ namespace MWRender mViewer->getCamera()->resize(width, height); mHUDCamera->resize(width, height); - mRendering.updateProjectionMatrix(); } void PostProcessor::createTexturesAndCamera(int width, int height) diff --git a/apps/openmw/mwrender/postprocessor.hpp b/apps/openmw/mwrender/postprocessor.hpp index cc5128d8f9..f2ef238737 100644 --- a/apps/openmw/mwrender/postprocessor.hpp +++ b/apps/openmw/mwrender/postprocessor.hpp @@ -14,12 +14,10 @@ namespace osgViewer namespace MWRender { - class RenderingManager; - class PostProcessor : public osg::Referenced { public: - PostProcessor(RenderingManager& rendering, osgViewer::Viewer* viewer, osg::Group* rootNode); + PostProcessor(osgViewer::Viewer* viewer, osg::Group* rootNode); auto getMsaaFbo() { return mMsaaFbo; } auto getFbo() { return mFbo; } @@ -46,8 +44,6 @@ namespace MWRender osg::ref_ptr mOpaqueDepthTex; int mDepthFormat; - - RenderingManager& mRendering; }; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 30be74c839..b15aaf6f06 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -454,7 +454,7 @@ namespace MWRender mSharedUniformStateUpdater = new SharedUniformStateUpdater(groundcover); rootNode->addUpdateCallback(mSharedUniformStateUpdater); - mPostProcessor = new PostProcessor(*this, viewer, mRootNode); + mPostProcessor = new PostProcessor(viewer, mRootNode); resourceSystem->getSceneManager()->setDepthFormat(mPostProcessor->getDepthFormat()); resourceSystem->getSceneManager()->setOpaqueDepthTex(mPostProcessor->getOpaqueDepthTex()); @@ -1208,19 +1208,26 @@ namespace MWRender void RenderingManager::processChangedSettings(const Settings::CategorySettingVector &changed) { + // Only perform a projection matrix update once if a relevant setting is changed. + bool updateProjection = false; + for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) { if (it->first == "Camera" && it->second == "field of view") { mFieldOfView = Settings::Manager::getFloat("field of view", "Camera"); - updateProjectionMatrix(); + updateProjection = true; + } + else if (it->first == "Video" && (it->second == "resolution x" || it->second == "resolution y")) + { + updateProjection = true; } else if (it->first == "Camera" && it->second == "viewing distance") { mViewDistance = Settings::Manager::getFloat("viewing distance", "Camera"); if(!Settings::Manager::getBool("use distant fog", "Fog")) mStateUpdater->setFogEnd(mViewDistance); - updateProjectionMatrix(); + updateProjection = true; } else if (it->first == "General" && (it->second == "texture filter" || it->second == "texture mipmap" || @@ -1263,6 +1270,11 @@ namespace MWRender } } } + + if (updateProjection) + { + updateProjectionMatrix(); + } } float RenderingManager::getNearClipDistance() const diff --git a/components/settings/categories.hpp b/components/settings/categories.hpp index d6cd042f61..6a2da2fa10 100644 --- a/components/settings/categories.hpp +++ b/components/settings/categories.hpp @@ -9,7 +9,7 @@ namespace Settings { using CategorySetting = std::pair; - using CategorySettingVector = std::set>; + using CategorySettingVector = std::set; using CategorySettingValueMap = std::map; } diff --git a/components/settings/settings.cpp b/components/settings/settings.cpp index 09a3d1f516..cef627acd4 100644 --- a/components/settings/settings.cpp +++ b/components/settings/settings.cpp @@ -39,7 +39,7 @@ void Manager::saveUser(const std::string &file) std::string Manager::getString(const std::string &setting, const std::string &category) { - CategorySettingValueMap::key_type key = std::make_pair(category, setting); + CategorySettingValueMap::key_type key (category, setting); CategorySettingValueMap::iterator it = mUserSettings.find(key); if (it != mUserSettings.end()) return it->second; @@ -93,7 +93,7 @@ osg::Vec2f Manager::getVector2 (const std::string& setting, const std::string& c stream >> x >> y; if (stream.fail()) throw std::runtime_error(std::string("Can't parse 2d vector: " + value)); - return osg::Vec2f(x, y); + return {x, y}; } osg::Vec3f Manager::getVector3 (const std::string& setting, const std::string& category) @@ -104,14 +104,14 @@ osg::Vec3f Manager::getVector3 (const std::string& setting, const std::string& c stream >> x >> y >> z; if (stream.fail()) throw std::runtime_error(std::string("Can't parse 3d vector: " + value)); - return osg::Vec3f(x, y, z); + return {x, y, z}; } void Manager::setString(const std::string &setting, const std::string &category, const std::string &value) { - CategorySettingValueMap::key_type key = std::make_pair(category, setting); + CategorySettingValueMap::key_type key (category, setting); - CategorySettingValueMap::iterator found = mUserSettings.find(key); + auto found = mUserSettings.find(key); if (found != mUserSettings.end()) { if (found->second == value) @@ -165,18 +165,35 @@ void Manager::setVector3 (const std::string &setting, const std::string &categor void Manager::resetPendingChange(const std::string &setting, const std::string &category) { - CategorySettingValueMap::key_type key = std::make_pair(category, setting); + CategorySettingValueMap::key_type key (category, setting); mChangedSettings.erase(key); } -const CategorySettingVector Manager::getPendingChanges() +CategorySettingVector Manager::getPendingChanges() { return mChangedSettings; } +CategorySettingVector Manager::getPendingChanges(const CategorySettingVector& filter) +{ + CategorySettingVector intersection; + std::set_intersection(mChangedSettings.begin(), mChangedSettings.end(), + filter.begin(), filter.end(), + std::inserter(intersection, intersection.begin())); + return intersection; +} + void Manager::resetPendingChanges() { mChangedSettings.clear(); } +void Manager::resetPendingChanges(const CategorySettingVector& filter) +{ + for (const auto& key : filter) + { + mChangedSettings.erase(key); + } +} + } diff --git a/components/settings/settings.hpp b/components/settings/settings.hpp index e3a29d4c34..21d5aff770 100644 --- a/components/settings/settings.hpp +++ b/components/settings/settings.hpp @@ -36,11 +36,19 @@ namespace Settings ///< save user settings to file static void resetPendingChange(const std::string &setting, const std::string &category); + ///< resets a single pending change static void resetPendingChanges(); + ///< resets the list of all pending changes - static const CategorySettingVector getPendingChanges(); - ///< returns the list of changed settings and then clears it + static void resetPendingChanges(const CategorySettingVector& filter); + ///< resets only the pending changes listed in the filter + + static CategorySettingVector getPendingChanges(); + ///< returns the list of changed settings + + static CategorySettingVector getPendingChanges(const CategorySettingVector& filter); + ///< returns the list of changed settings intersecting with the filter static int getInt (const std::string& setting, const std::string& category); static float getFloat (const std::string& setting, const std::string& category); @@ -50,15 +58,15 @@ namespace Settings static osg::Vec2f getVector2 (const std::string& setting, const std::string& category); static osg::Vec3f getVector3 (const std::string& setting, const std::string& category); - static void setInt (const std::string& setting, const std::string& category, const int value); - static void setFloat (const std::string& setting, const std::string& category, const float value); - static void setDouble (const std::string& setting, const std::string& category, const double value); + static void setInt (const std::string& setting, const std::string& category, int value); + static void setFloat (const std::string& setting, const std::string& category, float value); + static void setDouble (const std::string& setting, const std::string& category, double value); static void setString (const std::string& setting, const std::string& category, const std::string& value); - static void setBool (const std::string& setting, const std::string& category, const bool value); - static void setVector2 (const std::string& setting, const std::string& category, const osg::Vec2f value); - static void setVector3 (const std::string& setting, const std::string& category, const osg::Vec3f value); + static void setBool (const std::string& setting, const std::string& category, bool value); + static void setVector2 (const std::string& setting, const std::string& category, osg::Vec2f value); + static void setVector3 (const std::string& setting, const std::string& category, osg::Vec3f value); }; } -#endif // _COMPONENTS_SETTINGS_H +#endif // COMPONENTS_SETTINGS_H