feat(render): resolució d'offscreen configurable via YAML
Separa el tamany lògic (1280×720) del render target offscreen. Llista
tancada de 5 presets 16:9 (720p/900p/1080p/1440p/2160p) llegida de
rendering.render_{width,height} amb fallback a 1280×720 si invàlida.
Inclou API resizeRenderTarget() preparada per al menú de servei futur.
This commit is contained in:
@@ -14,9 +14,11 @@ namespace Rendering::GPU {
|
||||
|
||||
GpuFrameRenderer::~GpuFrameRenderer() { destroy(); }
|
||||
|
||||
auto GpuFrameRenderer::init(SDL_Window* window, float logical_w, float logical_h) -> bool {
|
||||
auto GpuFrameRenderer::init(SDL_Window* window, float logical_w, float logical_h, float render_w, float render_h) -> bool {
|
||||
logical_w_ = logical_w;
|
||||
logical_h_ = logical_h;
|
||||
render_w_ = render_w;
|
||||
render_h_ = render_h;
|
||||
|
||||
if (!device_.init(window)) {
|
||||
return false;
|
||||
@@ -47,13 +49,15 @@ namespace Rendering::GPU {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Textura offscreen del tamaño lógico del juego, COLOR_TARGET + SAMPLER.
|
||||
// Textura offscreen del tamaño físico de render, COLOR_TARGET + SAMPLER.
|
||||
// El tamaño lógico se aplica a los vértices vía UBO; el offscreen puede
|
||||
// ser de mayor resolución para ganar nitidez tras el upscale a la swapchain.
|
||||
SDL_GPUTextureCreateInfo tex_info{};
|
||||
tex_info.type = SDL_GPU_TEXTURETYPE_2D;
|
||||
tex_info.format = offscreen_format_;
|
||||
tex_info.usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER;
|
||||
tex_info.width = static_cast<uint32_t>(logical_w_);
|
||||
tex_info.height = static_cast<uint32_t>(logical_h_);
|
||||
tex_info.width = static_cast<uint32_t>(render_w_);
|
||||
tex_info.height = static_cast<uint32_t>(render_h_);
|
||||
tex_info.layer_count_or_depth = 1;
|
||||
tex_info.num_levels = 1;
|
||||
tex_info.sample_count = SDL_GPU_SAMPLECOUNT_1;
|
||||
@@ -107,6 +111,19 @@ namespace Rendering::GPU {
|
||||
indices_.clear();
|
||||
}
|
||||
|
||||
auto GpuFrameRenderer::resizeRenderTarget(float render_w, float render_h) -> bool {
|
||||
// Solo seguro fuera de un frame: si el cmd buffer está vivo y referencia
|
||||
// la textura antigua, recrearla provocaría un cuelgue/UB.
|
||||
if (isInsideFrame()) {
|
||||
std::cerr << "[GpuFrameRenderer] resizeRenderTarget llamado dentro de frame, ignorado\n";
|
||||
return false;
|
||||
}
|
||||
destroyOffscreen();
|
||||
render_w_ = render_w;
|
||||
render_h_ = render_h;
|
||||
return createOffscreen();
|
||||
}
|
||||
|
||||
auto GpuFrameRenderer::beginFrame(float clear_r, float clear_g, float clear_b) -> bool {
|
||||
// Los clear_* se ignoran: el fondo lo pinta el postpro. Mantenemos la
|
||||
// firma para no romper el SDLManager.
|
||||
@@ -438,8 +455,9 @@ namespace Rendering::GPU {
|
||||
ubo.background_max_g = BG_MAX_G;
|
||||
ubo.background_max_b = BG_MAX_B;
|
||||
ubo.background_max_a = 1.0F;
|
||||
ubo.texel_size_x = 1.0F / logical_w_;
|
||||
ubo.texel_size_y = 1.0F / logical_h_;
|
||||
// El sampling del bloom muestrea el offscreen → texel size del tamaño físico.
|
||||
ubo.texel_size_x = 1.0F / render_w_;
|
||||
ubo.texel_size_y = 1.0F / render_h_;
|
||||
ubo.pad_b = 0.0F;
|
||||
ubo.pad_c = 0.0F;
|
||||
|
||||
|
||||
@@ -59,12 +59,24 @@ namespace Rendering::GPU {
|
||||
GpuFrameRenderer(GpuFrameRenderer&&) = delete;
|
||||
auto operator=(GpuFrameRenderer&&) -> GpuFrameRenderer& = delete;
|
||||
|
||||
// Crea device + pipeline + offscreen + sampler. logical_w/h = tamaño
|
||||
// en píxeles lógicos del juego (1280×720), usado como base del
|
||||
// offscreen y de la transformación a NDC del shader de líneas.
|
||||
[[nodiscard]] auto init(SDL_Window* window, float logical_w, float logical_h) -> bool;
|
||||
// Crea device + pipeline + offscreen + sampler.
|
||||
// logical_w/h: tamaño en píxeles lógicos del juego (1280×720). Lo
|
||||
// consume el shader de líneas para transformar a NDC.
|
||||
// render_w/h: tamaño físico del offscreen donde se rasterizan las
|
||||
// líneas. Puede ser > logical para ganar nitidez al
|
||||
// escalar a la swapchain (configurable vía YAML).
|
||||
[[nodiscard]] auto init(SDL_Window* window,
|
||||
float logical_w,
|
||||
float logical_h,
|
||||
float render_w,
|
||||
float render_h) -> bool;
|
||||
void destroy();
|
||||
|
||||
// Recrea el offscreen con un nuevo tamaño físico de render. Solo es
|
||||
// seguro fuera de un frame (isInsideFrame() == false). Devuelve false
|
||||
// si está dentro de frame o si la creación de la textura falla.
|
||||
[[nodiscard]] auto resizeRenderTarget(float render_w, float render_h) -> bool;
|
||||
|
||||
// beginFrame: adquiere swapchain, abre render pass sobre offscreen
|
||||
// con clear a negro. Devuelve false si no hay textura disponible.
|
||||
// Los argumentos clear_r/g/b se ignoran (compatibilidad de API: el
|
||||
@@ -114,10 +126,18 @@ namespace Rendering::GPU {
|
||||
GpuLinePipeline line_pipeline_;
|
||||
GpuPostFxPipeline postfx_pipeline_;
|
||||
|
||||
// Tamaño lógico del juego (= tamaño del offscreen).
|
||||
// Tamaño lógico del juego: espacio de coordenadas de las primitivas
|
||||
// (vértices, UBO del line shader). Fijo a 1280×720.
|
||||
float logical_w_{1280.0F};
|
||||
float logical_h_{720.0F};
|
||||
|
||||
// Tamaño físico del offscreen (configurable). Independiente del lógico:
|
||||
// las coordenadas en NDC son agnósticas a la resolución de salida, así
|
||||
// que rasterizar a mayor render_w_/h_ da líneas más nítidas tras el
|
||||
// upscale lineal a la swapchain.
|
||||
float render_w_{1280.0F};
|
||||
float render_h_{720.0F};
|
||||
|
||||
// Viewport del pase final en píxeles físicos. <0 = full window.
|
||||
float viewport_x_{0.0F};
|
||||
float viewport_y_{0.0F};
|
||||
|
||||
Reference in New Issue
Block a user