From Brede Johansen, "The OpenFlight loader already have a caching mechanism for externals.

The cache works for nested externals but is cleared before the master
flight file is returned.  I implemented texture caching using the same
mechanism."
This commit is contained in:
Robert Osfield 2007-01-15 10:11:23 +00:00
parent c53b597795
commit 3cb9af0dd6
3 changed files with 72 additions and 29 deletions

View File

@ -246,7 +246,7 @@ protected:
virtual ~TexturePalette() {} virtual ~TexturePalette() {}
osg::Texture2D::WrapMode convertWrapMode(int32 attrWrapMode, const Document& document) osg::Texture2D::WrapMode convertWrapMode(int32 attrWrapMode, const Document& document) const
{ {
osg::Texture2D::WrapMode osgWrapMode = osg::Texture2D::REPEAT; osg::Texture2D::WrapMode osgWrapMode = osg::Texture2D::REPEAT;
switch (attrWrapMode) switch (attrWrapMode)
@ -268,33 +268,19 @@ protected:
return osgWrapMode; return osgWrapMode;
} }
virtual void readRecord(RecordInputStream& in, Document& document) osg::StateSet* readTexture(const std::string& filename, const Document& document) const
{ {
if (document.getTexturePoolParent()) osg::Image* image = osgDB::readImageFile(filename,document.getOptions());
// Using parent's texture pool -- ignore this record. if (!image) return NULL;
return;
int maxLength = (document.version() < VERSION_14) ? 80 : 200; // Create stateset to hold texture and attributes.
std::string filename = in.readString(maxLength); osg::StateSet* stateset = new osg::StateSet;
int32 index = in.readInt32(-1);
/*int32 x =*/ in.readInt32();
/*int32 y =*/ in.readInt32();
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(filename,document.getOptions());
if (!image.valid())
{
osg::notify(osg::WARN) << "Can't find texture (" << index << ") " << filename << std::endl;
return;
}
// Create stateset
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
osg::Texture2D* texture = new osg::Texture2D; osg::Texture2D* texture = new osg::Texture2D;
texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::REPEAT); texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::REPEAT);
texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::REPEAT); texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::REPEAT);
texture->setResizeNonPowerOfTwoHint(true); texture->setResizeNonPowerOfTwoHint(true);
texture->setImage(image.get()); texture->setImage(image);
stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
// Read attribute file // Read attribute file
@ -383,8 +369,44 @@ protected:
stateset->setTextureAttribute(0, texenv); stateset->setTextureAttribute(0, texenv);
} }
return stateset;
}
virtual void readRecord(RecordInputStream& in, Document& document)
{
if (document.getTexturePoolParent())
// Using parent's texture pool -- ignore this record.
return;
int maxLength = (document.version() < VERSION_14) ? 80 : 200;
std::string filename = in.readString(maxLength);
int32 index = in.readInt32(-1);
/*int32 x =*/ in.readInt32();
/*int32 y =*/ in.readInt32();
// Need full path for unique key in local texture cache.
std::string pathname = osgDB::findDataFile(filename,document.getOptions());
if (pathname.empty())
{
osg::notify(osg::WARN) << "Can't find texture (" << index << ") " << filename << std::endl;
return;
}
// Is texture in local cache?
osg::StateSet* stateset = flt::Registry::instance()->getTextureFromLocalCache(pathname);
// Read file if not in cache.
if (!stateset)
{
stateset = readTexture(pathname,document);
// Add to texture cache.
flt::Registry::instance()->addTextureToLocalCache(pathname,stateset);
}
// Add to texture pool.
TexturePool* tp = document.getOrCreateTexturePool(); TexturePool* tp = document.getOrCreateTexturePool();
(*tp)[index] = stateset.get(); (*tp)[index] = stateset;
} }
}; };

View File

@ -95,7 +95,7 @@ class FLTReaderWriter : public ReaderWriter
// in local cache? // in local cache?
{ {
osg::Node* node = flt::Registry::instance()->getFromLocalCache(fileName); osg::Node* node = flt::Registry::instance()->getExternalFromLocalCache(fileName);
if (node) if (node)
return ReadResult(node, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE); return ReadResult(node, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
} }
@ -122,7 +122,7 @@ class FLTReaderWriter : public ReaderWriter
if (rr.success()) if (rr.success())
{ {
// add to local cache. // add to local cache.
flt::Registry::instance()->addToLocalCache(fileName,rr.getNode()); flt::Registry::instance()->addExternalToLocalCache(fileName,rr.getNode());
bool keepExternalReferences = false; bool keepExternalReferences = false;
if (options) if (options)

View File

@ -34,8 +34,10 @@ class Registry : public osg::Referenced
void addToExternalReadQueue(const std::string& filename, osg::Group* parent); void addToExternalReadQueue(const std::string& filename, osg::Group* parent);
// Local cache // Local cache
void addToLocalCache(const std::string& filename, osg::Node* node); void addExternalToLocalCache(const std::string& filename, osg::Node* node);
osg::Node* getFromLocalCache(const std::string& filename); osg::Node* getExternalFromLocalCache(const std::string& filename);
void addTextureToLocalCache(const std::string& filename, osg::StateSet* stateset);
osg::StateSet* getTextureFromLocalCache(const std::string& filename);
void clearLocalCache(); void clearLocalCache();
protected: protected:
@ -47,8 +49,13 @@ class Registry : public osg::Referenced
ExternalQueue _externalReadQueue; ExternalQueue _externalReadQueue;
// External cache
typedef std::map<std::string, osg::ref_ptr<osg::Node> > ExternalCacheMap; typedef std::map<std::string, osg::ref_ptr<osg::Node> > ExternalCacheMap;
ExternalCacheMap _externalCacheMap; ExternalCacheMap _externalCacheMap;
// Texture cache
typedef std::map<std::string, osg::ref_ptr<osg::StateSet> > TextureCacheMap;
TextureCacheMap _textureCacheMap;
}; };
inline void Registry::addToExternalReadQueue(const std::string& filename, osg::Group* parent) inline void Registry::addToExternalReadQueue(const std::string& filename, osg::Group* parent)
@ -56,12 +63,12 @@ inline void Registry::addToExternalReadQueue(const std::string& filename, osg::G
_externalReadQueue.push( FilenameParentPair(filename,parent) ); _externalReadQueue.push( FilenameParentPair(filename,parent) );
} }
inline void Registry::addToLocalCache(const std::string& filename, osg::Node* node) inline void Registry::addExternalToLocalCache(const std::string& filename, osg::Node* node)
{ {
_externalCacheMap[filename] = node; _externalCacheMap[filename] = node;
} }
inline osg::Node* Registry::getFromLocalCache(const std::string& filename) inline osg::Node* Registry::getExternalFromLocalCache(const std::string& filename)
{ {
ExternalCacheMap::iterator itr = _externalCacheMap.find(filename); ExternalCacheMap::iterator itr = _externalCacheMap.find(filename);
if (itr != _externalCacheMap.end()) if (itr != _externalCacheMap.end())
@ -69,9 +76,23 @@ inline osg::Node* Registry::getFromLocalCache(const std::string& filename)
return NULL; return NULL;
} }
inline void Registry::addTextureToLocalCache(const std::string& filename, osg::StateSet* stateset)
{
_textureCacheMap[filename] = stateset;
}
inline osg::StateSet* Registry::getTextureFromLocalCache(const std::string& filename)
{
TextureCacheMap::iterator itr = _textureCacheMap.find(filename);
if (itr != _textureCacheMap.end())
return (*itr).second.get();
return NULL;
}
inline void Registry::clearLocalCache() inline void Registry::clearLocalCache()
{ {
_externalCacheMap.clear(); _externalCacheMap.clear();
_textureCacheMap.clear();
} }
/** Proxy class for automatic registration of reader/writers with the Registry.*/ /** Proxy class for automatic registration of reader/writers with the Registry.*/