176 lines
7.0 KiB
C++
176 lines
7.0 KiB
C++
#pragma once
|
||
|
||
#include <SDL3/SDL.h>
|
||
|
||
#include <string>
|
||
#include <utility>
|
||
|
||
namespace Rendering {
|
||
|
||
/** @brief Identificador del shader de post-procesado activo */
|
||
enum class ShaderType { 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
|
||
float chroma = 0.0F; // Aberración cromática
|
||
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
|
||
};
|
||
|
||
/**
|
||
* @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 Activa o desactiva el escalado entero (integer scale)
|
||
*/
|
||
virtual void setScaleMode(bool /*integer_scale*/) {}
|
||
|
||
/**
|
||
* @brief Establece el factor de supersampling (1 = off, 3 = 3× SS)
|
||
* Con factor > 1, la textura GPU se crea a game×factor resolución y
|
||
* las scanlines se hornean en CPU (uploadPixels). El sampler usa LINEAR.
|
||
*/
|
||
virtual void setOversample(int /*factor*/) {}
|
||
|
||
/**
|
||
* @brief Activa/desactiva interpolación LINEAR en el paso de upscale (SS).
|
||
* Por defecto NEAREST (false). Solo tiene efecto con supersampling activo.
|
||
*/
|
||
virtual void setLinearUpscale(bool /*linear*/) {}
|
||
[[nodiscard]] virtual auto isLinearUpscale() const -> bool { return false; }
|
||
|
||
/**
|
||
* @brief Selecciona el algoritmo de downscale tras el PostFX (SS activo).
|
||
* 0 = bilinear legacy (comportamiento actual, sin textura intermedia),
|
||
* 1 = Lanczos2 (ventana 2, ~25 muestras), 2 = Lanczos3 (ventana 3, ~49 muestras).
|
||
*/
|
||
virtual void setDownscaleAlgo(int /*algo*/) {}
|
||
[[nodiscard]] virtual auto getDownscaleAlgo() const -> int { return 0; }
|
||
|
||
/**
|
||
* @brief Devuelve las dimensiones de la textura de supersampling.
|
||
* @return Par (ancho, alto) en píxeles; (0, 0) si SS está desactivado.
|
||
*/
|
||
[[nodiscard]] virtual auto getSsTextureSize() const -> std::pair<int, int> { return {0, 0}; }
|
||
|
||
/**
|
||
* @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
|