#pragma once #include #include #include #include #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}; float chroma{0.0F}; float mask{0.0F}; float gamma{0.0F}; float curvature{0.0F}; float bleeding{0.0F}; float flicker{0.0F}; }; // 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; } // namespace Rendering