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:
parent
c53b597795
commit
3cb9af0dd6
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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.*/
|
||||||
|
Loading…
Reference in New Issue
Block a user