afinant els shaders

This commit is contained in:
2026-03-26 07:46:11 +01:00
parent c6d409c303
commit 8d213e7b3e
2 changed files with 49 additions and 37 deletions

View File

@@ -272,9 +272,8 @@ namespace Rendering {
return false;
}
// scaled_texture_ se creará en el primer render() una vez conocido el tamaño de ventana
scaled_w_ = 0;
scaled_h_ = 0;
// scaled_texture_ se creará en el primer render() una vez conocido el zoom de ventana
ss_factor_ = 0;
// ----------------------------------------------------------------
// 4. Create upload transfer buffer (CPU → GPU, always game resolution)
@@ -450,16 +449,17 @@ namespace Rendering {
void SDL3GPUShader::render() {
if (!is_initialized_) { return; }
// Paso 0: si SS activo, verificar si el tamaño de ventana cambió y recrear scaled_texture_
if (oversample_ > 1) {
// Paso 0: si SS activo, calcular el factor necesario según el zoom actual y recrear si cambió.
// Factor = primer múltiplo de 3 >= zoom (mín 3). Se recrea solo en saltos de factor.
if (oversample_ > 1 && game_height_ > 0) {
int win_w = 0;
int win_h = 0;
SDL_GetWindowSizeInPixels(window_, &win_w, &win_h);
const int NEED_W = win_w * oversample_;
const int NEED_H = win_h * oversample_;
if (NEED_W != scaled_w_ || NEED_H != scaled_h_) {
const float ZOOM = static_cast<float>(win_h) / static_cast<float>(game_height_);
const int NEED_FACTOR = calcSsFactor(ZOOM);
if (NEED_FACTOR != ss_factor_) {
SDL_WaitForGPUIdle(device_);
recreateScaledTexture(NEED_W, NEED_H);
recreateScaledTexture(NEED_FACTOR);
}
}
@@ -558,13 +558,15 @@ namespace Rendering {
// pixel_scale: subpíxeles de textura por pixel lógico de juego.
// Sin SS: vh/game_height (zoom de ventana).
// Con SS: scaled_h_/game_height (= win_h*oversample_/game_height), que indica
// cuántas subfilas de la textura intermedia corresponden a cada fila lógica.
uniforms_.pixel_scale = (oversample_ > 1 && game_height_ > 0)
? (static_cast<float>(scaled_h_) / static_cast<float>(game_height_))
// Con SS: ss_factor_ exacto (3, 6, 9...) — la textura scaled tiene exactamente
// ss_factor_ subfilas por fila lógica, múltiplo de 3 garantizado.
uniforms_.pixel_scale = (oversample_ > 1 && ss_factor_ > 0)
? static_cast<float>(ss_factor_)
: ((game_height_ > 0) ? (vh / static_cast<float>(game_height_)) : 1.0F);
uniforms_.time = static_cast<float>(SDL_GetTicks()) / 1000.0F;
uniforms_.oversample = static_cast<float>(oversample_);
uniforms_.oversample = (oversample_ > 1 && ss_factor_ > 0)
? static_cast<float>(ss_factor_)
: 1.0F;
// Con SS: leer de scaled_texture_ (ya ampliada); con LINEAR para suavizar
// el escalado final a zooms no-múltiplo-de-OS.
@@ -615,8 +617,7 @@ namespace Rendering {
SDL_ReleaseGPUTexture(device_, scaled_texture_);
scaled_texture_ = nullptr;
}
scaled_w_ = 0;
scaled_h_ = 0;
ss_factor_ = 0;
if (upload_buffer_ != nullptr) {
SDL_ReleaseGPUTransferBuffer(device_, upload_buffer_);
upload_buffer_ = nullptr;
@@ -744,13 +745,12 @@ namespace Rendering {
SDL_ReleaseGPUTexture(device_, scene_texture_);
scene_texture_ = nullptr;
}
// scaled_texture_ se libera aquí; se recreará en el primer render() con las dims de ventana
// scaled_texture_ se libera aquí; se recreará en el primer render() con el factor correcto
if (scaled_texture_ != nullptr) {
SDL_ReleaseGPUTexture(device_, scaled_texture_);
scaled_texture_ = nullptr;
}
scaled_w_ = 0;
scaled_h_ = 0;
ss_factor_ = 0;
if (upload_buffer_ != nullptr) {
SDL_ReleaseGPUTransferBuffer(device_, upload_buffer_);
@@ -787,39 +787,51 @@ namespace Rendering {
return false;
}
SDL_Log("SDL3GPUShader: reinit — scene %dx%d, oversample %d (scaled se creará en render)",
game_width_, game_height_, oversample_);
SDL_Log("SDL3GPUShader: reinit — scene %dx%d, SS %s (scaled se creará en render)",
game_width_, game_height_, oversample_ > 1 ? "on" : "off");
return true;
}
// ---------------------------------------------------------------------------
// recreateScaledTexture — libera y recrea scaled_texture_ con nuevas dimensiones.
// calcSsFactor — primer múltiplo de 3 >= zoom, mínimo 3.
// Ejemplos: zoom 1,2,3 → 3; zoom 4,5,6 → 6; zoom 4.4 → 6; zoom 7,8,9 → 9.
// ---------------------------------------------------------------------------
auto SDL3GPUShader::calcSsFactor(float zoom) -> int {
const int MULTIPLE = 3;
const int n = static_cast<int>(std::ceil(zoom / static_cast<float>(MULTIPLE)));
return std::max(1, n) * MULTIPLE;
}
// ---------------------------------------------------------------------------
// recreateScaledTexture — libera y recrea scaled_texture_ para el factor dado.
// Llamar solo cuando device_ no esté ejecutando comandos (SDL_WaitForGPUIdle previo).
// ---------------------------------------------------------------------------
auto SDL3GPUShader::recreateScaledTexture(int w, int h) -> bool {
auto SDL3GPUShader::recreateScaledTexture(int factor) -> bool {
if (scaled_texture_ != nullptr) {
SDL_ReleaseGPUTexture(device_, scaled_texture_);
scaled_texture_ = nullptr;
}
scaled_w_ = 0;
scaled_h_ = 0;
ss_factor_ = 0;
const int W = game_width_ * factor;
const int H = game_height_ * factor;
SDL_GPUTextureCreateInfo info = {};
info.type = SDL_GPU_TEXTURETYPE_2D;
info.format = SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM;
info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
info.width = static_cast<Uint32>(w);
info.height = static_cast<Uint32>(h);
info.width = static_cast<Uint32>(W);
info.height = static_cast<Uint32>(H);
info.layer_count_or_depth = 1;
info.num_levels = 1;
scaled_texture_ = SDL_CreateGPUTexture(device_, &info);
if (scaled_texture_ == nullptr) {
SDL_Log("SDL3GPUShader: failed to create scaled texture %dx%d: %s", w, h, SDL_GetError());
SDL_Log("SDL3GPUShader: failed to create scaled texture %dx%d (factor %d): %s",
W, H, factor, SDL_GetError());
return false;
}
scaled_w_ = w;
scaled_h_ = h;
SDL_Log("SDL3GPUShader: scaled texture %dx%d (oversample %d)", w, h, oversample_);
ss_factor_ = factor;
SDL_Log("SDL3GPUShader: scaled texture %dx%d (factor %d×)", W, H, factor);
return true;
}

View File

@@ -80,8 +80,9 @@ namespace Rendering {
Uint32 num_uniform_buffers) -> SDL_GPUShader*;
auto createPipeline() -> bool;
auto reinitTexturesAndBuffer() -> bool; // Recrea scene_texture_ y upload_buffer_
auto recreateScaledTexture(int w, int h) -> bool; // Recrea scaled_texture_ con nuevas dims
auto reinitTexturesAndBuffer() -> bool; // Recrea scene_texture_ y upload_buffer_
auto recreateScaledTexture(int factor) -> bool; // Recrea scaled_texture_ para factor dado
static auto calcSsFactor(float zoom) -> int; // Primer múltiplo de 3 >= zoom (mín 3)
SDL_Window* window_ = nullptr;
SDL_GPUDevice* device_ = nullptr;
@@ -95,11 +96,10 @@ namespace Rendering {
PostFXUniforms uniforms_{.vignette_strength = 0.6F, .chroma_strength = 0.15F, .scanline_strength = 0.7F, .screen_height = 192.0F, .pixel_scale = 1.0F, .oversample = 1.0F};
int game_width_ = 0; // Dimensiones originales del canvas
int game_width_ = 0; // Dimensiones originales del canvas
int game_height_ = 0;
int scaled_w_ = 0; // Dimensiones actuales de scaled_texture_ (win*SS)
int scaled_h_ = 0;
int oversample_ = 1; // Factor SS actual (1 o 3)
int ss_factor_ = 0; // Factor SS activo (3, 6, 9...) o 0 si SS desactivado
int oversample_ = 1; // SS on/off (1 = off, >1 = on)
bool is_initialized_ = false;
bool vsync_ = true;
bool integer_scale_ = false;