#pragma once #include #include #include namespace Rendering { /** @brief Identificador del shader de post-procesado activo */ enum class ShaderType : std::uint8_t { POSTFX, CRTPI }; /** * @brief Parámetros de intensidad de los efectos PostFX * Definido a nivel de namespace para facilitar el uso desde subclases y screen.cpp */ struct PostFXParams { float vignette = 0.0F; // Intensidad de la viñeta float scanlines = 0.0F; // Intensidad de las scanlines // Aberració cromàtica — varia entre min i max via sinusoidal; si coincideixen // queda estàtica. min > 0 garanteix que la imatge mai sigui lliure de chroma. float chroma_min = 0.0F; float chroma_max = 0.0F; float mask = 0.0F; // Máscara de fósforo RGB float gamma = 0.0F; // Corrección gamma (blend 0=off, 1=full) float curvature = 0.0F; // Curvatura barrel CRT float bleeding = 0.0F; // Sangrado de color NTSC float flicker = 0.0F; // Parpadeo de fósforo CRT ~50 Hz // 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 }; /** * @brief Parámetros del shader CRT-Pi (algoritmo de scanlines continuas) * Diferente al PostFX: usa pesos gaussianos por distancia subpixel y bloom. */ struct CrtPiParams { float scanline_weight{6.0F}; // Ajuste gaussiano (mayor = scanlines más estrechas) float scanline_gap_brightness{0.12F}; // Brillo mínimo en las ranuras entre scanlines float bloom_factor{3.5F}; // Factor de brillo para zonas iluminadas float input_gamma{2.4F}; // Gamma de entrada (linealización) float output_gamma{2.2F}; // Gamma de salida (codificación) float mask_brightness{0.80F}; // Sub-píxeles tenues en la máscara de fósforo float curvature_x{0.05F}; // Distorsión barrel eje X float curvature_y{0.10F}; // Distorsión barrel eje Y int mask_type{2}; // 0=ninguna, 1=verde/magenta, 2=RGB fósforo bool enable_scanlines{true}; // Activar efecto de scanlines bool enable_multisample{true}; // Antialiasing analítico de scanlines bool enable_gamma{true}; // Corrección gamma bool enable_curvature{false}; // Distorsión barrel CRT bool enable_sharper{false}; // Submuestreo más nítido (modo SHARPER) }; /** * @brief Interfaz abstracta para backends de renderizado con shaders * * Esta interfaz define el contrato que todos los backends de shaders * deben cumplir (OpenGL, Metal, Vulkan, etc.) */ class ShaderBackend { public: virtual ~ShaderBackend() = default; /** * @brief Inicializa el backend de shaders * @param window Ventana SDL * @param texture Textura de backbuffer a la que aplicar shaders * @param vertex_source Código fuente del vertex shader * @param fragment_source Código fuente del fragment shader * @return true si la inicialización fue exitosa */ virtual auto init(SDL_Window* window, SDL_Texture* texture, const std::string& vertex_source, const std::string& fragment_source) -> bool = 0; /** * @brief Renderiza la textura con los shaders aplicados */ virtual void render() = 0; /** * @brief Establece el tamaño de la textura como parámetro del shader * @param width Ancho de la textura * @param height Alto de la textura */ virtual void setTextureSize(float width, float height) = 0; /** * @brief Limpia y libera recursos del backend */ virtual void cleanup() = 0; /** * @brief Sube píxeles ARGB8888 desde la CPU al backend de shaders * Usado por SDL3GPUShader para evitar pasar por SDL_Texture */ virtual void uploadPixels(const Uint32* /*pixels*/, int /*width*/, int /*height*/) {} /** * @brief Establece los parámetros de intensidad de los efectos PostFX * @param p Struct con todos los parámetros PostFX */ virtual void setPostFXParams(const PostFXParams& /*p*/) {} /** * @brief Activa o desactiva VSync en el swapchain del GPU device */ virtual void setVSync(bool /*vsync*/) {} /** * @brief Estableix el mode de presentacio del canvas dins del swapchain. * El backend calcula el viewport en consequencia. */ enum class PresentationMode : std::uint8_t { INTEGER_SCALE, LETTERBOX, STRETCHED, OVERSCAN }; virtual void setPresentationMode(PresentationMode /*mode*/) {} /** * @brief Verifica si el backend está usando aceleración por hardware * @return true si usa aceleración (OpenGL/Metal/Vulkan) */ [[nodiscard]] virtual auto isHardwareAccelerated() const -> bool = 0; /** * @brief Nombre del driver GPU activo (p.ej. "vulkan", "metal", "direct3d12") * @return Cadena vacía si no disponible */ [[nodiscard]] virtual auto getDriverName() const -> std::string { return {}; } /** * @brief Establece el driver GPU preferido antes de init(). * Vacío = selección automática de SDL. Implementado en SDL3GPUShader. */ virtual void setPreferredDriver(const std::string& /*driver*/) {} /** * @brief Selecciona el shader de post-procesado activo (POSTFX o CRTPI). * Debe llamarse antes de render(). No recrea pipelines. */ virtual void setActiveShader(ShaderType /*type*/) {} /** * @brief Establece los parámetros del shader CRT-Pi. */ virtual void setCrtPiParams(const CrtPiParams& /*p*/) {} /** * @brief Devuelve el shader de post-procesado activo. */ [[nodiscard]] virtual auto getActiveShader() const -> ShaderType { return ShaderType::POSTFX; } }; } // namespace Rendering