*very* early texture manager, need a lot more thought to design this properly

c++11
scrawl 10 years ago
parent 322fcdc2d3
commit bb32c761df

@ -10,6 +10,8 @@
#include <components/vfs/bsaarchive.hpp>
#include <components/vfs/filesystemarchive.hpp>
#include <components/resource/texturemanager.hpp>
#include <components/files/configurationmanager.hpp>
#include <osgGA/TrackballManipulator>
@ -124,7 +126,8 @@ int main(int argc, char** argv)
//osgDB::writeNodeFile(*newNode, "out.osg");
osg::Group* newNode = new osg::Group;
NifOsg::Loader loader;
loader.resourceManager = &resourceMgr;
Resource::TextureManager texMgr(&resourceMgr);
loader.mTextureManager = &texMgr;
newNode->addChild(loader.load(nif));
osg::PositionAttitudeTransform* trans = new osg::PositionAttitudeTransform;

@ -109,7 +109,7 @@ CompositeViewer::CompositeViewer()
setRunFrameScheme(osgViewer::ViewerBase::CONTINUOUS);
connect( &mTimer, SIGNAL(timeout()), this, SLOT(update()) );
mTimer.start( 10 );
mTimer.start( 0 );
}
CompositeViewer &CompositeViewer::get()

@ -39,7 +39,7 @@ add_component_dir (vfs
)
add_component_dir (resource
scenemanager resourcesystem
scenemanager texturemanager resourcesystem
)
add_component_dir (sceneutil

@ -416,7 +416,7 @@ void MaterialColorController::operator() (osg::Node* node, osg::NodeVisitor* nv)
traverse(node, nv);
}
FlipController::FlipController(const Nif::NiFlipController *ctrl, std::vector<osg::ref_ptr<osg::Image> > textures)
FlipController::FlipController(const Nif::NiFlipController *ctrl, std::vector<osg::ref_ptr<osg::Texture2D> > textures)
: mTexSlot(ctrl->mTexSlot)
, mDelta(ctrl->mDelta)
, mTextures(textures)
@ -442,12 +442,7 @@ void FlipController::operator() (osg::Node* node, osg::NodeVisitor* nv)
{
osg::StateSet* stateset = node->getStateSet();
int curTexture = int(getInputValue(nv) / mDelta) % mTextures.size();
osg::Texture2D* tex = dynamic_cast<osg::Texture2D*>(stateset->getTextureAttribute(mTexSlot, osg::StateAttribute::TEXTURE));
if (tex)
tex->setImage(mTextures[curTexture].get());
else
std::cout << "FlipController: can't find target slot" << std::endl;
stateset->setTextureAttribute(mTexSlot, mTextures[curTexture]);
}
traverse(node, nv);
}

@ -13,7 +13,7 @@
#include <set> //UVController
// FlipController
#include <osg/Image>
#include <osg/Texture2D>
#include <osg/ref_ptr>
#include <osg/Timer>
@ -265,10 +265,10 @@ namespace NifOsg
private:
int mTexSlot;
float mDelta;
std::vector<osg::ref_ptr<osg::Image> > mTextures;
std::vector<osg::ref_ptr<osg::Texture2D> > mTextures;
public:
FlipController(const Nif::NiFlipController* ctrl, std::vector<osg::ref_ptr<osg::Image> > textures);
FlipController(const Nif::NiFlipController* ctrl, std::vector<osg::ref_ptr<osg::Texture2D> > textures);
FlipController();
FlipController(const FlipController& copy, const osg::CopyOp& copyop);

@ -6,12 +6,12 @@
#include <osg/Geometry>
#include <osg/Array>
// resource
#include <components/bsa/bsa_file.hpp>
#include <osgDB/Registry>
#include <osg/io_utils>
// resource
#include <components/misc/stringops.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/texturemanager.hpp>
// skel
#include <osgAnimation/Skeleton>
@ -510,11 +510,11 @@ namespace NifOsg
class LoaderImpl
{
public:
const VFS::Manager* mResourceManager;
Resource::TextureManager* mTextureManager;
bool mShowMarkers;
LoaderImpl(const VFS::Manager* resourceManager, bool showMarkers)
: mResourceManager(resourceManager)
LoaderImpl(Resource::TextureManager* textureManager, bool showMarkers)
: mTextureManager(textureManager)
, mShowMarkers(showMarkers)
{
}
@ -846,22 +846,26 @@ namespace NifOsg
if (ctrl->recType == Nif::RC_NiFlipController)
{
const Nif::NiFlipController* flipctrl = static_cast<const Nif::NiFlipController*>(ctrl.getPtr());
std::vector<osg::ref_ptr<osg::Image> > textures;
std::vector<osg::ref_ptr<osg::Texture2D> > textures;
for (unsigned int i=0; i<flipctrl->mSources.length(); ++i)
{
Nif::NiSourceTexturePtr st = flipctrl->mSources[i];
if (st.empty())
continue;
std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, mResourceManager);
// inherit wrap settings from the target slot
osg::Texture2D* inherit = dynamic_cast<osg::Texture2D*>(stateset->getTextureAttribute(flipctrl->mTexSlot, osg::StateAttribute::TEXTURE));
osg::Texture2D::WrapMode wrapS = osg::Texture2D::CLAMP;
osg::Texture2D::WrapMode wrapT = osg::Texture2D::CLAMP;
if (inherit)
{
wrapS = inherit->getWrap(osg::Texture2D::WRAP_S);
wrapT = inherit->getWrap(osg::Texture2D::WRAP_T);
}
// TODO: replace with texture manager
// tx_creature_werewolf.dds isn't loading in the correct format without this option
osgDB::Options* opts = new osgDB::Options;
opts->setOptionString("dds_dxt1_detect_rgba");
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("dds");
osgDB::ReaderWriter::ReadResult result = reader->readImage(*mResourceManager->get(filename.c_str()), opts);
textures.push_back(osg::ref_ptr<osg::Image>(result.getImage()));
std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, mTextureManager->getVFS());
osg::ref_ptr<osg::Texture2D> texture = mTextureManager->getTexture2D(filename, wrapS, wrapT);
textures.push_back(texture);
}
osg::ref_ptr<FlipController> callback(new FlipController(flipctrl, textures));
setupController(ctrl.getPtr(), callback, animflags);
@ -1398,26 +1402,15 @@ namespace NifOsg
continue;
}
std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, mResourceManager);
// TODO: replace with texture manager
// tx_creature_werewolf.dds isn't loading in the correct format without this option
osgDB::Options* opts = new osgDB::Options;
opts->setOptionString("dds_dxt1_detect_rgba");
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("dds");
osgDB::ReaderWriter::ReadResult result = reader->readImage(*mResourceManager->get(filename.c_str()), opts);
osg::Image* image = result.getImage();
osg::Texture2D* texture2d = new osg::Texture2D;
// Can be enabled for single-context, i.e. in openmw
//texture2d->setUnRefImageDataAfterApply(true);
texture2d->setImage(image);
std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, mTextureManager->getVFS());
unsigned int clamp = static_cast<unsigned int>(tex.clamp);
int wrapT = (clamp) & 0x1;
int wrapS = (clamp >> 1) & 0x1;
texture2d->setWrap(osg::Texture::WRAP_S, wrapS ? osg::Texture::REPEAT : osg::Texture::CLAMP);
texture2d->setWrap(osg::Texture::WRAP_T, wrapT ? osg::Texture::REPEAT : osg::Texture::CLAMP);
osg::Texture2D* texture2d = mTextureManager->getTexture2D(filename,
wrapS ? osg::Texture::REPEAT : osg::Texture::CLAMP,
wrapT ? osg::Texture::REPEAT : osg::Texture::CLAMP);
stateset->setTextureAttributeAndModes(i, texture2d, osg::StateAttribute::ON);
@ -1544,19 +1537,19 @@ namespace NifOsg
osg::ref_ptr<osg::Node> Loader::load(Nif::NIFFilePtr file, TextKeyMap *textKeys)
{
LoaderImpl loader(resourceManager, sShowMarkers);
LoaderImpl loader(mTextureManager, sShowMarkers);
return loader.load(file, textKeys);
}
osg::ref_ptr<osg::Node> Loader::loadAsSkeleton(Nif::NIFFilePtr file, TextKeyMap *textKeys)
{
LoaderImpl loader(resourceManager, sShowMarkers);
LoaderImpl loader(mTextureManager, sShowMarkers);
return loader.loadAsSkeleton(file, textKeys);
}
void Loader::loadKf(Nif::NIFFilePtr kf, osg::Node *rootNode, int sourceIndex, TextKeyMap &textKeys)
{
LoaderImpl loader(resourceManager, sShowMarkers);
LoaderImpl loader(mTextureManager, sShowMarkers);
loader.loadKf(kf, rootNode, sourceIndex, textKeys);
}

@ -5,8 +5,6 @@
#include <components/nifcache/nifcache.hpp> // NIFFilePtr
#include <components/vfs/manager.hpp>
#include <osg/ref_ptr>
namespace osg
@ -14,6 +12,11 @@ namespace osg
class Node;
}
namespace Resource
{
class TextureManager;
}
namespace NifOsg
{
typedef std::multimap<float,std::string> TextKeyMap;
@ -41,7 +44,7 @@ namespace NifOsg
/// Default: false.
static void setShowMarkers(bool show);
const VFS::Manager* resourceManager;
Resource::TextureManager* mTextureManager;
private:

@ -1,6 +1,7 @@
#include "resourcesystem.hpp"
#include "scenemanager.hpp"
#include "texturemanager.hpp"
namespace Resource
{
@ -8,7 +9,8 @@ namespace Resource
ResourceSystem::ResourceSystem(const VFS::Manager *vfs)
: mVFS(vfs)
{
mSceneManager.reset(new SceneManager(vfs));
mTextureManager.reset(new TextureManager(vfs));
mSceneManager.reset(new SceneManager(vfs, mTextureManager.get()));
}
SceneManager* ResourceSystem::getSceneManager()

@ -12,8 +12,11 @@ namespace Resource
{
class SceneManager;
class TextureManager;
/// @brief Wrapper class that constructs and provides access to the various resource subsystems.
/// @par Resource subsystems can be used with multiple OpenGL contexts, just like the OSG equivalents, but
/// are built around the use of a single virtual file system.
class ResourceSystem
{
public:
@ -25,6 +28,7 @@ namespace Resource
private:
std::auto_ptr<SceneManager> mSceneManager;
std::auto_ptr<TextureManager> mTextureManager;
const VFS::Manager* mVFS;
};

@ -9,6 +9,8 @@
#include <components/nifosg/nifloader.hpp>
#include <components/nif/niffile.hpp>
#include <components/vfs/manager.hpp>
#include <components/sceneutil/clone.hpp>
namespace
@ -61,8 +63,9 @@ namespace
namespace Resource
{
SceneManager::SceneManager(const VFS::Manager *vfs)
SceneManager::SceneManager(const VFS::Manager *vfs, Resource::TextureManager* textureManager)
: mVFS(vfs)
, mTextureManager(textureManager)
{
}
@ -79,7 +82,7 @@ namespace Resource
// TODO: add support for non-NIF formats
NifOsg::Loader loader;
loader.resourceManager = mVFS;
loader.mTextureManager = mTextureManager;
osg::ref_ptr<const osg::Node> loaded = loader.load(Nif::NIFFilePtr(new Nif::NIFFile(file, normalized)));
// TODO: provide way for the user to get textKeys (attach to the node?)

@ -7,6 +7,11 @@
#include <osg/ref_ptr>
#include <osg/Node>
namespace Resource
{
class TextureManager;
}
namespace VFS
{
class Manager;
@ -19,7 +24,7 @@ namespace Resource
class SceneManager
{
public:
SceneManager(const VFS::Manager* vfs);
SceneManager(const VFS::Manager* vfs, Resource::TextureManager* textureManager);
/// Get a read-only copy of this scene "template"
osg::ref_ptr<const osg::Node> getTemplate(const std::string& name);
@ -38,6 +43,7 @@ namespace Resource
private:
const VFS::Manager* mVFS;
Resource::TextureManager* mTextureManager;
// observer_ptr?
typedef std::map<std::string, osg::ref_ptr<const osg::Node> > Index;

@ -0,0 +1,66 @@
#include "texturemanager.hpp"
#include <osgDB/Registry>
#include <stdexcept>
#include <components/vfs/manager.hpp>
namespace Resource
{
TextureManager::TextureManager(const VFS::Manager *vfs)
: mVFS(vfs)
{
}
/*
osg::ref_ptr<osg::Image> TextureManager::getImage(const std::string &filename)
{
}
*/
osg::ref_ptr<osg::Texture2D> TextureManager::getTexture2D(const std::string &filename, osg::Texture::WrapMode wrapS, osg::Texture::WrapMode wrapT)
{
std::string normalized = filename;
mVFS->normalizeFilename(normalized);
MapKey key = std::make_pair(std::make_pair(wrapS, wrapT), normalized);
std::map<MapKey, osg::ref_ptr<osg::Texture2D> >::iterator found = mTextures.find(key);
if (found != mTextures.end())
{
return found->second;
}
else
{
osg::ref_ptr<osgDB::Options> opts (new osgDB::Options);
opts->setOptionString("dds_dxt1_detect_rgba"); // tx_creature_werewolf.dds isn't loading in the correct format without this option
size_t extPos = normalized.find_last_of('.');
std::string ext;
if (extPos != std::string::npos && extPos+1 < normalized.size())
ext = normalized.substr(extPos+1);
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension(ext);
osgDB::ReaderWriter::ReadResult result = reader->readImage(*mVFS->get(normalized.c_str()), opts);
if (!result.success())
{
// TODO: use "notfound" default texture
throw std::runtime_error("Error loading");
//std::cerr << "Error loading " << filename << ": " << result.message() << std::endl;
}
osg::Image* image = result.getImage();
osg::ref_ptr<osg::Texture2D> texture(new osg::Texture2D);
texture->setImage(image);
texture->setWrap(osg::Texture::WRAP_S, wrapS);
texture->setWrap(osg::Texture::WRAP_T, wrapT);
// Can be enabled for single-context, i.e. in openmw
//texture->setUnRefImageDataAfterApply(true);
mTextures.insert(std::make_pair(key, texture));
return texture;
}
}
}

@ -0,0 +1,48 @@
#ifndef OPENMW_COMPONENTS_RESOURCE_TEXTUREMANAGER_H
#define OPENMW_COMPONENTS_RESOURCE_TEXTUREMANAGER_H
#include <string>
#include <map>
#include <osg/ref_ptr>
#include <osg/Image>
#include <osg/Texture2D>
namespace VFS
{
class Manager;
}
namespace Resource
{
/// @brief Handles loading/caching of Images and Texture StateAttributes.
class TextureManager
{
public:
TextureManager(const VFS::Manager* vfs);
// TODO: texture filtering settings
/// Create or retrieve a Texture2D using the specified image filename, and wrap parameters.
osg::ref_ptr<osg::Texture2D> getTexture2D(const std::string& filename, osg::Texture::WrapMode wrapS, osg::Texture::WrapMode wrapT);
/// Create or retrieve an Image
//osg::ref_ptr<osg::Image> getImage(const std::string& filename);
const VFS::Manager* getVFS() { return mVFS; }
private:
const VFS::Manager* mVFS;
typedef std::pair<std::pair<int, int>, std::string> MapKey;
std::map<std::string, osg::observer_ptr<osg::Image> > mImages;
std::map<MapKey, osg::ref_ptr<osg::Texture2D> > mTextures;
};
}
#endif
Loading…
Cancel
Save