afinant els shaders
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user