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() {}
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;
switch (attrWrapMode)
@ -268,33 +268,19 @@ protected:
return osgWrapMode;
}
virtual void readRecord(RecordInputStream& in, Document& document)
osg::StateSet* readTexture(const std::string& filename, const Document& document) const
{
if (document.getTexturePoolParent())
// Using parent's texture pool -- ignore this record.
return;
osg::Image* image = osgDB::readImageFile(filename,document.getOptions());
if (!image) return NULL;
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();
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;
// Create stateset to hold texture and attributes.
osg::StateSet* stateset = new osg::StateSet;
osg::Texture2D* texture = new osg::Texture2D;
texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::REPEAT);
texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::REPEAT);
texture->setResizeNonPowerOfTwoHint(true);
texture->setImage(image.get());
texture->setImage(image);
stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
// Read attribute file
@ -383,8 +369,44 @@ protected:
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();
(*tp)[index] = stateset.get();
(*tp)[index] = stateset;
}
};

View File

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

View File

@ -34,8 +34,10 @@ class Registry : public osg::Referenced
void addToExternalReadQueue(const std::string& filename, osg::Group* parent);
// Local cache
void addToLocalCache(const std::string& filename, osg::Node* node);
osg::Node* getFromLocalCache(const std::string& filename);
void addExternalToLocalCache(const std::string& filename, osg::Node* node);
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();
protected:
@ -47,8 +49,13 @@ class Registry : public osg::Referenced
ExternalQueue _externalReadQueue;
// External cache
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)
@ -56,12 +63,12 @@ inline void Registry::addToExternalReadQueue(const std::string& filename, osg::G
_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;
}
inline osg::Node* Registry::getFromLocalCache(const std::string& filename)
inline osg::Node* Registry::getExternalFromLocalCache(const std::string& filename)
{
ExternalCacheMap::iterator itr = _externalCacheMap.find(filename);
if (itr != _externalCacheMap.end())
@ -69,9 +76,23 @@ inline osg::Node* Registry::getFromLocalCache(const std::string& filename)
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()
{
_externalCacheMap.clear();
_textureCacheMap.clear();
}
/** Proxy class for automatic registration of reader/writers with the Registry.*/