Change the way that texture filtering settings are applied at runtime

move
scrawl 9 years ago
parent 7f89bb273a
commit e05d975020

@ -453,8 +453,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
Settings::Manager::getString("texture mag filter", "General"), Settings::Manager::getString("texture mag filter", "General"),
Settings::Manager::getString("texture min filter", "General"), Settings::Manager::getString("texture min filter", "General"),
Settings::Manager::getString("texture mipmap", "General"), Settings::Manager::getString("texture mipmap", "General"),
Settings::Manager::getInt("anisotropy", "General"), Settings::Manager::getInt("anisotropy", "General")
NULL
); );
// Create input and UI first to set up a bootstrapping environment for // Create input and UI first to set up a bootstrapping environment for

@ -836,16 +836,18 @@ namespace MWRender
void RenderingManager::updateTextureFiltering() void RenderingManager::updateTextureFiltering()
{ {
if (mTerrain.get()) mViewer->stopThreading();
mTerrain->updateCache();
mResourceSystem->getSceneManager()->setFilterSettings( mResourceSystem->getSceneManager()->setFilterSettings(
Settings::Manager::getString("texture mag filter", "General"), Settings::Manager::getString("texture mag filter", "General"),
Settings::Manager::getString("texture min filter", "General"), Settings::Manager::getString("texture min filter", "General"),
Settings::Manager::getString("texture mipmap", "General"), Settings::Manager::getString("texture mipmap", "General"),
Settings::Manager::getInt("anisotropy", "General"), Settings::Manager::getInt("anisotropy", "General")
mViewer
); );
mTerrain->updateTextureFiltering();
mViewer->startThreading();
} }
void RenderingManager::updateAmbient() void RenderingManager::updateAmbient()

@ -318,7 +318,6 @@ public:
mRefractionTexture->setInternalFormat(GL_RGB); mRefractionTexture->setInternalFormat(GL_RGB);
mRefractionTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); mRefractionTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
mRefractionTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); mRefractionTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
mRefractionTexture->getOrCreateUserDataContainer()->addDescription("dont_override_filter");
attach(osg::Camera::COLOR_BUFFER, mRefractionTexture); attach(osg::Camera::COLOR_BUFFER, mRefractionTexture);
@ -330,7 +329,6 @@ public:
mRefractionDepthTexture->setSourceType(GL_UNSIGNED_INT); mRefractionDepthTexture->setSourceType(GL_UNSIGNED_INT);
mRefractionDepthTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); mRefractionDepthTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
mRefractionDepthTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); mRefractionDepthTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
mRefractionDepthTexture->getOrCreateUserDataContainer()->addDescription("dont_override_filter");
attach(osg::Camera::DEPTH_BUFFER, mRefractionDepthTexture); attach(osg::Camera::DEPTH_BUFFER, mRefractionDepthTexture);
} }
@ -393,7 +391,6 @@ public:
mReflectionTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); mReflectionTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
mReflectionTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); mReflectionTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
mReflectionTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); mReflectionTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
mReflectionTexture->getOrCreateUserDataContainer()->addDescription("dont_override_filter");
attach(osg::Camera::COLOR_BUFFER, mReflectionTexture); attach(osg::Camera::COLOR_BUFFER, mReflectionTexture);

@ -14,6 +14,7 @@
#include "objectcache.hpp" #include "objectcache.hpp"
#include <osg/Object> #include <osg/Object>
#include <osg/Node>
namespace Resource namespace Resource
{ {
@ -119,4 +120,19 @@ void ObjectCache::releaseGLObjects(osg::State* state)
} }
} }
void ObjectCache::accept(osg::NodeVisitor &nv)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
for(ObjectCacheMap::iterator itr = _objectCache.begin();
itr != _objectCache.end();
++itr)
{
osg::Object* object = itr->second.first.get();
osg::Node* node = object->asNode();
if (node)
node->accept(nv);
}
}
} }

@ -27,6 +27,7 @@ namespace osg
{ {
class Object; class Object;
class State; class State;
class NodeVisitor;
} }
namespace Resource { namespace Resource {
@ -66,6 +67,9 @@ class ObjectCache : public osg::Referenced
/** call releaseGLObjects on all objects attached to the object cache.*/ /** call releaseGLObjects on all objects attached to the object cache.*/
void releaseGLObjects(osg::State* state); void releaseGLObjects(osg::State* state);
/** call node->accept(nv); for all nodes in the objectCache. */
void accept(osg::NodeVisitor& nv);
protected: protected:
virtual ~ObjectCache(); virtual ~ObjectCache();

@ -10,8 +10,6 @@
#include <osgUtil/IncrementalCompileOperation> #include <osgUtil/IncrementalCompileOperation>
#include <osgViewer/Viewer>
#include <osgDB/SharedStateManager> #include <osgDB/SharedStateManager>
#include <osgDB/Registry> #include <osgDB/Registry>
@ -192,13 +190,6 @@ namespace Resource
osg::Texture* tex = attr->asTexture(); osg::Texture* tex = attr->asTexture();
if (tex) if (tex)
{ {
if (tex->getUserDataContainer())
{
const std::vector<std::string>& descriptions = tex->getUserDataContainer()->getDescriptions();
if (std::find(descriptions.begin(), descriptions.end(), "dont_override_filter") != descriptions.end())
return;
}
tex->setFilter(osg::Texture::MIN_FILTER, mMinFilter); tex->setFilter(osg::Texture::MIN_FILTER, mMinFilter);
tex->setFilter(osg::Texture::MAG_FILTER, mMagFilter); tex->setFilter(osg::Texture::MAG_FILTER, mMagFilter);
tex->setMaxAnisotropy(mMaxAnisotropy); tex->setMaxAnisotropy(mMaxAnisotropy);
@ -425,8 +416,7 @@ namespace Resource
} }
void SceneManager::setFilterSettings(const std::string &magfilter, const std::string &minfilter, void SceneManager::setFilterSettings(const std::string &magfilter, const std::string &minfilter,
const std::string &mipmap, int maxAnisotropy, const std::string &mipmap, int maxAnisotropy)
osgViewer::Viewer *viewer)
{ {
osg::Texture::FilterMode min = osg::Texture::LINEAR; osg::Texture::FilterMode min = osg::Texture::LINEAR;
osg::Texture::FilterMode mag = osg::Texture::LINEAR; osg::Texture::FilterMode mag = osg::Texture::LINEAR;
@ -458,23 +448,15 @@ namespace Resource
min = osg::Texture::LINEAR_MIPMAP_LINEAR; min = osg::Texture::LINEAR_MIPMAP_LINEAR;
} }
if(viewer) viewer->stopThreading();
mMinFilter = min; mMinFilter = min;
mMagFilter = mag; mMagFilter = mag;
mMaxAnisotropy = std::max(1, maxAnisotropy); mMaxAnisotropy = std::max(1, maxAnisotropy);
mCache->clear();
SetFilterSettingsControllerVisitor setFilterSettingsControllerVisitor (mMinFilter, mMagFilter, mMaxAnisotropy); SetFilterSettingsControllerVisitor setFilterSettingsControllerVisitor (mMinFilter, mMagFilter, mMaxAnisotropy);
SetFilterSettingsVisitor setFilterSettingsVisitor (mMinFilter, mMagFilter, mMaxAnisotropy); SetFilterSettingsVisitor setFilterSettingsVisitor (mMinFilter, mMagFilter, mMaxAnisotropy);
if (viewer && viewer->getSceneData())
{
viewer->getSceneData()->accept(setFilterSettingsControllerVisitor);
viewer->getSceneData()->accept(setFilterSettingsVisitor);
}
if(viewer) viewer->startThreading(); mCache->accept(setFilterSettingsVisitor);
mCache->accept(setFilterSettingsControllerVisitor);
} }
void SceneManager::applyFilterSettings(osg::Texture *tex) void SceneManager::applyFilterSettings(osg::Texture *tex)

@ -21,11 +21,6 @@ namespace osgUtil
class IncrementalCompileOperation; class IncrementalCompileOperation;
} }
namespace osgViewer
{
class Viewer;
}
namespace Resource namespace Resource
{ {
@ -83,10 +78,9 @@ namespace Resource
/// @param mask The node mask to apply to loaded particle system nodes. /// @param mask The node mask to apply to loaded particle system nodes.
void setParticleSystemMask(unsigned int mask); void setParticleSystemMask(unsigned int mask);
/// @param viewer used to apply the new filter settings to the existing scene graph. If there is no scene yet, you can pass a NULL viewer. /// @warning It is unsafe to call this method while the draw thread is using textures! call Viewer::stopThreading first.
void setFilterSettings(const std::string &magfilter, const std::string &minfilter, void setFilterSettings(const std::string &magfilter, const std::string &minfilter,
const std::string &mipmap, int maxAnisotropy, const std::string &mipmap, int maxAnisotropy);
osgViewer::Viewer *viewer);
/// Apply filter settings to the given texture. Note, when loading an object through this scene manager (i.e. calling getTemplate or createInstance) /// Apply filter settings to the given texture. Note, when loading an object through this scene manager (i.e. calling getTemplate or createInstance)
/// the filter settings are applied automatically. This method is provided for textures that were created outside of the SceneManager. /// the filter settings are applied automatically. This method is provided for textures that were created outside of the SceneManager.

@ -175,7 +175,6 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
texture->setResizeNonPowerOfTwoHint(false); texture->setResizeNonPowerOfTwoHint(false);
texture->getOrCreateUserDataContainer()->addDescription("dont_override_filter");
blendmapTextures.push_back(texture); blendmapTextures.push_back(texture);
textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, blendmapTextures.back()); textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, blendmapTextures.back());
@ -278,4 +277,11 @@ void TerrainGrid::updateCache()
} }
} }
void TerrainGrid::updateTextureFiltering()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mTextureCacheMutex);
for (TextureCache::iterator it = mTextureCache.begin(); it != mTextureCache.end(); ++it)
mResourceSystem->getSceneManager()->applyFilterSettings(it->second);
}
} }

@ -36,6 +36,10 @@ namespace Terrain
/// @note Thread safe. /// @note Thread safe.
void updateCache(); void updateCache();
/// Apply the scene manager's texture filtering settings to all cached textures.
/// @note Thread safe.
void updateTextureFiltering();
private: private:
osg::ref_ptr<osg::Node> buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter); osg::ref_ptr<osg::Node> buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter);

@ -39,6 +39,8 @@ namespace Terrain
Storage* storage, int nodeMask); Storage* storage, int nodeMask);
virtual ~World(); virtual ~World();
virtual void updateTextureFiltering() {}
virtual void updateCache() {} virtual void updateCache() {}
float getHeightAt (const osg::Vec3f& worldPos); float getHeightAt (const osg::Vec3f& worldPos);

Loading…
Cancel
Save