GlobalInputs F1-F12 + Escape, Screen sense destruir finestra, escalat al GPU, presets i fons canvas (v0.11.0)

This commit is contained in:
JailDesigner committed 2026-04-19 14:27:16 +02:00
1 parent 837eb73398
commit 297dc85e47
23 files changed
+653 -34

No files matched your search

@@ -3,6 +3,8 @@
#include <cstring>
#include <iostream>
#include "core/rendering/sdl3gpu/viewport.hpp"
#ifndef __APPLE__
#include "core/rendering/sdl3gpu/spv/crtpi_frag_spv.h"
#include "core/rendering/sdl3gpu/spv/postfx_vert_spv.h"
@@ -280,7 +282,10 @@ namespace Rendering {
SDL_GPUTexture* scene,
SDL_GPUSampler* sampler,
int game_width,
int game_height) {
int game_height,
Defaults::ScalingMode scaling_mode,
std::uint32_t swapchain_w,
std::uint32_t swapchain_h) {
if (pipeline_ == nullptr) { return; }
SDL_GPUColorTargetInfo color_target{};
@@ -292,6 +297,11 @@ namespace Rendering {
SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &color_target, 1, nullptr);
if (pass == nullptr) { return; }
// Viewport per aplicar letterbox/integer/... sense modificar el
// triangle fullscreen; la resta del swapchain queda a clear_color.
const SDL_GPUViewport VP = computeViewport(scaling_mode, swapchain_w, swapchain_h, game_width, game_height);
SDL_SetGPUViewport(pass, &VP);
SDL_BindGPUGraphicsPipeline(pass, pipeline_);
SDL_GPUTextureSamplerBinding binding{};
@@ -3,6 +3,8 @@
#include <SDL3/SDL.h>
#include <SDL3/SDL_gpu.h>
#include <cstdint>
#include "core/rendering/shader_backend.hpp"
// Uniforms del shader CRT-Pi. 4 × vec4 (64 bytes) per a alineament Metal/Vulkan.
@@ -56,7 +58,10 @@ namespace Rendering {
SDL_GPUTexture* scene,
SDL_GPUSampler* sampler,
int game_width,
int game_height);
int game_height,
Defaults::ScalingMode scaling_mode,
std::uint32_t swapchain_w,
std::uint32_t swapchain_h);
private:
SDL_GPUDevice* device_{nullptr};
@@ -4,6 +4,8 @@
#include <cstring>
#include <iostream>
#include "core/rendering/sdl3gpu/viewport.hpp"
#ifndef __APPLE__
#include "core/rendering/sdl3gpu/spv/postfx_frag_spv.h"
#include "core/rendering/sdl3gpu/spv/postfx_vert_spv.h"
@@ -370,7 +372,7 @@ namespace Rendering {
// Camí CrtPi: delega tot el render pass al pipeline dedicat.
if (active_shader_ == ShaderType::CRTPI && crtpi_pipeline_ != nullptr) {
crtpi_pipeline_->render(cmd, swapchain, scene_texture_, sampler_, game_width_, game_height_);
crtpi_pipeline_->render(cmd, swapchain, scene_texture_, sampler_, game_width_, game_height_, scaling_mode_, sw, sh);
SDL_SubmitGPUCommandBuffer(cmd);
return;
}
@@ -385,6 +387,9 @@ namespace Rendering {
SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &color_target, 1, nullptr);
if (pass != nullptr) {
const SDL_GPUViewport VP = computeViewport(scaling_mode_, sw, sh, game_width_, game_height_);
SDL_SetGPUViewport(pass, &VP);
SDL_BindGPUGraphicsPipeline(pass, pipeline_);
SDL_GPUTextureSamplerBinding binding{};
@@ -53,6 +53,7 @@ namespace Rendering {
void setActiveShader(ShaderType type) override { active_shader_ = type; }
void setCrtPiParams(const CrtPiParams& params) override;
void setVSync(bool vsync) override;
void setScalingMode(Defaults::ScalingMode mode) override { scaling_mode_ = mode; }
void setPreferredDriver(const std::string& driver) override { preferred_driver_ = driver; }
void cleanup() override;
@@ -99,6 +100,7 @@ namespace Rendering {
int game_width_{0};
int game_height_{0};
Defaults::ScalingMode scaling_mode_{Defaults::Video::SCALING_MODE};
std::string preferred_driver_;
std::string driver_name_;
bool vsync_{true};
@@ -0,0 +1,54 @@
#include "core/rendering/sdl3gpu/viewport.hpp"
#include <algorithm>
#include <cmath>
namespace Rendering {
auto computeViewport(Defaults::ScalingMode mode,
std::uint32_t swapchain_w,
std::uint32_t swapchain_h,
int logical_w,
int logical_h) -> SDL_GPUViewport {
const auto SW = static_cast<float>(swapchain_w);
const auto SH = static_cast<float>(swapchain_h);
const auto LW = static_cast<float>(logical_w);
const auto LH = static_cast<float>(logical_h);
float vw = 0.0F;
float vh = 0.0F;
switch (mode) {
case Defaults::ScalingMode::DISABLED:
vw = LW;
vh = LH;
break;
case Defaults::ScalingMode::STRETCH:
vw = SW;
vh = SH;
break;
case Defaults::ScalingMode::LETTERBOX: {
const float SCALE = std::min(SW / LW, SH / LH);
vw = LW * SCALE;
vh = LH * SCALE;
break;
}
case Defaults::ScalingMode::OVERSCAN: {
const float SCALE = std::max(SW / LW, SH / LH);
vw = LW * SCALE;
vh = LH * SCALE;
break;
}
case Defaults::ScalingMode::INTEGER: {
const int SCALE = std::max(1,
std::min(static_cast<int>(SW) / logical_w, static_cast<int>(SH) / logical_h));
vw = LW * static_cast<float>(SCALE);
vh = LH * static_cast<float>(SCALE);
break;
}
}
const float VX = std::floor((SW - vw) * 0.5F);
const float VY = std::floor((SH - vh) * 0.5F);
return {.x = VX, .y = VY, .w = vw, .h = vh, .min_depth = 0.0F, .max_depth = 1.0F};
}
} // namespace Rendering
@@ -0,0 +1,21 @@
#pragma once
#include <SDL3/SDL_gpu.h>
#include <cstdint>
#include "utils/defaults.hpp"
namespace Rendering {
// Calcula el rectangle on s'ha de pintar el triangle fullscreen dins del
// swapchain segons el mode d'escalat configurat. La zona fora del
// viewport queda amb la clear_color del render pass (negre o el color
// que decidisca el caller).
auto computeViewport(Defaults::ScalingMode mode,
std::uint32_t swapchain_w,
std::uint32_t swapchain_h,
int logical_w,
int logical_h) -> SDL_GPUViewport;
} // namespace Rendering