Fix texture loading if casing mismatches filename

Always use lower-case unqualified names to find and cache the actual textures.
This commit is contained in:
Kai Blaschke
2024-10-07 12:08:44 +02:00
parent f6ff7943c1
commit f2a0277ddd
8 changed files with 77 additions and 34 deletions

View File

@ -23,6 +23,8 @@ add_library(projectM_main OBJECT
ProjectMCWrapper.hpp
TimeKeeper.cpp
TimeKeeper.hpp
Utils.cpp
Utils.hpp
projectM-opengl.h
)

View File

@ -2,6 +2,7 @@
#include "PerFrameContext.hpp"
#include "PresetState.hpp"
#include "Utils.hpp"
#include <MilkdropStaticShaders.hpp>
@ -69,8 +70,7 @@ void MilkdropShader::LoadTexturesAndCompile(PresetState& presetState)
baseName = name.substr(3);
}
std::string lowerCaseName(baseName);
std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), tolower);
std::string lowerCaseName = Utils::ToLower(baseName);
// The "main" and "blurX" textures are preset-specific and are not managed by TextureManager.
if (lowerCaseName == "main")

View File

@ -2,6 +2,8 @@
#include <MilkdropPreset/Factory.hpp>
#include <Utils.hpp>
#include <algorithm>
#include <cassert>
#include <iostream>
@ -135,9 +137,8 @@ auto PresetFactoryManager::ParseExtension(const std::string& filename) -> std::s
if (start == std::string::npos || start >= (filename.length() - 1)) {
return "";
}
std::string ext = filename.substr(start + 1, filename.length());
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
return ext;
return Utils::ToLower(filename.substr(start + 1, filename.length()));
}
} // namespace libprojectM

View File

@ -1,5 +1,7 @@
#include "FileScanner.hpp"
#include "Utils.hpp"
#include <algorithm>
#include <cctype>
@ -17,7 +19,7 @@ FileScanner::FileScanner(const std::vector<std::string>& rootDirs, std::vector<s
// Convert all extensions to lower-case.
for (auto& extension : _extensions)
{
std::transform(extension.begin(), extension.end(), extension.begin(), [](unsigned char c) { return std::tolower(c); });
Utils::ToLowerInPlace(extension);
}
}
@ -59,8 +61,7 @@ void FileScanner::Scan(ScanCallback callback)
}
// Match the lower-case extension of the file with the provided list of valid extensions.
auto extension = entry.path().extension().string();
std::transform(extension.begin(), extension.end(), extension.begin(), [](unsigned char c) { return std::tolower(c); });
auto extension = Utils::ToLower(entry.path().extension().string());
if (std::find(_extensions.begin(), _extensions.end(), extension) != _extensions.end())
{
callback(entry.path().string(), entry.path().stem().string());

View File

@ -4,6 +4,7 @@
#include "IdleTextures.hpp"
#include "MilkdropNoise.hpp"
#include "Texture.hpp"
#include "Utils.hpp"
#include <SOIL2/SOIL2.h>
@ -165,7 +166,6 @@ void TextureManager::PurgeTextures()
auto TextureManager::TryLoadingTexture(const std::string& name) -> TextureSamplerDescriptor
{
TextureSamplerDescriptor texDesc;
GLint wrapMode{0};
GLint filterMode{0};
std::string unqualifiedName;
@ -174,24 +174,22 @@ auto TextureManager::TryLoadingTexture(const std::string& name) -> TextureSample
ScanTextures();
std::string lowerCaseFileName(name);
std::transform(lowerCaseFileName.begin(), lowerCaseFileName.end(), lowerCaseFileName.begin(), tolower);
std::string lowerCaseUnqualifiedName = Utils::ToLower(unqualifiedName);
for (const auto& file : m_scannedTextureFiles)
{
if (file.lowerCaseBaseName != unqualifiedName)
if (file.lowerCaseBaseName != lowerCaseUnqualifiedName)
{
continue;
}
texDesc = LoadTexture(file.filePath, name);
auto texture = LoadTexture(file);
if (!texDesc.Empty())
if (texture)
{
#ifdef DEBUG
std::cerr << "Loaded texture " << unqualifiedName << std::endl;
#endif
return texDesc;
return {texture, m_samplers.at({wrapMode, filterMode}), name, unqualifiedName};;
}
}
@ -203,24 +201,20 @@ auto TextureManager::TryLoadingTexture(const std::string& name) -> TextureSample
return {m_placeholderTexture, m_samplers.at({wrapMode, filterMode}), name, unqualifiedName};
}
auto TextureManager::LoadTexture(const std::string& fileName, const std::string& name) -> TextureSamplerDescriptor
auto TextureManager::LoadTexture(const ScannedFile& file) -> std::shared_ptr<Texture>
{
GLint wrapMode;
GLint filterMode;
std::string unqualifiedName;
ExtractTextureSettings(name, wrapMode, filterMode, unqualifiedName);
auto sampler = m_samplers.at({wrapMode, filterMode});
if (m_textures.find(name) != m_textures.end())
if (m_textures.find(file.lowerCaseBaseName) != m_textures.end())
{
return {m_textures.at(name), sampler, name, unqualifiedName};
return m_textures.at(file.lowerCaseBaseName);
}
int width{};
int height{};
unsigned int const tex = SOIL_load_OGL_texture(
fileName.c_str(),
file.filePath.c_str(),
SOIL_LOAD_RGBA,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MULTIPLY_ALPHA, &width, &height);
@ -232,10 +226,10 @@ auto TextureManager::LoadTexture(const std::string& fileName, const std::string&
uint32_t memoryBytes = width * height * 4; // RGBA, unsigned byte color channels.
auto newTexture = std::make_shared<Texture>(unqualifiedName, tex, GL_TEXTURE_2D, width, height, true);
m_textures[name] = newTexture;
m_textureStats.insert({name, {memoryBytes}});
m_textures[file.lowerCaseBaseName] = newTexture;
m_textureStats.insert({file.lowerCaseBaseName, {memoryBytes}});
return {newTexture, sampler, name, unqualifiedName};
return newTexture;
}
auto TextureManager::GetRandomTexture(const std::string& randomName) -> TextureSamplerDescriptor
@ -247,8 +241,7 @@ auto TextureManager::GetRandomTexture(const std::string& randomName) -> TextureS
ScanTextures();
std::string lowerCaseName(randomName);
std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), tolower);
std::string lowerCaseName = Utils::ToLower(randomName);
if (m_scannedTextureFiles.empty())
{
@ -300,8 +293,7 @@ auto TextureManager::GetRandomTexture(const std::string& randomName) -> TextureS
void TextureManager::AddTextureFile(const std::string& fileName, const std::string& baseName)
{
std::string lowerCaseBaseName(baseName);
std::transform(lowerCaseBaseName.begin(), lowerCaseBaseName.end(), lowerCaseBaseName.begin(), tolower);
std::string lowerCaseBaseName = Utils::ToLower(baseName);
ScannedFile file;
file.filePath = fileName;
@ -320,8 +312,7 @@ void TextureManager::ExtractTextureSettings(const std::string& qualifiedName, GL
return;
}
std::string lowerQualifiedName(qualifiedName);
std::transform(lowerQualifiedName.begin(), lowerQualifiedName.end(), lowerQualifiedName.begin(), tolower);
std::string lowerQualifiedName = Utils::ToLower(qualifiedName);
// Default mode for user textures is "fw" (bilinear filtering + wrap).
wrapMode = GL_REPEAT;

View File

@ -82,7 +82,7 @@ private:
void Preload();
TextureSamplerDescriptor LoadTexture(const std::string& fileName, const std::string& name);
auto LoadTexture(const ScannedFile& file) -> std::shared_ptr<Texture>;
void AddTextureFile(const std::string& fileName, const std::string& baseName);

33
src/libprojectM/Utils.cpp Normal file
View File

@ -0,0 +1,33 @@
#include "Utils.hpp"
#include <algorithm>
namespace libprojectM {
namespace Utils {
auto ToLower(const std::string& str) -> std::string
{
std::string lowerStr(str);
ToLowerInPlace(lowerStr);
return lowerStr;
}
auto ToUpper(const std::string& str) -> std::string
{
std::string upperStr(str);
ToUpperInPlace(upperStr);
return upperStr;
}
void ToLowerInPlace(std::string& str)
{
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
}
void ToUpperInPlace(std::string& str)
{
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
}
} // namespace Utils
} // namespace libprojectM

15
src/libprojectM/Utils.hpp Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <string>
namespace libprojectM {
namespace Utils {
auto ToLower(const std::string& str) -> std::string;
auto ToUpper(const std::string& str) -> std::string;
void ToLowerInPlace(std::string& str);
void ToUpperInPlace(std::string& str);
} // namespace Utils
} // namespace libprojectM