115 lines
4.7 KiB
C++
115 lines
4.7 KiB
C++
#pragma once
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "utils/defaults.hpp"
|
|
|
|
namespace Rendering {
|
|
|
|
// Shader de post-procés actiu. El backend escull el pipeline corresponent.
|
|
enum class ShaderType : std::uint8_t { POSTFX,
|
|
CRTPI };
|
|
|
|
// Paràmetres d'intensitat dels efectes PostFX. Amb tot a 0 el shader
|
|
// actua com un passthrough. Els presets els omplen en fases futures.
|
|
struct PostFXParams {
|
|
float vignette{0.0F};
|
|
float scanlines{0.0F};
|
|
// Aberració cromàtica — varia entre min i max via sinusoidal; si coincideixen
|
|
// queda estàtica. Permet un "floor" perquè la imatge mai sigui lliure de chroma.
|
|
float chroma_min{0.0F};
|
|
float chroma_max{0.0F};
|
|
float mask{0.0F};
|
|
float gamma{0.0F};
|
|
float curvature{0.0F};
|
|
float bleeding{0.0F};
|
|
float flicker{0.0F};
|
|
// Forma de les scanlines — 3 subpíxels per fila lògica per defecte.
|
|
float scan_dark_ratio{0.333F}; // fracció obscura (1/3)
|
|
float scan_dark_floor{0.42F}; // brillantor subfila fosca
|
|
float scan_edge_soft{1.0F}; // 0 = step dur; 1 = suavitzat 1 px físic
|
|
};
|
|
|
|
// Paràmetres del shader CRT-Pi (algoritme de scanlines amb pesos gaussians).
|
|
struct CrtPiParams {
|
|
float scanline_weight{6.0F};
|
|
float scanline_gap_brightness{0.12F};
|
|
float bloom_factor{3.5F};
|
|
float input_gamma{2.4F};
|
|
float output_gamma{2.2F};
|
|
float mask_brightness{0.80F};
|
|
float curvature_x{0.05F};
|
|
float curvature_y{0.10F};
|
|
int mask_type{2}; // 0=cap, 1=verd/magenta, 2=RGB fòsfor
|
|
bool enable_scanlines{true};
|
|
bool enable_multisample{true};
|
|
bool enable_gamma{true};
|
|
bool enable_curvature{false};
|
|
bool enable_sharper{false};
|
|
};
|
|
|
|
// Interfície abstracta per a backends de renderitzat per GPU.
|
|
// Per ara, l'única implementació és SDL3GPUShader. Un backend
|
|
// alternatiu (p.ex. OpenGL o dummy) podria afegir-se més endavant.
|
|
class ShaderBackend {
|
|
public:
|
|
ShaderBackend() = default;
|
|
virtual ~ShaderBackend() = default;
|
|
|
|
ShaderBackend(const ShaderBackend&) = delete;
|
|
ShaderBackend(ShaderBackend&&) = delete;
|
|
auto operator=(const ShaderBackend&) -> ShaderBackend& = delete;
|
|
auto operator=(ShaderBackend&&) -> ShaderBackend& = delete;
|
|
|
|
// Crea device, pipeline, textura i sampler a partir de la finestra
|
|
// i la resolució del canvas del joc. Retorna false si la GPU no
|
|
// està disponible (el Screen farà fallback al SDL_Renderer).
|
|
virtual auto init(SDL_Window* window, int game_width, int game_height) -> bool = 0;
|
|
|
|
// Copia píxels ARGB8888 des de CPU cap al buffer de transferència.
|
|
virtual void uploadPixels(const std::uint32_t* pixels, int width, int height) = 0;
|
|
|
|
// Executa el pas de renderitzat (copy pass + PostFX → swapchain + present).
|
|
virtual void render() = 0;
|
|
|
|
// Actualitza els uniforms de PostFX per al pròxim render().
|
|
virtual void setPostFXParams(const PostFXParams& params) = 0;
|
|
|
|
// Selecciona quin shader aplica a la pròxima crida a render().
|
|
virtual void setActiveShader(ShaderType type) = 0;
|
|
|
|
// Actualitza els uniforms del shader CRT-Pi per al pròxim render().
|
|
virtual void setCrtPiParams(const CrtPiParams& params) = 0;
|
|
|
|
// Canvia el mode de presentació (VSYNC/IMMEDIATE/MAILBOX) en calent.
|
|
virtual void setVSync(bool vsync) = 0;
|
|
|
|
// Mode d'escalat del triangle fullscreen al swapchain (letterbox,
|
|
// integer, overscan, ...). Implementat via SDL_SetGPUViewport.
|
|
virtual void setScalingMode(Defaults::ScalingMode mode) = 0;
|
|
|
|
// Fixa el driver preferit (buit = automàtic). S'ha de cridar abans d'init().
|
|
virtual void setPreferredDriver(const std::string& driver) = 0;
|
|
|
|
// Destrueix tots els recursos GPU (pipeline, textura, buffer, sampler, device).
|
|
virtual void cleanup() = 0;
|
|
|
|
// Allibera la finestra del device sense destruir el device. Cal cridar-ho
|
|
// ABANS de SDL_DestroyWindow per evitar que vkDestroyInstance intente
|
|
// alliberar una Wayland surface ja desapareguda.
|
|
virtual void releaseWindow() = 0;
|
|
|
|
[[nodiscard]] virtual auto isReady() const -> bool = 0;
|
|
[[nodiscard]] virtual auto getDriverName() const -> std::string = 0;
|
|
};
|
|
|
|
// Fàbrica: construeix el backend per defecte del projecte (SDL3 GPU).
|
|
// Screen l'invoca sense conèixer la classe concreta.
|
|
[[nodiscard]] auto makeDefaultShaderBackend() -> std::unique_ptr<ShaderBackend>;
|
|
|
|
} // namespace Rendering
|