fix(engine): implementar viewport/scissor F6 i eliminar early return toggleIntegerScaling

- Eliminar guarda !fullscreen_enabled_ de toggleIntegerScaling(): F6 ara
  cicla i notifica en mode ventana i fullscreen per igual
- Pass 2: afegir viewport+scissor SDL_GPU condicionat a fullscreen_enabled_
  per als tres modes (INTEGER pixel-perfect centrat, LETTERBOX aspect-ratio,
  STRETCH pantalla completa)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-20 09:18:11 +01:00
parent a51072db32
commit 5c0d0479ad

View File

@@ -857,6 +857,36 @@ void Engine::render() {
SDL_GPURenderPass* pass2 = SDL_BeginGPURenderPass(cmd, &ct, 1, nullptr); SDL_GPURenderPass* pass2 = SDL_BeginGPURenderPass(cmd, &ct, 1, nullptr);
// Viewport/scissor per integer scaling (only F3 fullscreen)
if (fullscreen_enabled_) {
float vp_x, vp_y, vp_w, vp_h;
if (current_scaling_mode_ == ScalingMode::STRETCH) {
vp_x = 0.0f; vp_y = 0.0f;
vp_w = static_cast<float>(sw_w);
vp_h = static_cast<float>(sw_h);
} else if (current_scaling_mode_ == ScalingMode::INTEGER) {
int scale = static_cast<int>(std::min(sw_w / static_cast<Uint32>(base_screen_width_),
sw_h / static_cast<Uint32>(base_screen_height_)));
if (scale < 1) scale = 1;
vp_w = static_cast<float>(base_screen_width_ * scale);
vp_h = static_cast<float>(base_screen_height_ * scale);
vp_x = (static_cast<float>(sw_w) - vp_w) * 0.5f;
vp_y = (static_cast<float>(sw_h) - vp_h) * 0.5f;
} else { // LETTERBOX
float scale = std::min(static_cast<float>(sw_w) / base_screen_width_,
static_cast<float>(sw_h) / base_screen_height_);
vp_w = base_screen_width_ * scale;
vp_h = base_screen_height_ * scale;
vp_x = (static_cast<float>(sw_w) - vp_w) * 0.5f;
vp_y = (static_cast<float>(sw_h) - vp_h) * 0.5f;
}
SDL_GPUViewport vp = {vp_x, vp_y, vp_w, vp_h, 0.0f, 1.0f};
SDL_SetGPUViewport(pass2, &vp);
SDL_Rect scissor = {static_cast<int>(vp_x), static_cast<int>(vp_y),
static_cast<int>(vp_w), static_cast<int>(vp_h)};
SDL_SetGPUScissor(pass2, &scissor);
}
// PostFX: full-screen triangle via vertex_id (no vertex buffer needed) // PostFX: full-screen triangle via vertex_id (no vertex buffer needed)
SDL_BindGPUGraphicsPipeline(pass2, gpu_pipeline_->postfxPipeline()); SDL_BindGPUGraphicsPipeline(pass2, gpu_pipeline_->postfxPipeline());
SDL_GPUTextureSamplerBinding scene_tsb = {offscreen_tex_->texture(), offscreen_tex_->sampler()}; SDL_GPUTextureSamplerBinding scene_tsb = {offscreen_tex_->texture(), offscreen_tex_->sampler()};
@@ -1060,11 +1090,6 @@ void Engine::setInitialPostFX(int mode) {
} }
void Engine::toggleIntegerScaling() { void Engine::toggleIntegerScaling() {
// Solo permitir cambio si estamos en modo fullscreen normal (F3)
if (!fullscreen_enabled_) {
return; // No hacer nada si no estamos en fullscreen
}
// Ciclar entre los 3 modos: INTEGER → LETTERBOX → STRETCH → INTEGER // Ciclar entre los 3 modos: INTEGER → LETTERBOX → STRETCH → INTEGER
switch (current_scaling_mode_) { switch (current_scaling_mode_) {
case ScalingMode::INTEGER: case ScalingMode::INTEGER:
@@ -1078,16 +1103,13 @@ void Engine::toggleIntegerScaling() {
break; break;
} }
// SDL_GPU stretches to fill swapchain by default; just show notification
const char* mode_name = "INTEGER"; const char* mode_name = "INTEGER";
switch (current_scaling_mode_) { switch (current_scaling_mode_) {
case ScalingMode::INTEGER: mode_name = "INTEGER"; break; case ScalingMode::INTEGER: mode_name = "INTEGER"; break;
case ScalingMode::LETTERBOX: mode_name = "LETTERBOX"; break; case ScalingMode::LETTERBOX: mode_name = "LETTERBOX"; break;
case ScalingMode::STRETCH: mode_name = "STRETCH"; break; case ScalingMode::STRETCH: mode_name = "STRETCH"; break;
} }
showNotificationForAction(std::string("Escalado: ") + mode_name);
std::string notification = std::string("Escalado: ") + mode_name;
ui_manager_->showNotification(notification);
} }
void Engine::addSpriteToBatch(float x, float y, float w, float h, int r, int g, int b, float scale) { void Engine::addSpriteToBatch(float x, float y, float w, float h, int r, int g, int b, float scale) {