Merge branch 'vfs_normalized_path_14' into 'master'

Use normalized path in multiple places (#8138)

See merge request OpenMW/openmw!4383
pull/3236/head
Evil Eye 3 months ago
commit 772a0b3711

@ -4,13 +4,13 @@
#include "rotationflags.hpp"
#include <deque>
#include <map>
#include <set>
#include <span>
#include <string_view>
#include <vector>
#include <components/misc/rng.hpp>
#include <components/vfs/pathutil.hpp>
#include "../mwworld/doorstate.hpp"
#include "../mwworld/globalvariablename.hpp"
@ -515,7 +515,7 @@ namespace MWBase
/// Spawn a blood effect for \a ptr at \a worldPosition
virtual void spawnBloodEffect(const MWWorld::Ptr& ptr, const osg::Vec3f& worldPosition) = 0;
virtual void spawnEffect(const std::string& model, const std::string& textureOverride,
virtual void spawnEffect(VFS::Path::NormalizedView model, const std::string& textureOverride,
const osg::Vec3f& worldPos, float scale = 1.f, bool isMagicVFX = true)
= 0;

@ -319,14 +319,14 @@ namespace MWLua
std::string texture = options->get_or<std::string>("particleTextureOverride", "");
float scale = options->get_or("scale", 1.f);
context.mLuaManager->addAction(
[world, model = std::string(model), texture = std::move(texture), worldPos, scale,
[world, model = VFS::Path::Normalized(model), texture = std::move(texture), worldPos, scale,
magicVfx]() { world->spawnEffect(model, texture, worldPos, scale, magicVfx); },
"openmw.vfx.spawn");
}
else
{
context.mLuaManager->addAction(
[world, model = std::string(model), worldPos]() { world->spawnEffect(model, "", worldPos); },
context.mLuaManager->addAction([world, model = VFS::Path::Normalized(model),
worldPos]() { world->spawnEffect(model, "", worldPos); },
"openmw.vfx.spawn");
}
};

@ -214,7 +214,7 @@ namespace
const ESM::Static* const fx
= world->getStore().get<ESM::Static>().search(ESM::RefId::stringRefId("VFX_Soul_Trap"));
if (fx != nullptr)
world->spawnEffect(Misc::ResourceHelpers::correctMeshPath(fx->mModel), "",
world->spawnEffect(VFS::Path::toNormalized(Misc::ResourceHelpers::correctMeshPath(fx->mModel)), "",
creature.getRefData().getPosition().asVec3());
MWBase::Environment::get().getSoundManager()->playSound3D(
@ -1806,7 +1806,8 @@ namespace MWMechanics
ESM::RefId::stringRefId("VFX_Summon_End"));
if (fx)
MWBase::Environment::get().getWorld()->spawnEffect(
Misc::ResourceHelpers::correctMeshPath(fx->mModel), "", ptr.getRefData().getPosition().asVec3());
VFS::Path::toNormalized(Misc::ResourceHelpers::correctMeshPath(fx->mModel)), "",
ptr.getRefData().getPosition().asVec3());
// Remove the summoned creature's summoned creatures as well
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);

@ -72,12 +72,13 @@ namespace MWMechanics
{
if (effectInfo.mData.mRange == ESM::RT_Target)
world->spawnEffect(
Misc::ResourceHelpers::correctMeshPath(areaStatic->mModel), texture, mHitPosition, 1.0f);
VFS::Path::toNormalized(Misc::ResourceHelpers::correctMeshPath(areaStatic->mModel)), texture,
mHitPosition, 1.0f);
continue;
}
else
world->spawnEffect(Misc::ResourceHelpers::correctMeshPath(areaStatic->mModel), texture, mHitPosition,
static_cast<float>(effectInfo.mData.mArea * 2));
world->spawnEffect(VFS::Path::toNormalized(Misc::ResourceHelpers::correctMeshPath(areaStatic->mModel)),
texture, mHitPosition, static_cast<float>(effectInfo.mData.mArea * 2));
// Play explosion sound (make sure to use NoTrack, since we will delete the projectile now)
{
@ -539,7 +540,8 @@ namespace MWMechanics
}
scale = std::max(scale, 1.f);
MWBase::Environment::get().getWorld()->spawnEffect(
Misc::ResourceHelpers::correctMeshPath(castStatic->mModel), effect->mParticle, pos, scale);
VFS::Path::toNormalized(Misc::ResourceHelpers::correctMeshPath(castStatic->mModel)),
effect->mParticle, pos, scale);
}
if (animation && !mCaster.getClass().isActor())

@ -67,31 +67,29 @@ namespace MWRender
}
PartHolderPtr ActorAnimation::attachMesh(
const std::string& model, std::string_view bonename, bool enchantedGlow, osg::Vec4f* glowColor)
VFS::Path::NormalizedView model, std::string_view bonename, const osg::Vec4f* glowColor)
{
osg::Group* parent = getBoneByName(bonename);
if (!parent)
return nullptr;
osg::ref_ptr<osg::Node> instance
= mResourceSystem->getSceneManager()->getInstance(VFS::Path::toNormalized(model), parent);
osg::ref_ptr<osg::Node> instance = mResourceSystem->getSceneManager()->getInstance(model, parent);
const NodeMap& nodeMap = getNodeMap();
NodeMap::const_iterator found = nodeMap.find(bonename);
if (found == nodeMap.end())
return {};
if (enchantedGlow)
if (glowColor != nullptr)
mGlowUpdater = SceneUtil::addEnchantedGlow(instance, mResourceSystem, *glowColor);
return std::make_unique<PartHolder>(instance);
}
osg::ref_ptr<osg::Node> ActorAnimation::attach(
const std::string& model, std::string_view bonename, std::string_view bonefilter, bool isLight)
VFS::Path::NormalizedView model, std::string_view bonename, std::string_view bonefilter, bool isLight)
{
osg::ref_ptr<const osg::Node> templateNode
= mResourceSystem->getSceneManager()->getTemplate(VFS::Path::toNormalized(model));
osg::ref_ptr<const osg::Node> templateNode = mResourceSystem->getSceneManager()->getTemplate(model);
const NodeMap& nodeMap = getNodeMap();
auto found = nodeMap.find(bonename);
@ -218,20 +216,20 @@ namespace MWRender
return;
}
std::string mesh = getSheathedShieldMesh(*shield);
const VFS::Path::Normalized mesh = getSheathedShieldMesh(*shield);
if (mesh.empty())
return;
std::string_view boneName = "Bip01 AttachShield";
osg::Vec4f glowColor = shield->getClass().getEnchantmentColor(*shield);
const std::string holsteredName = addSuffixBeforeExtension(mesh, "_sh");
bool isEnchanted = !shield->getClass().getEnchantment(*shield).empty();
constexpr std::string_view boneName = "Bip01 AttachShield";
const bool isEnchanted = !shield->getClass().getEnchantment(*shield).empty();
const osg::Vec4f glowColor = isEnchanted ? shield->getClass().getEnchantmentColor(*shield) : osg::Vec4f();
const VFS::Path::Normalized holsteredName = addSuffixBeforeExtension(mesh, "_sh");
// If we have no dedicated sheath model, use basic shield model as fallback.
if (!mResourceSystem->getVFS()->exists(holsteredName))
mHolsteredShield = attachMesh(mesh, boneName, isEnchanted, &glowColor);
mHolsteredShield = attachMesh(mesh, boneName, isEnchanted ? &glowColor : nullptr);
else
mHolsteredShield = attachMesh(holsteredName, boneName, isEnchanted, &glowColor);
mHolsteredShield = attachMesh(holsteredName, boneName, isEnchanted ? &glowColor : nullptr);
if (!mHolsteredShield)
return;
@ -245,8 +243,7 @@ namespace MWRender
// file.
if (shieldNode && !shieldNode->getNumChildren())
{
osg::ref_ptr<osg::Node> fallbackNode
= mResourceSystem->getSceneManager()->getInstance(VFS::Path::toNormalized(mesh), shieldNode);
osg::ref_ptr<osg::Node> fallbackNode = mResourceSystem->getSceneManager()->getInstance(mesh, shieldNode);
if (isEnchanted)
SceneUtil::addEnchantedGlow(shieldNode, mResourceSystem, glowColor);
}
@ -341,20 +338,24 @@ namespace MWRender
if (MWMechanics::getWeaponType(type)->mWeaponClass == ESM::WeaponType::Thrown)
showHolsteredWeapons = false;
std::string mesh = weapon->getClass().getCorrectedModel(*weapon);
std::string_view boneName = getHolsteredWeaponBoneName(*weapon);
if (mesh.empty() || boneName.empty())
const VFS::Path::Normalized mesh = weapon->getClass().getCorrectedModel(*weapon);
if (mesh.empty())
return;
const std::string_view boneName = getHolsteredWeaponBoneName(*weapon);
if (boneName.empty())
return;
// If the scabbard is not found, use the weapon mesh as fallback.
const std::string scabbardName = addSuffixBeforeExtension(mesh, "_sh");
bool isEnchanted = !weapon->getClass().getEnchantment(*weapon).empty();
const VFS::Path::Normalized scabbardName = addSuffixBeforeExtension(mesh, "_sh");
const bool isEnchanted = !weapon->getClass().getEnchantment(*weapon).empty();
if (!mResourceSystem->getVFS()->exists(scabbardName))
{
if (showHolsteredWeapons)
{
osg::Vec4f glowColor = weapon->getClass().getEnchantmentColor(*weapon);
mScabbard = attachMesh(mesh, boneName, isEnchanted, &glowColor);
const osg::Vec4f glowColor
= isEnchanted ? weapon->getClass().getEnchantmentColor(*weapon) : osg::Vec4f();
mScabbard = attachMesh(mesh, boneName, isEnchanted ? &glowColor : nullptr);
if (mScabbard)
resetControllers(mScabbard->getNode());
}

@ -5,6 +5,8 @@
#include <osg/ref_ptr>
#include <components/vfs/pathutil.hpp>
#include "../mwworld/containerstore.hpp"
#include "animation.hpp"
@ -45,21 +47,18 @@ namespace MWRender
protected:
osg::Group* getBoneByName(std::string_view boneName) const;
virtual void updateHolsteredWeapon(bool showHolsteredWeapons);
virtual void updateHolsteredShield(bool showCarriedLeft);
virtual void updateQuiver();
void updateHolsteredWeapon(bool showHolsteredWeapons);
void updateHolsteredShield(bool showCarriedLeft);
void updateQuiver();
std::string getShieldMesh(const MWWorld::ConstPtr& shield, bool female) const;
virtual std::string getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const;
virtual std::string_view getHolsteredWeaponBoneName(const MWWorld::ConstPtr& weapon);
virtual PartHolderPtr attachMesh(
const std::string& model, std::string_view bonename, bool enchantedGlow, osg::Vec4f* glowColor);
virtual PartHolderPtr attachMesh(const std::string& model, std::string_view bonename)
{
osg::Vec4f stubColor = osg::Vec4f(0, 0, 0, 0);
return attachMesh(model, bonename, false, &stubColor);
}
std::string_view getHolsteredWeaponBoneName(const MWWorld::ConstPtr& weapon);
PartHolderPtr attachMesh(
VFS::Path::NormalizedView model, std::string_view bonename, const osg::Vec4f* glowColor = nullptr);
osg::ref_ptr<osg::Node> attach(
const std::string& model, std::string_view bonename, std::string_view bonefilter, bool isLight);
VFS::Path::NormalizedView model, std::string_view bonename, std::string_view bonefilter, bool isLight);
PartHolderPtr mScabbard;
PartHolderPtr mHolsteredShield;

@ -1511,10 +1511,10 @@ namespace MWRender
}
animationPath.replace(animationPath.size() - 4, 4, "/");
for (const auto& name : resourceSystem->getVFS()->getRecursiveDirectoryIterator(animationPath))
for (const VFS::Path::Normalized& name : resourceSystem->getVFS()->getRecursiveDirectoryIterator(animationPath))
{
if (Misc::getFileExtension(name) == "nif")
loadBonesFromFile(node, VFS::Path::toNormalized(name), resourceSystem);
loadBonesFromFile(node, name, resourceSystem);
}
}

@ -111,7 +111,7 @@ namespace MWRender
MWWorld::ConstPtr item = *it;
std::string_view bonename;
std::string itemModel = item.getClass().getCorrectedModel(item);
VFS::Path::Normalized itemModel = item.getClass().getCorrectedModel(item);
if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
{
if (item.getType() == ESM::Weapon::sRecordId)

@ -681,11 +681,11 @@ namespace MWRender
PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, std::string_view bonename,
std::string_view bonefilter, bool enchantedGlow, osg::Vec4f* glowColor, bool isLight)
{
osg::ref_ptr<osg::Node> attached = attach(model, bonename, bonefilter, isLight);
osg::ref_ptr<osg::Node> attached = attach(VFS::Path::toNormalized(model), bonename, bonefilter, isLight);
if (enchantedGlow)
mGlowUpdater = SceneUtil::addEnchantedGlow(attached, mResourceSystem, *glowColor);
return std::make_unique<PartHolder>(attached);
return std::make_unique<PartHolder>(std::move(attached));
}
osg::Vec3f NpcAnimation::runAnimation(float timepassed)

@ -20,6 +20,7 @@
#include <components/esm3/loaddoor.hpp>
#include <components/esm3/loadstat.hpp>
#include <components/esm3/readerscache.hpp>
#include <components/misc/pathhelpers.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/misc/rng.hpp>
#include <components/resource/scenemanager.hpp>
@ -639,7 +640,7 @@ namespace MWRender
continue;
const int type = store.findStatic(ref.mRefId);
std::string model = getModel(type, ref.mRefId, store);
VFS::Path::Normalized model = getModel(type, ref.mRefId, store);
if (model.empty())
continue;
model = Misc::ResourceHelpers::correctMeshPath(model);
@ -647,10 +648,10 @@ namespace MWRender
if (activeGrid && type != ESM::REC_STAT)
{
model = Misc::ResourceHelpers::correctActorModelPath(model, mSceneManager->getVFS());
std::string kfname = Misc::StringUtils::lowerCase(model);
if (kfname.size() > 4 && kfname.ends_with(".nif"))
if (Misc::getFileExtension(model) == "nif")
{
kfname.replace(kfname.size() - 4, 4, ".kf");
VFS::Path::Normalized kfname = model;
kfname.changeExtension("kf");
if (mSceneManager->getVFS()->exists(kfname))
continue;
}
@ -671,7 +672,7 @@ namespace MWRender
->second;
}
osg::ref_ptr<const osg::Node> cnode = mSceneManager->getTemplate(VFS::Path::toNormalized(model), false);
osg::ref_ptr<const osg::Node> cnode = mSceneManager->getTemplate(model, false);
if (activeGrid)
{

@ -1125,19 +1125,19 @@ namespace MWWorld
void Scene::preload(const std::string& mesh, bool useAnim)
{
std::string meshPath = mesh;
if (useAnim)
meshPath = Misc::ResourceHelpers::correctActorModelPath(meshPath, mRendering.getResourceSystem()->getVFS());
const VFS::Path::Normalized meshPath = useAnim
? Misc::ResourceHelpers::correctActorModelPath(mesh, mRendering.getResourceSystem()->getVFS())
: mesh;
if (!mRendering.getResourceSystem()->getSceneManager()->checkLoaded(meshPath, mRendering.getReferenceTime()))
{
osg::ref_ptr<PreloadMeshItem> item(new PreloadMeshItem(
VFS::Path::toNormalized(meshPath), mRendering.getResourceSystem()->getSceneManager()));
mRendering.getWorkQueue()->addWorkItem(item);
const auto isDone = [](const osg::ref_ptr<SceneUtil::WorkItem>& v) { return v->isDone(); };
mWorkItems.erase(std::remove_if(mWorkItems.begin(), mWorkItems.end(), isDone), mWorkItems.end());
mWorkItems.emplace_back(std::move(item));
}
if (mRendering.getResourceSystem()->getSceneManager()->checkLoaded(meshPath, mRendering.getReferenceTime()))
return;
osg::ref_ptr<PreloadMeshItem> item(
new PreloadMeshItem(meshPath, mRendering.getResourceSystem()->getSceneManager()));
mRendering.getWorkQueue()->addWorkItem(item);
const auto isDone = [](const osg::ref_ptr<SceneUtil::WorkItem>& v) { return v->isDone(); };
mWorkItems.erase(std::remove_if(mWorkItems.begin(), mWorkItems.end(), isDone), mWorkItems.end());
mWorkItems.emplace_back(std::move(item));
}
void Scene::preloadCells(float dt)

@ -3644,10 +3644,10 @@ namespace MWWorld
mRendering->spawnEffect(model, texture, worldPosition, 1.0f, false);
}
void World::spawnEffect(const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPos,
float scale, bool isMagicVFX)
void World::spawnEffect(VFS::Path::NormalizedView model, const std::string& textureOverride,
const osg::Vec3f& worldPos, float scale, bool isMagicVFX)
{
mRendering->spawnEffect(VFS::Path::toNormalized(model), textureOverride, worldPos, scale, isMagicVFX);
mRendering->spawnEffect(model, textureOverride, worldPos, scale, isMagicVFX);
}
struct ResetActorsVisitor

@ -7,6 +7,7 @@
#include <components/esm3/readerscache.hpp>
#include <components/misc/rng.hpp>
#include <components/settings/settings.hpp>
#include <components/vfs/pathutil.hpp>
#include "../mwbase/world.hpp"
@ -603,8 +604,8 @@ namespace MWWorld
/// Spawn a blood effect for \a ptr at \a worldPosition
void spawnBloodEffect(const MWWorld::Ptr& ptr, const osg::Vec3f& worldPosition) override;
void spawnEffect(const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPos,
float scale = 1.f, bool isMagicVFX = true) override;
void spawnEffect(VFS::Path::NormalizedView model, const std::string& textureOverride,
const osg::Vec3f& worldPos, float scale = 1.f, bool isMagicVFX = true) override;
/// @see MWWorld::WeatherManager::isInStorm
bool isInStorm() const override;

@ -56,7 +56,7 @@ void ESM::LuaScriptsCfg::load(ESMReader& esm)
{
mScripts.emplace_back();
ESM::LuaScriptCfg& script = mScripts.back();
script.mScriptPath = esm.getHString();
script.mScriptPath = VFS::Path::Normalized(esm.getHString());
esm.getSubNameIs("LUAF");
esm.getSubHeader();
@ -161,7 +161,7 @@ void ESM::LuaScripts::load(ESMReader& esm)
{
while (esm.isNextSub("LUAS"))
{
std::string name = esm.getHString();
VFS::Path::Normalized name(esm.getHString());
std::string data = loadLuaBinaryData(esm);
std::vector<LuaTimer> timers;
while (esm.isNextSub("LUAT"))

@ -320,16 +320,18 @@ namespace ESM4
std::filesystem::path path = strings / (prefix + language + suffix);
if (mVFS != nullptr)
{
std::string vfsPath = Files::pathToUnicodeString(path);
if (!mVFS->exists(vfsPath))
VFS::Path::Normalized vfsPath(Files::pathToUnicodeString(path));
Files::IStreamPtr stream = mVFS->find(vfsPath);
if (stream == nullptr)
{
path = strings / (prefix + altLanguage + suffix);
vfsPath = Files::pathToUnicodeString(path);
vfsPath = VFS::Path::Normalized(Files::pathToUnicodeString(path));
stream = mVFS->find(vfsPath);
}
if (mVFS->exists(vfsPath))
if (stream != nullptr)
{
const Files::IStreamPtr stream = mVFS->get(vfsPath);
buildLStringIndex(stringType, *stream);
return;
}

@ -228,7 +228,7 @@ bool Misc::ResourceHelpers::isHiddenMarker(const ESM::RefId& id)
namespace
{
std::string getLODMeshNameImpl(std::string resPath, const VFS::Manager* vfs, std::string_view pattern)
std::string getLODMeshNameImpl(std::string resPath, std::string_view pattern)
{
if (auto w = Misc::findExtension(resPath); w != std::string::npos)
resPath.insert(w, pattern);
@ -237,7 +237,7 @@ namespace
std::string getBestLODMeshName(std::string const& resPath, const VFS::Manager* vfs, std::string_view pattern)
{
if (const auto& result = getLODMeshNameImpl(resPath, vfs, pattern); vfs->exists(result))
if (std::string result = getLODMeshNameImpl(resPath, pattern); vfs->exists(result))
return result;
return resPath;
}

@ -95,7 +95,7 @@ namespace osgMyGUI
if (!mImageManager)
throw std::runtime_error("No imagemanager set");
osg::ref_ptr<osg::Image> image(mImageManager->getImage(VFS::Path::toNormalized(fname)));
osg::ref_ptr<osg::Image> image(mImageManager->getImage(VFS::Path::Normalized(fname)));
mTexture = new osg::Texture2D(image);
mTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
mTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);

@ -597,9 +597,9 @@ namespace Resource
mShaderManager->setShaderPath(path);
}
bool SceneManager::checkLoaded(const std::string& name, double timeStamp)
bool SceneManager::checkLoaded(VFS::Path::NormalizedView name, double timeStamp)
{
return mCache->checkInObjectCache(VFS::Path::normalizeFilename(name), timeStamp);
return mCache->checkInObjectCache(name, timeStamp);
}
void SceneManager::setUpNormalsRTForStateSet(osg::StateSet* stateset, bool enabled)

@ -152,7 +152,7 @@ namespace Resource
void setShaderPath(const std::filesystem::path& path);
/// Check if a given scene is loaded and if so, update its usage timestamp to prevent it from being unloaded
bool checkLoaded(const std::string& name, double referenceTime);
bool checkLoaded(VFS::Path::NormalizedView name, double referenceTime);
/// Get a read-only copy of this scene "template"
/// @note If the given filename does not exist or fails to load, an error marker mesh will be used instead.

@ -1,7 +1,7 @@
#ifndef COMPONENTS_TERRAIN_DEFS_HPP
#define COMPONENTS_TERRAIN_DEFS_HPP
#include <string>
#include <components/vfs/pathutil.hpp>
namespace Terrain
{
@ -16,8 +16,8 @@ namespace Terrain
struct LayerInfo
{
std::string mDiffuseMap;
std::string mNormalMap;
VFS::Path::Normalized mDiffuseMap;
VFS::Path::Normalized mNormalMap;
bool mParallax; // Height info in normal map alpha channel?
bool mSpecular; // Specular info in diffuse map alpha channel?

@ -35,23 +35,21 @@ namespace Terrain
mCache->call(f);
}
osg::ref_ptr<osg::Texture2D> TextureManager::getTexture(const std::string& name)
osg::ref_ptr<osg::Texture2D> TextureManager::getTexture(VFS::Path::NormalizedView name)
{
// don't bother with case folding, since there is only one way of referring to terrain textures we can assume
// the case is always the same
osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(name);
if (obj)
if (obj != nullptr)
return static_cast<osg::Texture2D*>(obj.get());
else
{
osg::ref_ptr<osg::Texture2D> texture(
new osg::Texture2D(mSceneManager->getImageManager()->getImage(VFS::Path::toNormalized(name))));
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
mSceneManager->applyFilterSettings(texture);
mCache->addEntryToObjectCache(name, texture.get());
return texture;
}
osg::ref_ptr<osg::Texture2D> texture(new osg::Texture2D(mSceneManager->getImageManager()->getImage(name)));
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
mSceneManager->applyFilterSettings(texture);
mCache->addEntryToObjectCache(name.value(), texture.get());
return texture;
}
void TextureManager::reportStats(unsigned int frameNumber, osg::Stats* stats) const

@ -1,9 +1,8 @@
#ifndef OPENMW_COMPONENTS_TERRAIN_TEXTUREMANAGER_H
#define OPENMW_COMPONENTS_TERRAIN_TEXTUREMANAGER_H
#include <string>
#include <components/resource/resourcemanager.hpp>
#include <components/vfs/pathutil.hpp>
namespace Resource
{
@ -25,7 +24,7 @@ namespace Terrain
void updateTextureFiltering();
osg::ref_ptr<osg::Texture2D> getTexture(const std::string& name);
osg::ref_ptr<osg::Texture2D> getTexture(VFS::Path::NormalizedView name);
void reportStats(unsigned int frameNumber, osg::Stats* stats) const override;

Loading…
Cancel
Save