fix: pantalla completa, integer scale i vsync

This commit is contained in:
2026-03-21 18:10:48 +01:00
parent 9df3f1b929
commit 3a2015256a
7 changed files with 68 additions and 1721 deletions

View File

@@ -431,12 +431,18 @@ void Screen::toggleDebugInfo() { show_debug_info_ = !show_debug_info_; }
void Screen::toggleIntegerScale() {
Options::video.integer_scale = !Options::video.integer_scale;
SDL_SetRenderLogicalPresentation(renderer_, Options::game.width, Options::game.height, Options::video.integer_scale ? SDL_LOGICAL_PRESENTATION_INTEGER_SCALE : SDL_LOGICAL_PRESENTATION_LETTERBOX);
if (shader_backend_) {
shader_backend_->setScaleMode(Options::video.integer_scale);
}
}
// Alterna entre activar y desactivar el V-Sync
void Screen::toggleVSync() {
Options::video.vertical_sync = !Options::video.vertical_sync;
SDL_SetRenderVSync(renderer_, Options::video.vertical_sync ? 1 : SDL_RENDERER_VSYNC_DISABLED);
if (shader_backend_) {
shader_backend_->setVSync(Options::video.vertical_sync);
}
}
// Getters
@@ -470,6 +476,10 @@ void Screen::initShaders() {
}
shader_backend_->init(window_, tex, "", "");
// Propagar flags de vsync e integer scale al backend GPU
shader_backend_->setVSync(Options::video.vertical_sync);
shader_backend_->setScaleMode(Options::video.integer_scale);
if (Options::video.postfx) {
applyCurrentPostFXPreset();
} else {

View File

@@ -2,7 +2,9 @@
#include <SDL3/SDL_log.h>
#include <cstring> // memcpy, strlen
#include <algorithm> // std::min, std::max, std::floor
#include <cmath> // std::floor
#include <cstring> // memcpy, strlen
#ifndef __APPLE__
#include "core/rendering/sdl3gpu/postfx_frag_spv.h"
@@ -218,7 +220,7 @@ auto SDL3GPUShader::init(SDL_Window* window,
}
SDL_SetGPUSwapchainParameters(device_, window_,
SDL_GPU_SWAPCHAINCOMPOSITION_SDR,
SDL_GPU_PRESENTMODE_VSYNC);
vsync_ ? SDL_GPU_PRESENTMODE_VSYNC : SDL_GPU_PRESENTMODE_IMMEDIATE);
}
// ----------------------------------------------------------------
@@ -410,6 +412,29 @@ void SDL3GPUShader::render() {
if (pass != nullptr) {
SDL_BindGPUGraphicsPipeline(pass, pipeline_);
// Calcular viewport para mantener relación de aspecto (letterbox o integer scale)
float vx = 0.0F;
float vy = 0.0F;
float vw = 0.0F;
float vh = 0.0F;
if (integer_scale_) {
const int scale = std::max(1, std::min(
static_cast<int>(sw) / tex_width_,
static_cast<int>(sh) / tex_height_));
vw = static_cast<float>(tex_width_ * scale);
vh = static_cast<float>(tex_height_ * scale);
} else {
const float scale = std::min(
static_cast<float>(sw) / static_cast<float>(tex_width_),
static_cast<float>(sh) / static_cast<float>(tex_height_));
vw = static_cast<float>(tex_width_) * scale;
vh = static_cast<float>(tex_height_) * scale;
}
vx = std::floor((static_cast<float>(sw) - vw) * 0.5F);
vy = std::floor((static_cast<float>(sh) - vh) * 0.5F);
SDL_GPUViewport vp = {vx, vy, vw, vh, 0.0F, 1.0F};
SDL_SetGPUViewport(pass, &vp);
SDL_GPUTextureSamplerBinding binding = {};
binding.texture = scene_texture_;
binding.sampler = sampler_;
@@ -525,4 +550,17 @@ void SDL3GPUShader::setPostFXParams(const PostFXParams& p) {
uniforms_.bleeding = p.bleeding;
}
void SDL3GPUShader::setVSync(bool vsync) {
vsync_ = vsync;
if (device_ != nullptr && window_ != nullptr) {
SDL_SetGPUSwapchainParameters(device_, window_,
SDL_GPU_SWAPCHAINCOMPOSITION_SDR,
vsync_ ? SDL_GPU_PRESENTMODE_VSYNC : SDL_GPU_PRESENTMODE_IMMEDIATE);
}
}
void SDL3GPUShader::setScaleMode(bool integer_scale) {
integer_scale_ = integer_scale;
}
} // namespace Rendering

View File

@@ -50,6 +50,12 @@ class SDL3GPUShader : public ShaderBackend {
// Actualiza los parámetros de intensidad de los efectos PostFX
void setPostFXParams(const PostFXParams& p) override;
// Activa/desactiva VSync en el swapchain
void setVSync(bool vsync) override;
// Activa/desactiva escalado entero (integer scale)
void setScaleMode(bool integer_scale) override;
private:
static auto createShaderMSL(SDL_GPUDevice* device,
const char* msl_source,
@@ -80,6 +86,8 @@ class SDL3GPUShader : public ShaderBackend {
int tex_width_ = 0;
int tex_height_ = 0;
bool is_initialized_ = false;
bool vsync_ = true;
bool integer_scale_ = false;
};
} // namespace Rendering

View File

@@ -72,6 +72,16 @@ class ShaderBackend {
*/
virtual void setPostFXParams(const PostFXParams& /*p*/) {}
/**
* @brief Activa o desactiva VSync en el swapchain del GPU device
*/
virtual void setVSync(bool /*vsync*/) {}
/**
* @brief Activa o desactiva el escalado entero (integer scale)
*/
virtual void setScaleMode(bool /*integer_scale*/) {}
/**
* @brief Verifica si el backend está usando aceleración por hardware
* @return true si usa aceleración (OpenGL/Metal/Vulkan)