diff --git a/apps/opencs/view/render/cellwater.cpp b/apps/opencs/view/render/cellwater.cpp index 7589f2c1fc..5ad860b435 100644 --- a/apps/opencs/view/render/cellwater.cpp +++ b/apps/opencs/view/render/cellwater.cpp @@ -176,14 +176,14 @@ namespace CSVRender mWaterGeometry->setStateSet(SceneUtil::createSimpleWaterStateSet(Alpha, RenderBin)); // Add water texture - std::string textureName = "textures/water/"; - textureName += Fallback::Map::getString("Water_SurfaceTexture"); - textureName += "00.dds"; + constexpr VFS::Path::NormalizedView prefix("textures/water"); + VFS::Path::Normalized texturePath(prefix); + texturePath /= std::string(Fallback::Map::getString("Water_SurfaceTexture")) + "00.dds"; Resource::ImageManager* imageManager = mData.getResourceSystem()->getImageManager(); osg::ref_ptr waterTexture = new osg::Texture2D(); - waterTexture->setImage(imageManager->getImage(textureName)); + waterTexture->setImage(imageManager->getImage(texturePath)); waterTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); waterTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index b2b576522f..1816cf8a61 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -2229,9 +2229,10 @@ namespace MWGui ResourceImageSetPointerFix* imgSetPointer = resource->castType(false); if (!imgSetPointer) continue; - auto tex_name = imgSetPointer->getImageSet()->getIndexInfo(0, 0).texture; - osg::ref_ptr image = mResourceSystem->getImageManager()->getImage(tex_name); + const VFS::Path::Normalized path(imgSetPointer->getImageSet()->getIndexInfo(0, 0).texture); + + osg::ref_ptr image = mResourceSystem->getImageManager()->getImage(path); if (image.valid()) { diff --git a/apps/openmw/mwrender/ripplesimulation.cpp b/apps/openmw/mwrender/ripplesimulation.cpp index 3e8a6fd2ec..88a620efd0 100644 --- a/apps/openmw/mwrender/ripplesimulation.cpp +++ b/apps/openmw/mwrender/ripplesimulation.cpp @@ -41,8 +41,8 @@ namespace { std::ostringstream texname; texname << "textures/water/" << tex << std::setw(2) << std::setfill('0') << i << ".dds"; - osg::ref_ptr tex2( - new osg::Texture2D(resourceSystem->getImageManager()->getImage(texname.str()))); + const VFS::Path::Normalized path(texname.str()); + osg::ref_ptr tex2(new osg::Texture2D(resourceSystem->getImageManager()->getImage(path))); tex2->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); tex2->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); resourceSystem->getSceneManager()->applyFilterSettings(tex2); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index c45fadc74f..483de27317 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -403,8 +403,9 @@ namespace MWRender osg::ref_ptr stateset = mRainParticleSystem->getOrCreateStateSet(); + constexpr VFS::Path::NormalizedView raindropImage("textures/tx_raindrop_01.dds"); osg::ref_ptr raindropTex - = new osg::Texture2D(mSceneManager->getImageManager()->getImage("textures/tx_raindrop_01.dds")); + = new osg::Texture2D(mSceneManager->getImageManager()->getImage(raindropImage)); raindropTex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); raindropTex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); @@ -768,7 +769,8 @@ namespace MWRender { mClouds = weather.mCloudTexture; - std::string texture = Misc::ResourceHelpers::correctTexturePath(mClouds, mSceneManager->getVFS()); + const VFS::Path::Normalized texture + = Misc::ResourceHelpers::correctTexturePath(mClouds, mSceneManager->getVFS()); osg::ref_ptr cloudTex = new osg::Texture2D(mSceneManager->getImageManager()->getImage(texture)); @@ -790,7 +792,8 @@ namespace MWRender if (!mNextClouds.empty()) { - std::string texture = Misc::ResourceHelpers::correctTexturePath(mNextClouds, mSceneManager->getVFS()); + const VFS::Path::Normalized texture + = Misc::ResourceHelpers::correctTexturePath(mNextClouds, mSceneManager->getVFS()); osg::ref_ptr cloudTex = new osg::Texture2D(mSceneManager->getImageManager()->getImage(texture)); diff --git a/apps/openmw/mwrender/skyutil.cpp b/apps/openmw/mwrender/skyutil.cpp index faa0566016..2881f51d4c 100644 --- a/apps/openmw/mwrender/skyutil.cpp +++ b/apps/openmw/mwrender/skyutil.cpp @@ -406,7 +406,7 @@ namespace MWRender } } - void setTextures(const std::string& phaseTex, const std::string& circleTex) + void setTextures(VFS::Path::NormalizedView phaseTex, VFS::Path::NormalizedView circleTex) { mPhaseTex = new osg::Texture2D(mImageManager.getImage(phaseTex)); mPhaseTex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); @@ -766,7 +766,9 @@ namespace MWRender Resource::ImageManager& imageManager = *sceneManager.getImageManager(); - osg::ref_ptr sunTex = new osg::Texture2D(imageManager.getImage("textures/tx_sun_05.dds")); + constexpr VFS::Path::NormalizedView image("textures/tx_sun_05.dds"); + + osg::ref_ptr sunTex = new osg::Texture2D(imageManager.getImage(image)); sunTex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); sunTex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); @@ -907,8 +909,8 @@ namespace MWRender void Sun::createSunFlash(Resource::ImageManager& imageManager) { - osg::ref_ptr tex - = new osg::Texture2D(imageManager.getImage("textures/tx_sun_flash_grey_05.dds")); + constexpr VFS::Path::NormalizedView image("textures/tx_sun_flash_grey_05.dds"); + osg::ref_ptr tex = new osg::Texture2D(imageManager.getImage(image)); tex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); tex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); @@ -1115,10 +1117,18 @@ namespace MWRender textureName += ".dds"; + const VFS::Path::Normalized texturePath(std::move(textureName)); + if (mType == Moon::Type_Secunda) - mUpdater->setTextures(textureName, "textures/tx_mooncircle_full_s.dds"); + { + constexpr VFS::Path::NormalizedView secunda("textures/tx_mooncircle_full_s.dds"); + mUpdater->setTextures(texturePath, secunda); + } else - mUpdater->setTextures(textureName, "textures/tx_mooncircle_full_m.dds"); + { + constexpr VFS::Path::NormalizedView masser("textures/tx_mooncircle_full_m.dds"); + mUpdater->setTextures(texturePath, masser); + } } int RainCounter::numParticlesToCreate(double dt) const diff --git a/apps/openmw/mwrender/util.cpp b/apps/openmw/mwrender/util.cpp index 019484eebd..c2231c31f8 100644 --- a/apps/openmw/mwrender/util.cpp +++ b/apps/openmw/mwrender/util.cpp @@ -49,7 +49,8 @@ namespace MWRender { if (texture.empty()) return; - std::string correctedTexture = Misc::ResourceHelpers::correctTexturePath(texture, resourceSystem->getVFS()); + const VFS::Path::Normalized correctedTexture + = Misc::ResourceHelpers::correctTexturePath(texture, resourceSystem->getVFS()); // Not sure if wrap settings should be pulled from the overridden texture? osg::ref_ptr tex = new osg::Texture2D(resourceSystem->getImageManager()->getImage(correctedTexture)); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 1b8b307d21..81e44248ac 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -589,8 +589,8 @@ namespace MWRender { std::ostringstream texname; texname << "textures/water/" << texture << std::setw(2) << std::setfill('0') << i << ".dds"; - osg::ref_ptr tex( - new osg::Texture2D(mResourceSystem->getImageManager()->getImage(texname.str()))); + const VFS::Path::Normalized path(texname.str()); + osg::ref_ptr tex(new osg::Texture2D(mResourceSystem->getImageManager()->getImage(path))); tex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); tex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); mResourceSystem->getSceneManager()->applyFilterSettings(tex); @@ -703,8 +703,9 @@ namespace MWRender Shader::ShaderManager& shaderMgr = mResourceSystem->getSceneManager()->getShaderManager(); osg::ref_ptr program = shaderMgr.getProgram("water", defineMap); + constexpr VFS::Path::NormalizedView waterImage("textures/omw/water_nm.png"); osg::ref_ptr normalMap( - new osg::Texture2D(mResourceSystem->getImageManager()->getImage("textures/omw/water_nm.png"))); + new osg::Texture2D(mResourceSystem->getImageManager()->getImage(waterImage))); normalMap->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); normalMap->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); mResourceSystem->getSceneManager()->applyFilterSettings(normalMap); diff --git a/components/fx/technique.cpp b/components/fx/technique.cpp index 73355de9a5..c99d30a1de 100644 --- a/components/fx/technique.cpp +++ b/components/fx/technique.cpp @@ -445,7 +445,8 @@ namespace fx else if (key == "source") { expect(); - auto image = mImageManager.getImage(std::string{ std::get(mToken).value }, is3D); + const osg::ref_ptr image + = mImageManager.getImage(VFS::Path::Normalized(std::get(mToken).value), is3D); if constexpr (is1D) { type = Types::SamplerType::Texture_1D; diff --git a/components/myguiplatform/myguitexture.cpp b/components/myguiplatform/myguitexture.cpp index 26127cf39a..fe2b700049 100644 --- a/components/myguiplatform/myguitexture.cpp +++ b/components/myguiplatform/myguitexture.cpp @@ -95,7 +95,7 @@ namespace osgMyGUI if (!mImageManager) throw std::runtime_error("No imagemanager set"); - osg::ref_ptr image(mImageManager->getImage(fname)); + osg::ref_ptr image(mImageManager->getImage(VFS::Path::toNormalized(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); diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 6ec0fe51e0..ad3ba12070 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1022,8 +1022,8 @@ namespace NifOsg if (!mImageManager) return nullptr; - std::string filename = Misc::ResourceHelpers::correctTexturePath(path, mImageManager->getVFS()); - return mImageManager->getImage(filename); + return mImageManager->getImage( + VFS::Path::toNormalized(Misc::ResourceHelpers::correctTexturePath(path, mImageManager->getVFS()))); } osg::ref_ptr attachTexture(const std::string& name, osg::ref_ptr image, bool wrapS, diff --git a/components/resource/imagemanager.cpp b/components/resource/imagemanager.cpp index e7cc9f03e5..b7a19b4d52 100644 --- a/components/resource/imagemanager.cpp +++ b/components/resource/imagemanager.cpp @@ -85,11 +85,9 @@ namespace Resource return true; } - osg::ref_ptr ImageManager::getImage(std::string_view filename, bool disableFlip) + osg::ref_ptr ImageManager::getImage(VFS::Path::NormalizedView path, bool disableFlip) { - const std::string normalized = VFS::Path::normalizeFilename(filename); - - osg::ref_ptr obj = mCache->getRefFromObjectCache(normalized); + osg::ref_ptr obj = mCache->getRefFromObjectCache(path); if (obj) return osg::ref_ptr(static_cast(obj.get())); else @@ -97,21 +95,21 @@ namespace Resource Files::IStreamPtr stream; try { - stream = mVFS->get(normalized); + stream = mVFS->get(path); } catch (std::exception& e) { Log(Debug::Error) << "Failed to open image: " << e.what(); - mCache->addEntryToObjectCache(normalized, mWarningImage); + mCache->addEntryToObjectCache(path.value(), mWarningImage); return mWarningImage; } - const std::string ext(Misc::getFileExtension(normalized)); + const std::string ext(Misc::getFileExtension(path.value())); osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension(ext); if (!reader) { - Log(Debug::Error) << "Error loading " << filename << ": no readerwriter for '" << ext << "' found"; - mCache->addEntryToObjectCache(normalized, mWarningImage); + Log(Debug::Error) << "Error loading " << path << ": no readerwriter for '" << ext << "' found"; + mCache->addEntryToObjectCache(path.value(), mWarningImage); return mWarningImage; } @@ -123,8 +121,8 @@ namespace Resource stream->read((char*)header, 18); if (stream->gcount() != 18) { - Log(Debug::Error) << "Error loading " << filename << ": couldn't read TGA header"; - mCache->addEntryToObjectCache(normalized, mWarningImage); + Log(Debug::Error) << "Error loading " << path << ": couldn't read TGA header"; + mCache->addEntryToObjectCache(path.value(), mWarningImage); return mWarningImage; } int type = header[2]; @@ -142,23 +140,22 @@ namespace Resource = reader->readImage(*stream, disableFlip ? mOptionsNoFlip : mOptions); if (!result.success()) { - Log(Debug::Error) << "Error loading " << filename << ": " << result.message() << " code " + Log(Debug::Error) << "Error loading " << path << ": " << result.message() << " code " << result.status(); - mCache->addEntryToObjectCache(normalized, mWarningImage); + mCache->addEntryToObjectCache(path.value(), mWarningImage); return mWarningImage; } osg::ref_ptr image = result.getImage(); - image->setFileName(normalized); + image->setFileName(std::string(path.value())); if (!checkSupported(image)) { static bool uncompress = (getenv("OPENMW_DECOMPRESS_TEXTURES") != nullptr); if (!uncompress) { - Log(Debug::Error) << "Error loading " << filename - << ": no S3TC texture compression support installed"; - mCache->addEntryToObjectCache(normalized, mWarningImage); + Log(Debug::Error) << "Error loading " << path << ": no S3TC texture compression support installed"; + mCache->addEntryToObjectCache(path.value(), mWarningImage); return mWarningImage; } else @@ -189,7 +186,7 @@ namespace Resource image = newImage; } - mCache->addEntryToObjectCache(normalized, image); + mCache->addEntryToObjectCache(path.value(), image); return image; } } diff --git a/components/resource/imagemanager.hpp b/components/resource/imagemanager.hpp index 2fad70d576..ead55c792a 100644 --- a/components/resource/imagemanager.hpp +++ b/components/resource/imagemanager.hpp @@ -1,13 +1,12 @@ #ifndef OPENMW_COMPONENTS_RESOURCE_IMAGEMANAGER_H #define OPENMW_COMPONENTS_RESOURCE_IMAGEMANAGER_H -#include -#include - #include #include #include +#include + #include "resourcemanager.hpp" namespace osgDB @@ -28,7 +27,7 @@ namespace Resource /// Create or retrieve an Image /// Returns the dummy image if the given image is not found. - osg::ref_ptr getImage(std::string_view filename, bool disableFlip = false); + osg::ref_ptr getImage(VFS::Path::NormalizedView path, bool disableFlip = false); osg::Image* getWarningImage(); diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index 281a21d860..9feab669a9 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -627,7 +627,8 @@ namespace Resource filePath = std::filesystem::relative(filename, osgDB::getCurrentWorkingDirectory()); try { - return osgDB::ReaderWriter::ReadResult(mImageManager->getImage(Files::pathToUnicodeString(filePath)), + return osgDB::ReaderWriter::ReadResult( + mImageManager->getImage(VFS::Path::toNormalized(Files::pathToUnicodeString(filePath))), osgDB::ReaderWriter::ReadResult::FILE_LOADED); } catch (std::exception& e) diff --git a/components/sceneutil/util.cpp b/components/sceneutil/util.cpp index 2ad4c92ab5..ed891f835e 100644 --- a/components/sceneutil/util.cpp +++ b/components/sceneutil/util.cpp @@ -221,7 +221,7 @@ namespace SceneUtil std::vector> textures; for (const std::string& name : glowTextureNames) { - osg::ref_ptr image = resourceSystem->getImageManager()->getImage(name); + osg::ref_ptr image = resourceSystem->getImageManager()->getImage(VFS::Path::toNormalized(name)); osg::ref_ptr tex(new osg::Texture2D(image)); tex->setWrap(osg::Texture::WRAP_S, osg::Texture2D::REPEAT); tex->setWrap(osg::Texture::WRAP_T, osg::Texture2D::REPEAT); diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index 2e4035a990..63ee6cb41f 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -404,17 +404,19 @@ namespace Shader bool normalHeight = false; std::string normalHeightMap = normalMapFileName; Misc::StringUtils::replaceLast(normalHeightMap, ".", mNormalHeightMapPattern + "."); - if (mImageManager.getVFS()->exists(normalHeightMap)) + const VFS::Path::Normalized normalHeightMapPath(normalHeightMap); + if (mImageManager.getVFS()->exists(normalHeightMapPath)) { - image = mImageManager.getImage(normalHeightMap); + image = mImageManager.getImage(normalHeightMapPath); normalHeight = true; } else { Misc::StringUtils::replaceLast(normalMapFileName, ".", mNormalMapPattern + "."); - if (mImageManager.getVFS()->exists(normalMapFileName)) + const VFS::Path::Normalized normalMapPath(normalMapFileName); + if (mImageManager.getVFS()->exists(normalMapPath)) { - image = mImageManager.getImage(normalMapFileName); + image = mImageManager.getImage(normalMapPath); } } // Avoid using the auto-detected normal map if it's already being used as a bump map. @@ -464,9 +466,10 @@ namespace Shader { std::string specularMapFileName = diffuseMap->getImage(0)->getFileName(); Misc::StringUtils::replaceLast(specularMapFileName, ".", mSpecularMapPattern + "."); - if (mImageManager.getVFS()->exists(specularMapFileName)) + const VFS::Path::Normalized specularMapPath(specularMapFileName); + if (mImageManager.getVFS()->exists(specularMapPath)) { - osg::ref_ptr image(mImageManager.getImage(specularMapFileName)); + osg::ref_ptr image(mImageManager.getImage(specularMapPath)); osg::ref_ptr specularMapTex(new osg::Texture2D(image)); specularMapTex->setTextureSize(image->s(), image->t()); specularMapTex->setWrap(osg::Texture::WRAP_S, diffuseMap->getWrap(osg::Texture::WRAP_S)); diff --git a/components/terrain/texturemanager.cpp b/components/terrain/texturemanager.cpp index 6b388faf69..8df880fab0 100644 --- a/components/terrain/texturemanager.cpp +++ b/components/terrain/texturemanager.cpp @@ -44,7 +44,8 @@ namespace Terrain return static_cast(obj.get()); else { - osg::ref_ptr texture(new osg::Texture2D(mSceneManager->getImageManager()->getImage(name))); + osg::ref_ptr 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);