92 lines
2.8 KiB
C++
92 lines
2.8 KiB
C++
#include "app/TextureLoader.h"
|
|
|
|
#include <SDL3_image/SDL_image.h>
|
|
|
|
#include <algorithm>
|
|
#include <mutex>
|
|
#include <sstream>
|
|
|
|
#include "utils/ImagePathResolver.h"
|
|
|
|
TextureLoader::TextureLoader(
|
|
std::atomic<int>& loadedTasks,
|
|
std::string& currentLoadingFile,
|
|
std::mutex& currentLoadingMutex,
|
|
std::vector<std::string>& assetLoadErrors,
|
|
std::mutex& assetLoadErrorsMutex)
|
|
: loadedTasks_(loadedTasks)
|
|
, currentLoadingFile_(currentLoadingFile)
|
|
, currentLoadingMutex_(currentLoadingMutex)
|
|
, assetLoadErrors_(assetLoadErrors)
|
|
, assetLoadErrorsMutex_(assetLoadErrorsMutex)
|
|
{
|
|
}
|
|
|
|
void TextureLoader::setCurrentLoadingFile(const std::string& filename) {
|
|
std::lock_guard<std::mutex> lk(currentLoadingMutex_);
|
|
currentLoadingFile_ = filename;
|
|
}
|
|
|
|
void TextureLoader::clearCurrentLoadingFile() {
|
|
std::lock_guard<std::mutex> lk(currentLoadingMutex_);
|
|
currentLoadingFile_.clear();
|
|
}
|
|
|
|
void TextureLoader::recordAssetLoadError(const std::string& message) {
|
|
std::lock_guard<std::mutex> lk(assetLoadErrorsMutex_);
|
|
assetLoadErrors_.emplace_back(message);
|
|
}
|
|
|
|
SDL_Texture* TextureLoader::loadFromImage(SDL_Renderer* renderer, const std::string& path, int* outW, int* outH) {
|
|
if (!renderer) {
|
|
return nullptr;
|
|
}
|
|
|
|
const std::string resolvedPath = AssetPath::resolveImagePath(path);
|
|
setCurrentLoadingFile(resolvedPath.empty() ? path : resolvedPath);
|
|
|
|
SDL_Surface* surface = IMG_Load(resolvedPath.c_str());
|
|
if (!surface) {
|
|
{
|
|
std::ostringstream ss;
|
|
ss << "Image load failed: " << path << " (" << resolvedPath << "): " << SDL_GetError();
|
|
recordAssetLoadError(ss.str());
|
|
}
|
|
loadedTasks_.fetch_add(1);
|
|
clearCurrentLoadingFile();
|
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load image %s (resolved: %s): %s", path.c_str(), resolvedPath.c_str(), SDL_GetError());
|
|
return nullptr;
|
|
}
|
|
|
|
if (outW) {
|
|
*outW = surface->w;
|
|
}
|
|
if (outH) {
|
|
*outH = surface->h;
|
|
}
|
|
|
|
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
SDL_DestroySurface(surface);
|
|
|
|
if (!texture) {
|
|
{
|
|
std::ostringstream ss;
|
|
ss << "Texture create failed: " << resolvedPath << ": " << SDL_GetError();
|
|
recordAssetLoadError(ss.str());
|
|
}
|
|
loadedTasks_.fetch_add(1);
|
|
clearCurrentLoadingFile();
|
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create texture from %s: %s", resolvedPath.c_str(), SDL_GetError());
|
|
return nullptr;
|
|
}
|
|
|
|
loadedTasks_.fetch_add(1);
|
|
clearCurrentLoadingFile();
|
|
|
|
if (resolvedPath != path) {
|
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Loaded %s via %s", path.c_str(), resolvedPath.c_str());
|
|
}
|
|
|
|
return texture;
|
|
}
|