supersampling ara aplica al tamany de la finestra, no a la textura base
This commit is contained in:
@@ -273,25 +273,9 @@ namespace Rendering {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// 3b. Create scaled texture (render target for upscale pass, only with SS)
|
||||
// ----------------------------------------------------------------
|
||||
if (oversample_ > 1) {
|
||||
SDL_GPUTextureCreateInfo scaled_info = {};
|
||||
scaled_info.type = SDL_GPU_TEXTURETYPE_2D;
|
||||
scaled_info.format = SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM;
|
||||
scaled_info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
|
||||
scaled_info.width = static_cast<Uint32>(game_width_ * oversample_);
|
||||
scaled_info.height = static_cast<Uint32>(game_height_ * oversample_);
|
||||
scaled_info.layer_count_or_depth = 1;
|
||||
scaled_info.num_levels = 1;
|
||||
scaled_texture_ = SDL_CreateGPUTexture(device_, &scaled_info);
|
||||
if (scaled_texture_ == nullptr) {
|
||||
SDL_Log("SDL3GPUShader: failed to create scaled texture: %s", SDL_GetError());
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// scaled_texture_ se creará en el primer render() una vez conocido el tamaño de ventana
|
||||
scaled_w_ = 0;
|
||||
scaled_h_ = 0;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// 4. Create upload transfer buffer (CPU → GPU, always game resolution)
|
||||
@@ -467,6 +451,19 @@ 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) {
|
||||
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_) {
|
||||
SDL_WaitForGPUIdle(device_);
|
||||
recreateScaledTexture(NEED_W, NEED_H);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(device_);
|
||||
if (cmd == nullptr) {
|
||||
SDL_Log("SDL3GPUShader: SDL_AcquireGPUCommandBuffer failed: %s", SDL_GetError());
|
||||
@@ -561,11 +558,11 @@ namespace Rendering {
|
||||
SDL_SetGPUViewport(pass, &vp);
|
||||
|
||||
// pixel_scale: subpíxeles de textura por pixel lógico de juego.
|
||||
// Sin SS: vh/game_height (zoom de ventana = subpíxeles por fila).
|
||||
// Con SS: la textura entrada al PostFX tiene OS subfilas por fila lógica,
|
||||
// así que pixel_scale = OS (independiente del zoom de ventana).
|
||||
uniforms_.pixel_scale = (oversample_ > 1)
|
||||
? static_cast<float>(oversample_)
|
||||
// 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_))
|
||||
: ((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_);
|
||||
@@ -619,6 +616,8 @@ namespace Rendering {
|
||||
SDL_ReleaseGPUTexture(device_, scaled_texture_);
|
||||
scaled_texture_ = nullptr;
|
||||
}
|
||||
scaled_w_ = 0;
|
||||
scaled_h_ = 0;
|
||||
if (upload_buffer_ != nullptr) {
|
||||
SDL_ReleaseGPUTransferBuffer(device_, upload_buffer_);
|
||||
upload_buffer_ = nullptr;
|
||||
@@ -746,10 +745,14 @@ 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
|
||||
if (scaled_texture_ != nullptr) {
|
||||
SDL_ReleaseGPUTexture(device_, scaled_texture_);
|
||||
scaled_texture_ = nullptr;
|
||||
}
|
||||
scaled_w_ = 0;
|
||||
scaled_h_ = 0;
|
||||
|
||||
if (upload_buffer_ != nullptr) {
|
||||
SDL_ReleaseGPUTransferBuffer(device_, upload_buffer_);
|
||||
upload_buffer_ = nullptr;
|
||||
@@ -773,25 +776,6 @@ namespace Rendering {
|
||||
return false;
|
||||
}
|
||||
|
||||
// scaled_texture_: solo con SS
|
||||
if (oversample_ > 1) {
|
||||
SDL_GPUTextureCreateInfo scaled_info = {};
|
||||
scaled_info.type = SDL_GPU_TEXTURETYPE_2D;
|
||||
scaled_info.format = SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM;
|
||||
scaled_info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
|
||||
scaled_info.width = static_cast<Uint32>(game_width_ * oversample_);
|
||||
scaled_info.height = static_cast<Uint32>(game_height_ * oversample_);
|
||||
scaled_info.layer_count_or_depth = 1;
|
||||
scaled_info.num_levels = 1;
|
||||
scaled_texture_ = SDL_CreateGPUTexture(device_, &scaled_info);
|
||||
if (scaled_texture_ == nullptr) {
|
||||
SDL_Log("SDL3GPUShader: reinit — failed to create scaled texture: %s", SDL_GetError());
|
||||
SDL_ReleaseGPUTexture(device_, scene_texture_);
|
||||
scene_texture_ = nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// upload_buffer_: siempre a resolución del juego
|
||||
SDL_GPUTransferBufferCreateInfo tb_info = {};
|
||||
tb_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||
@@ -799,15 +783,44 @@ namespace Rendering {
|
||||
upload_buffer_ = SDL_CreateGPUTransferBuffer(device_, &tb_info);
|
||||
if (upload_buffer_ == nullptr) {
|
||||
SDL_Log("SDL3GPUShader: reinit — failed to create upload buffer: %s", SDL_GetError());
|
||||
if (scaled_texture_ != nullptr) { SDL_ReleaseGPUTexture(device_, scaled_texture_); scaled_texture_ = nullptr; }
|
||||
SDL_ReleaseGPUTexture(device_, scene_texture_);
|
||||
scene_texture_ = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_Log("SDL3GPUShader: oversample %d — scene %dx%d, scaled %dx%d",
|
||||
oversample_, game_width_, game_height_,
|
||||
game_width_ * oversample_, game_height_ * oversample_);
|
||||
SDL_Log("SDL3GPUShader: reinit — scene %dx%d, oversample %d (scaled se creará en render)",
|
||||
game_width_, game_height_, oversample_);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// recreateScaledTexture — libera y recrea scaled_texture_ con nuevas dimensiones.
|
||||
// Llamar solo cuando device_ no esté ejecutando comandos (SDL_WaitForGPUIdle previo).
|
||||
// ---------------------------------------------------------------------------
|
||||
auto SDL3GPUShader::recreateScaledTexture(int w, int h) -> bool {
|
||||
if (scaled_texture_ != nullptr) {
|
||||
SDL_ReleaseGPUTexture(device_, scaled_texture_);
|
||||
scaled_texture_ = nullptr;
|
||||
}
|
||||
scaled_w_ = 0;
|
||||
scaled_h_ = 0;
|
||||
|
||||
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.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());
|
||||
return false;
|
||||
}
|
||||
scaled_w_ = w;
|
||||
scaled_h_ = h;
|
||||
SDL_Log("SDL3GPUShader: scaled texture %dx%d (oversample %d)", w, h, oversample_);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,14 +80,15 @@ namespace Rendering {
|
||||
Uint32 num_uniform_buffers) -> SDL_GPUShader*;
|
||||
|
||||
auto createPipeline() -> bool;
|
||||
auto reinitTexturesAndBuffer() -> bool; // Recrea textura y buffer con oversample actual
|
||||
auto reinitTexturesAndBuffer() -> bool; // Recrea scene_texture_ y upload_buffer_
|
||||
auto recreateScaledTexture(int w, int h) -> bool; // Recrea scaled_texture_ con nuevas dims
|
||||
|
||||
SDL_Window* window_ = nullptr;
|
||||
SDL_GPUDevice* device_ = nullptr;
|
||||
SDL_GPUGraphicsPipeline* pipeline_ = nullptr; // PostFX pass
|
||||
SDL_GPUGraphicsPipeline* upscale_pipeline_ = nullptr; // Upscale nearest pass (solo con SS)
|
||||
SDL_GPUTexture* scene_texture_ = nullptr; // Canvas del juego (game_width_ × game_height_)
|
||||
SDL_GPUTexture* scaled_texture_ = nullptr; // Render target intermedio (game × OS), solo con SS
|
||||
SDL_GPUTexture* scene_texture_ = nullptr; // Canvas del juego (game_width_ × game_height_)
|
||||
SDL_GPUTexture* scaled_texture_ = nullptr; // Render target intermedio (win*SS × win*SS), solo con SS
|
||||
SDL_GPUTransferBuffer* upload_buffer_ = nullptr;
|
||||
SDL_GPUSampler* sampler_ = nullptr; // NEAREST
|
||||
SDL_GPUSampler* linear_sampler_ = nullptr; // LINEAR
|
||||
@@ -96,6 +97,8 @@ namespace Rendering {
|
||||
|
||||
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)
|
||||
bool is_initialized_ = false;
|
||||
bool vsync_ = true;
|
||||
|
||||
Reference in New Issue
Block a user