- Afegir GpuShaderPreset i ShaderManager per carregar shaders des de data/shaders/ - Implementar preset ntsc-md-rainbows (2 passos: encode + decode MAME NTSC) - Render loop multi-pass per shaders externs (targets intermedis R16G16B16A16_FLOAT) - cycleShader(): cicla OFF→PostFX natius→shaders externs amb tecla X - --shader <nom> per arrancar directament amb un preset extern - CMake auto-descubreix i compila data/shaders/**/*.vert/.frag → .spv - HUD F1 mostra 'Shader: <nom>' quan hi ha shader extern actiu Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
69 lines
2.1 KiB
C++
69 lines
2.1 KiB
C++
#include "shader_manager.hpp"
|
|
|
|
#include <SDL3/SDL_log.h>
|
|
#include <filesystem>
|
|
#include <algorithm>
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
void ShaderManager::scan(const std::string& root_dir) {
|
|
root_dir_ = root_dir;
|
|
names_.clear();
|
|
dirs_.clear();
|
|
|
|
std::error_code ec;
|
|
for (const auto& entry : fs::directory_iterator(root_dir, ec)) {
|
|
if (!entry.is_directory()) continue;
|
|
fs::path ini = entry.path() / "preset.ini";
|
|
if (!fs::exists(ini)) continue;
|
|
|
|
std::string preset_name = entry.path().filename().string();
|
|
names_.push_back(preset_name);
|
|
dirs_[preset_name] = entry.path().string();
|
|
}
|
|
|
|
if (ec) {
|
|
SDL_Log("ShaderManager: scan error on %s: %s", root_dir.c_str(), ec.message().c_str());
|
|
}
|
|
|
|
std::sort(names_.begin(), names_.end());
|
|
SDL_Log("ShaderManager: found %d preset(s) in %s", (int)names_.size(), root_dir.c_str());
|
|
}
|
|
|
|
GpuShaderPreset* ShaderManager::load(SDL_GPUDevice* device,
|
|
const std::string& name,
|
|
SDL_GPUTextureFormat swapchain_fmt,
|
|
int w, int h) {
|
|
auto it = loaded_.find(name);
|
|
if (it != loaded_.end()) return it->second.get();
|
|
|
|
auto dir_it = dirs_.find(name);
|
|
if (dir_it == dirs_.end()) {
|
|
SDL_Log("ShaderManager: preset '%s' not found", name.c_str());
|
|
return nullptr;
|
|
}
|
|
|
|
auto preset = std::make_unique<GpuShaderPreset>();
|
|
if (!preset->load(device, dir_it->second, swapchain_fmt, w, h)) {
|
|
SDL_Log("ShaderManager: failed to load preset '%s'", name.c_str());
|
|
return nullptr;
|
|
}
|
|
|
|
GpuShaderPreset* raw = preset.get();
|
|
loaded_[name] = std::move(preset);
|
|
return raw;
|
|
}
|
|
|
|
void ShaderManager::onResize(SDL_GPUDevice* device, SDL_GPUTextureFormat /*swapchain_fmt*/, int w, int h) {
|
|
for (auto& [name, preset] : loaded_) {
|
|
preset->recreateTargets(device, w, h);
|
|
}
|
|
}
|
|
|
|
void ShaderManager::destroyAll(SDL_GPUDevice* device) {
|
|
for (auto& [name, preset] : loaded_) {
|
|
preset->destroy(device);
|
|
}
|
|
loaded_.clear();
|
|
}
|