mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-19 15:09:41 +00:00
*very* early texture manager, need a lot more thought to design this properly
This commit is contained in:
parent
322fcdc2d3
commit
bb32c761df
13 changed files with 176 additions and 53 deletions
|
@ -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;
|
||||
|
|
66
components/resource/texturemanager.cpp
Normal file
66
components/resource/texturemanager.cpp
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
48
components/resource/texturemanager.hpp
Normal file
48
components/resource/texturemanager.hpp
Normal file
|
@ -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…
Reference in a new issue