refactor: eliminar sistema de shaders externos (ShaderManager + GpuShaderPreset)
Elimina el sistema multi-pass de shaders runtime en favor del PostFX nativo. Queda solo el ciclo de 5 modos nativos: OFF → Vinyeta → Scanlines → Cromàtica → Complet. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -354,26 +354,6 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen, AppMod
|
||||
delete[] tmp;
|
||||
}
|
||||
|
||||
// Inicializar ShaderManager (shaders externos desde data/shaders/)
|
||||
if (gpu_ctx_ && success) {
|
||||
shader_manager_ = std::make_unique<ShaderManager>();
|
||||
std::string shaders_dir = getResourcesDirectory() + "/data/shaders";
|
||||
shader_manager_->scan(shaders_dir);
|
||||
|
||||
// Si se especificó --shader, activar el preset inicial
|
||||
if (!initial_shader_name_.empty()) {
|
||||
active_shader_ = shader_manager_->load(
|
||||
gpu_ctx_->device(),
|
||||
initial_shader_name_,
|
||||
gpu_ctx_->swapchainFormat(),
|
||||
current_screen_width_, current_screen_height_);
|
||||
if (active_shader_) {
|
||||
const auto& names = shader_manager_->names();
|
||||
auto it = std::find(names.begin(), names.end(), initial_shader_name_);
|
||||
active_shader_idx_ = (it != names.end()) ? (int)(it - names.begin()) : -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
@@ -408,7 +388,6 @@ void Engine::shutdown() {
|
||||
if (sprite_batch_) { sprite_batch_->destroy(gpu_ctx_->device()); sprite_batch_.reset(); }
|
||||
if (gpu_ball_buffer_) { gpu_ball_buffer_->destroy(gpu_ctx_->device()); gpu_ball_buffer_.reset(); }
|
||||
if (gpu_pipeline_) { gpu_pipeline_->destroy(gpu_ctx_->device()); gpu_pipeline_.reset(); }
|
||||
if (shader_manager_) { shader_manager_->destroyAll(gpu_ctx_->device()); shader_manager_.reset(); }
|
||||
}
|
||||
|
||||
// Destroy software UI renderer and surface
|
||||
@@ -903,75 +882,7 @@ void Engine::render() {
|
||||
SDL_SetGPUScissor(rp, &scissor);
|
||||
};
|
||||
|
||||
if (active_shader_ != nullptr) {
|
||||
// --- External multi-pass shader ---
|
||||
NTSCParams ntsc = {};
|
||||
ntsc.source_width = static_cast<float>(current_screen_width_);
|
||||
ntsc.source_height = static_cast<float>(current_screen_height_);
|
||||
ntsc.a_value = active_shader_->param("avalue", 0.0f);
|
||||
ntsc.b_value = active_shader_->param("bvalue", 0.0f);
|
||||
ntsc.cc_value = active_shader_->param("ccvalue", 3.5795455f);
|
||||
ntsc.scan_time = active_shader_->param("scantime", 47.9f);
|
||||
ntsc.notch_width = active_shader_->param("notch_width", 3.45f);
|
||||
ntsc.y_freq = active_shader_->param("yfreqresponse", 1.75f);
|
||||
ntsc.i_freq = active_shader_->param("ifreqresponse", 1.75f);
|
||||
ntsc.q_freq = active_shader_->param("qfreqresponse", 1.45f);
|
||||
|
||||
SDL_GPUTexture* current_input = offscreen_tex_->texture();
|
||||
SDL_GPUSampler* current_samp = offscreen_tex_->sampler();
|
||||
|
||||
for (int pi = 0; pi < active_shader_->passCount(); ++pi) {
|
||||
ShaderPass& sp = active_shader_->pass(pi);
|
||||
bool is_last = (pi == active_shader_->passCount() - 1);
|
||||
|
||||
SDL_GPUTexture* target_tex = is_last ? swapchain : sp.target->texture();
|
||||
SDL_GPULoadOp load_op = SDL_GPU_LOADOP_CLEAR;
|
||||
|
||||
SDL_GPUColorTargetInfo ct = {};
|
||||
ct.texture = target_tex;
|
||||
ct.load_op = load_op;
|
||||
ct.clear_color = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
ct.store_op = SDL_GPU_STOREOP_STORE;
|
||||
|
||||
SDL_GPURenderPass* ext_pass = SDL_BeginGPURenderPass(cmd, &ct, 1, nullptr);
|
||||
if (is_last) applyViewport(ext_pass);
|
||||
|
||||
SDL_BindGPUGraphicsPipeline(ext_pass, sp.pipeline);
|
||||
SDL_GPUTextureSamplerBinding src_tsb = {current_input, current_samp};
|
||||
SDL_BindGPUFragmentSamplers(ext_pass, 0, &src_tsb, 1);
|
||||
SDL_PushGPUFragmentUniformData(cmd, 0, &ntsc, sizeof(NTSCParams));
|
||||
SDL_DrawGPUPrimitives(ext_pass, 3, 1, 0, 0);
|
||||
|
||||
SDL_EndGPURenderPass(ext_pass);
|
||||
|
||||
if (!is_last) {
|
||||
current_input = sp.target->texture();
|
||||
current_samp = sp.target->sampler();
|
||||
}
|
||||
}
|
||||
|
||||
// Re-open swapchain pass for UI overlay
|
||||
SDL_GPUColorTargetInfo ct_ui = {};
|
||||
ct_ui.texture = swapchain;
|
||||
ct_ui.load_op = SDL_GPU_LOADOP_LOAD; // preserve shader output
|
||||
ct_ui.store_op = SDL_GPU_STOREOP_STORE;
|
||||
SDL_GPURenderPass* pass2 = SDL_BeginGPURenderPass(cmd, &ct_ui, 1, nullptr);
|
||||
applyViewport(pass2);
|
||||
|
||||
if (ui_tex_ && ui_tex_->isValid() && sprite_batch_->overlayIndexCount() > 0) {
|
||||
SDL_BindGPUGraphicsPipeline(pass2, gpu_pipeline_->spritePipeline());
|
||||
SDL_GPUBufferBinding vb = {sprite_batch_->vertexBuffer(), 0};
|
||||
SDL_GPUBufferBinding ib = {sprite_batch_->indexBuffer(), 0};
|
||||
SDL_BindGPUVertexBuffers(pass2, 0, &vb, 1);
|
||||
SDL_BindGPUIndexBuffer(pass2, &ib, SDL_GPU_INDEXELEMENTSIZE_32BIT);
|
||||
SDL_GPUTextureSamplerBinding ui_tsb = {ui_tex_->texture(), ui_tex_->sampler()};
|
||||
SDL_BindGPUFragmentSamplers(pass2, 0, &ui_tsb, 1);
|
||||
SDL_DrawGPUIndexedPrimitives(pass2, sprite_batch_->overlayIndexCount(), 1,
|
||||
sprite_batch_->overlayIndexOffset(), 0, 0);
|
||||
}
|
||||
SDL_EndGPURenderPass(pass2);
|
||||
|
||||
} else {
|
||||
{
|
||||
// --- Native PostFX path ---
|
||||
SDL_GPUColorTargetInfo ct = {};
|
||||
ct.texture = swapchain;
|
||||
@@ -1003,7 +914,7 @@ void Engine::render() {
|
||||
}
|
||||
|
||||
SDL_EndGPURenderPass(pass2);
|
||||
} // end else (native PostFX)
|
||||
} // end native PostFX
|
||||
} // end if (swapchain && ...)
|
||||
|
||||
gpu_ctx_->submit(cmd);
|
||||
@@ -1155,7 +1066,6 @@ void Engine::applyPostFXPreset(int mode) {
|
||||
}
|
||||
|
||||
void Engine::handlePostFXCycle() {
|
||||
// Delegate to cycleShader() which handles both native PostFX and external shaders
|
||||
cycleShader();
|
||||
}
|
||||
|
||||
@@ -1164,16 +1074,6 @@ void Engine::handlePostFXToggle() {
|
||||
"PostFX: Vinyeta", "PostFX: Scanlines",
|
||||
"PostFX: Cromàtica", "PostFX: Complet"
|
||||
};
|
||||
// If external shader is active, toggle it off
|
||||
if (active_shader_) {
|
||||
active_shader_ = nullptr;
|
||||
active_shader_idx_ = 0; // reset to OFF
|
||||
postfx_uniforms_.vignette_strength = 0.0f;
|
||||
postfx_uniforms_.chroma_strength = 0.0f;
|
||||
postfx_uniforms_.scanline_strength = 0.0f;
|
||||
showNotificationForAction("PostFX: Desactivat");
|
||||
return;
|
||||
}
|
||||
postfx_enabled_ = !postfx_enabled_;
|
||||
if (postfx_enabled_) {
|
||||
applyPostFXPreset(postfx_effect_mode_);
|
||||
@@ -1201,81 +1101,25 @@ void Engine::setPostFXParamOverrides(float vignette, float chroma) {
|
||||
if (chroma >= 0.f) postfx_uniforms_.chroma_strength = chroma;
|
||||
}
|
||||
|
||||
void Engine::setInitialShader(const std::string& name) {
|
||||
initial_shader_name_ = name;
|
||||
}
|
||||
|
||||
void Engine::cycleShader() {
|
||||
// Cycle order:
|
||||
// native OFF → native Vinyeta → Scanlines → Cromàtica → Complet →
|
||||
// ext shader 0 → ext shader 1 → ... → native OFF → ...
|
||||
if (!shader_manager_) {
|
||||
// No shader manager: fall back to native PostFX cycle
|
||||
handlePostFXCycle();
|
||||
return;
|
||||
}
|
||||
|
||||
// active_shader_idx_ is a 0-based cycle counter:
|
||||
// -1 = uninitialized (first press → index 0 = OFF)
|
||||
// 0 = OFF
|
||||
// 1 = PostFX Vinyeta, 2 = Scanlines, 3 = Cromàtica, 4 = Complet
|
||||
// 5..4+num_ext = external shaders (0-based into names())
|
||||
const int num_native = 5; // 0=OFF, 1..4=PostFX modes
|
||||
const int num_ext = static_cast<int>(shader_manager_->names().size());
|
||||
const int total = num_native + num_ext;
|
||||
|
||||
static const char* native_names[5] = {
|
||||
static const char* names[5] = {
|
||||
"PostFX: Desactivat", "PostFX: Vinyeta", "PostFX: Scanlines",
|
||||
"PostFX: Cromàtica", "PostFX: Complet"
|
||||
};
|
||||
postfx_cycle_idx_ = (postfx_cycle_idx_ + 1) % 5;
|
||||
int cycle = postfx_cycle_idx_;
|
||||
|
||||
// Advance and wrap
|
||||
int cycle = active_shader_idx_ + 1;
|
||||
if (cycle < 0 || cycle >= total) cycle = 0;
|
||||
active_shader_idx_ = cycle;
|
||||
|
||||
if (cycle < num_native) {
|
||||
// Native PostFX
|
||||
active_shader_ = nullptr;
|
||||
if (cycle == 0) {
|
||||
postfx_enabled_ = false;
|
||||
postfx_uniforms_.vignette_strength = 0.0f;
|
||||
postfx_uniforms_.chroma_strength = 0.0f;
|
||||
postfx_uniforms_.scanline_strength = 0.0f;
|
||||
} else {
|
||||
postfx_enabled_ = true;
|
||||
postfx_effect_mode_ = cycle - 1; // 0..3
|
||||
applyPostFXPreset(postfx_effect_mode_);
|
||||
}
|
||||
showNotificationForAction(native_names[cycle]);
|
||||
if (cycle == 0) {
|
||||
postfx_enabled_ = false;
|
||||
postfx_uniforms_.vignette_strength = 0.0f;
|
||||
postfx_uniforms_.chroma_strength = 0.0f;
|
||||
postfx_uniforms_.scanline_strength = 0.0f;
|
||||
} else {
|
||||
// External shader
|
||||
int ext_idx = cycle - num_native;
|
||||
const std::string& shader_name = shader_manager_->names()[ext_idx];
|
||||
GpuShaderPreset* preset = shader_manager_->load(
|
||||
gpu_ctx_->device(),
|
||||
shader_name,
|
||||
gpu_ctx_->swapchainFormat(),
|
||||
current_screen_width_, current_screen_height_);
|
||||
if (preset) {
|
||||
active_shader_ = preset;
|
||||
postfx_enabled_ = false;
|
||||
postfx_uniforms_.vignette_strength = 0.0f;
|
||||
postfx_uniforms_.chroma_strength = 0.0f;
|
||||
postfx_uniforms_.scanline_strength = 0.0f;
|
||||
showNotificationForAction("Shader: " + shader_name);
|
||||
} else {
|
||||
// Failed to load: skip to next
|
||||
SDL_Log("Engine::cycleShader: failed to load '%s', skipping", shader_name.c_str());
|
||||
active_shader_ = nullptr;
|
||||
showNotificationForAction("Shader: ERROR " + shader_name);
|
||||
}
|
||||
postfx_enabled_ = true;
|
||||
postfx_effect_mode_ = cycle - 1;
|
||||
applyPostFXPreset(postfx_effect_mode_);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Engine::getActiveShaderName() const {
|
||||
if (active_shader_) return active_shader_->name();
|
||||
return {};
|
||||
showNotificationForAction(names[cycle]);
|
||||
}
|
||||
|
||||
void Engine::toggleIntegerScaling() {
|
||||
@@ -1621,11 +1465,6 @@ void Engine::recreateOffscreenTexture() {
|
||||
base_screen_width_, base_screen_height_); // logical (font size based on base)
|
||||
}
|
||||
|
||||
// Recreate external shader intermediate targets
|
||||
if (shader_manager_) {
|
||||
shader_manager_->onResize(gpu_ctx_->device(), gpu_ctx_->swapchainFormat(),
|
||||
current_screen_width_, current_screen_height_);
|
||||
}
|
||||
if (ui_renderer_ && app_logo_) {
|
||||
app_logo_->initialize(ui_renderer_, current_screen_width_, current_screen_height_);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user