From 24bb2e152cdd54b08b06b4c0b5b8b80f8f5f0ebc Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 14 May 2015 21:42:04 +0200 Subject: [PATCH] Apply texture filter setting changes --- apps/openmw/engine.cpp | 8 ++++- apps/openmw/mwgui/settingswindow.cpp | 8 ++--- apps/openmw/mwrender/renderingmanager.cpp | 40 ++++++++++++++++------- apps/openmw/mwrender/renderingmanager.hpp | 5 +-- apps/openmw/mwworld/worldimp.cpp | 2 +- apps/openmw/mwworld/worldimp.hpp | 2 +- components/resource/texturemanager.cpp | 21 ++++++++++++ components/resource/texturemanager.hpp | 7 +++- files/mygui/openmw_settings_window.layout | 1 - files/settings-default.cfg | 5 +-- 10 files changed, 72 insertions(+), 27 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index f9bb297a9..9fb233140 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -419,6 +419,12 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mResourceSystem.reset(new Resource::ResourceSystem(mVFS.get())); mResourceSystem->getTextureManager()->setUnRefImageDataAfterApply(true); + osg::Texture::FilterMode min = osg::Texture::LINEAR_MIPMAP_NEAREST; + osg::Texture::FilterMode mag = osg::Texture::LINEAR; + if (Settings::Manager::getString("texture filtering", "General") == "trilinear") + min = osg::Texture::LINEAR_MIPMAP_LINEAR; + int maxAnisotropy = Settings::Manager::getInt("anisotropy", "General"); + mResourceSystem->getTextureManager()->setFilterSettings(min, mag, maxAnisotropy); // Create input and UI first to set up a bootstrapping environment for // showing a loading screen and keeping the window responsive while doing so @@ -469,7 +475,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) } // Create the world - mEnvironment.setWorld( new MWWorld::World (*mViewer, rootNode, mResourceSystem.get(), + mEnvironment.setWorld( new MWWorld::World (mViewer, rootNode, mResourceSystem.get(), mFileCollections, mContentFiles, mEncoder, mFallbackMap, mActivationDistanceOverride, mCellName, mStartupScript)); MWBase::Environment::get().getWorld()->setupPlayer(); diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index c23e2bb94..8ba46339a 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -38,12 +38,10 @@ namespace std::string textureFilteringToStr(const std::string& val) { - if (val == "anisotropic") - return "Anisotropic"; - else if (val == "bilinear") - return "Bilinear"; - else + if (val == "trilinear") return "Trilinear"; + else + return "Bilinear"; } void parseResolution (int &x, int &y, const std::string& str) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 7822ccb30..7e742e729 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -14,6 +14,7 @@ #include #include +#include #include @@ -82,7 +83,7 @@ namespace MWRender float mFogEnd; }; - RenderingManager::RenderingManager(osgViewer::Viewer &viewer, osg::ref_ptr rootNode, Resource::ResourceSystem* resourceSystem) + RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr rootNode, Resource::ResourceSystem* resourceSystem) : mViewer(viewer) , mRootNode(rootNode) , mResourceSystem(resourceSystem) @@ -97,13 +98,13 @@ namespace MWRender mObjects.reset(new Objects(mResourceSystem, lightRoot)); - mViewer.setIncrementalCompileOperation(new osgUtil::IncrementalCompileOperation); + mViewer->setIncrementalCompileOperation(new osgUtil::IncrementalCompileOperation); - mObjects->setIncrementalCompileOperation(mViewer.getIncrementalCompileOperation()); + mObjects->setIncrementalCompileOperation(mViewer->getIncrementalCompileOperation()); mEffectManager.reset(new EffectManager(mRootNode, mResourceSystem)); - mViewer.setLightingMode(osgViewer::View::NO_LIGHT); + mViewer->setLightingMode(osgViewer::View::NO_LIGHT); osg::ref_ptr source = new osg::LightSource; mSunLight = new osg::Light; @@ -133,10 +134,10 @@ namespace MWRender else cullingMode |= osg::CullStack::SMALL_FEATURE_CULLING; - viewer.getCamera()->setCullingMode( cullingMode ); + mViewer->getCamera()->setCullingMode( cullingMode ); - mViewer.getCamera()->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); - mViewer.getCamera()->setCullingMode(cullingMode); + mViewer->getCamera()->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); + mViewer->getCamera()->setCullingMode(cullingMode); mViewDistance = Settings::Manager::getFloat("viewing distance", "Viewing distance"); mFieldOfView = Settings::Manager::getFloat("field of view", "General"); @@ -184,7 +185,7 @@ namespace MWRender osg::Vec3f RenderingManager::getEyePos() { - osg::Vec3d eye = mViewer.getCameraManipulator()->getMatrix().getTrans(); + osg::Vec3d eye = mViewer->getCameraManipulator()->getMatrix().getTrans(); return eye; } @@ -232,7 +233,7 @@ namespace MWRender void RenderingManager::configureFog(float /* fogDepth */, const osg::Vec4f &colour) { - mViewer.getCamera()->setClearColor(colour); + mViewer->getCamera()->setClearColor(colour); mStateUpdater->setFogColor(colour); mStateUpdater->setFogEnd(mViewDistance); @@ -325,11 +326,26 @@ namespace MWRender void RenderingManager::updateProjectionMatrix() { double fovy, aspect, zNear, zFar; - mViewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar); + mViewer->getCamera()->getProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar); fovy = mFieldOfView; zNear = 5.f; zFar = mViewDistance; - mViewer.getCamera()->setProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar); + mViewer->getCamera()->setProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar); + } + + void RenderingManager::updateTextureFiltering() + { + osg::Texture::FilterMode min = osg::Texture::LINEAR_MIPMAP_NEAREST; + osg::Texture::FilterMode mag = osg::Texture::LINEAR; + + if (Settings::Manager::getString("texture filtering", "General") == "trilinear") + min = osg::Texture::LINEAR_MIPMAP_LINEAR; + + int maxAnisotropy = Settings::Manager::getInt("anisotropy", "General"); + + mViewer->stopThreading(); + mResourceSystem->getTextureManager()->setFilterSettings(min, mag, maxAnisotropy); + mViewer->startThreading(); } void RenderingManager::processChangedSettings(const Settings::CategorySettingVector &changed) @@ -346,6 +362,8 @@ namespace MWRender mViewDistance = Settings::Manager::getFloat("viewing distance", "Viewing distance"); updateProjectionMatrix(); } + else if (it->first == "General" && (it->second == "texture filtering" || it->second == "anisotropy")) + updateTextureFiltering(); } } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index b13dffb8c..32e081995 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -45,7 +45,7 @@ namespace MWRender class RenderingManager : public MWRender::RenderingInterface { public: - RenderingManager(osgViewer::Viewer& viewer, osg::ref_ptr rootNode, Resource::ResourceSystem* resourceSystem); + RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr rootNode, Resource::ResourceSystem* resourceSystem); ~RenderingManager(); MWRender::Objects& getObjects(); @@ -99,8 +99,9 @@ namespace MWRender private: void updateProjectionMatrix(); + void updateTextureFiltering(); - osgViewer::Viewer& mViewer; + osg::ref_ptr mViewer; osg::ref_ptr mRootNode; osg::ref_ptr mLightRoot; Resource::ResourceSystem* mResourceSystem; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index bbd98be56..91484a6ba 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -143,7 +143,7 @@ namespace MWWorld } World::World ( - osgViewer::Viewer& viewer, + osgViewer::Viewer* viewer, osg::ref_ptr rootNode, Resource::ResourceSystem* resourceSystem, const Files::Collections& fileCollections, diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 279d35329..21ad2d7ef 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -162,7 +162,7 @@ namespace MWWorld public: World ( - osgViewer::Viewer& viewer, + osgViewer::Viewer* viewer, osg::ref_ptr rootNode, Resource::ResourceSystem* resourceSystem, const Files::Collections& fileCollections, diff --git a/components/resource/texturemanager.cpp b/components/resource/texturemanager.cpp index b9b9fad5f..5f2ca19ef 100644 --- a/components/resource/texturemanager.cpp +++ b/components/resource/texturemanager.cpp @@ -36,6 +36,9 @@ namespace Resource TextureManager::TextureManager(const VFS::Manager *vfs) : mVFS(vfs) + , mMinFilter(osg::Texture::LINEAR_MIPMAP_LINEAR) + , mMagFilter(osg::Texture::LINEAR) + , mMaxAnisotropy(1) , mWarningTexture(createWarningTexture()) , mUnRefImageDataAfterApply(false) { @@ -52,6 +55,21 @@ namespace Resource mUnRefImageDataAfterApply = unref; } + void TextureManager::setFilterSettings(osg::Texture::FilterMode minFilter, osg::Texture::FilterMode magFilter, int maxAnisotropy) + { + mMinFilter = minFilter; + mMagFilter = magFilter; + mMaxAnisotropy = std::max(1, maxAnisotropy); + + for (std::map >::iterator it = mTextures.begin(); it != mTextures.end(); ++it) + { + osg::ref_ptr tex = it->second; + tex->setFilter(osg::Texture::MIN_FILTER, mMinFilter); + tex->setFilter(osg::Texture::MAG_FILTER, mMagFilter); + tex->setMaxAnisotropy(static_cast(mMaxAnisotropy)); + } + } + /* osg::ref_ptr TextureManager::getImage(const std::string &filename) { @@ -110,6 +128,9 @@ namespace Resource texture->setImage(image); texture->setWrap(osg::Texture::WRAP_S, wrapS); texture->setWrap(osg::Texture::WRAP_T, wrapT); + texture->setFilter(osg::Texture::MIN_FILTER, mMinFilter); + texture->setFilter(osg::Texture::MAG_FILTER, mMagFilter); + texture->setMaxAnisotropy(mMaxAnisotropy); texture->setUnRefImageDataAfterApply(mUnRefImageDataAfterApply); diff --git a/components/resource/texturemanager.hpp b/components/resource/texturemanager.hpp index 851a55166..5ff233348 100644 --- a/components/resource/texturemanager.hpp +++ b/components/resource/texturemanager.hpp @@ -23,7 +23,8 @@ namespace Resource TextureManager(const VFS::Manager* vfs); ~TextureManager(); - // TODO: texture filtering settings + /// @warning It is unsafe to call this function when a draw thread is using the textures. Call stopThreading() first! + void setFilterSettings(osg::Texture::FilterMode minFilter, osg::Texture::FilterMode maxFilter, int maxAnisotropy); /// Keep a copy of the texture data around in system memory? This is needed when using multiple graphics contexts, /// otherwise should be disabled to reduce memory usage. @@ -40,6 +41,10 @@ namespace Resource private: const VFS::Manager* mVFS; + osg::Texture::FilterMode mMinFilter; + osg::Texture::FilterMode mMagFilter; + int mMaxAnisotropy; + typedef std::pair, std::string> MapKey; std::map > mImages; diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index 397a9df04..66514c886 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -322,7 +322,6 @@ - diff --git a/files/settings-default.cfg b/files/settings-default.cfg index d28240f2c..4ad2a323f 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -48,13 +48,10 @@ stretch menu background = false field of view = 55 # Texture filtering mode. valid values: -# none -# anisotropic # bilinear # trilinear -texture filtering = anisotropic +texture filtering = -# Has no effect when texture filtering is not anisotropic anisotropy = 4 # Number of texture mipmaps to generate