millores en els presets

This commit is contained in:
2026-03-21 14:12:11 +01:00
parent 6996b3a82a
commit 23863c02a6
11 changed files with 125 additions and 48 deletions

View File

@@ -30,6 +30,7 @@ auto OpenGLShader::initGLExtensions() -> bool {
glUseProgram = (PFNGLUSEPROGRAMPROC)SDL_GL_GetProcAddress("glUseProgram");
glDeleteProgram = (PFNGLDELETEPROGRAMPROC)SDL_GL_GetProcAddress("glDeleteProgram");
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)SDL_GL_GetProcAddress("glGetUniformLocation");
glUniform1f = (PFNGLUNIFORM1FPROC)SDL_GL_GetProcAddress("glUniform1f");
glUniform2f = (PFNGLUNIFORM2FPROC)SDL_GL_GetProcAddress("glUniform2f");
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)SDL_GL_GetProcAddress("glGenVertexArrays");
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)SDL_GL_GetProcAddress("glBindVertexArray");
@@ -44,7 +45,8 @@ auto OpenGLShader::initGLExtensions() -> bool {
return (glCreateShader != nullptr) && (glShaderSource != nullptr) && (glCompileShader != nullptr) && (glGetShaderiv != nullptr) &&
(glGetShaderInfoLog != nullptr) && (glDeleteShader != nullptr) && (glAttachShader != nullptr) && (glCreateProgram != nullptr) &&
(glLinkProgram != nullptr) && (glValidateProgram != nullptr) && (glGetProgramiv != nullptr) && (glGetProgramInfoLog != nullptr) &&
(glUseProgram != nullptr) && (glDeleteProgram != nullptr) && (glGetUniformLocation != nullptr) && (glUniform2f != nullptr) &&
(glUseProgram != nullptr) && (glDeleteProgram != nullptr) && (glGetUniformLocation != nullptr) &&
(glUniform1f != nullptr) && (glUniform2f != nullptr) &&
(glGenVertexArrays != nullptr) && (glBindVertexArray != nullptr) && (glDeleteVertexArrays != nullptr) &&
(glGenBuffers != nullptr) && (glBindBuffer != nullptr) && (glBufferData != nullptr) && (glDeleteBuffers != nullptr) &&
(glVertexAttribPointer != nullptr) && (glEnableVertexAttribArray != nullptr);
@@ -320,7 +322,7 @@ auto OpenGLShader::init(SDL_Window* window,
// Crear geometría del quad
createQuadGeometry();
// Obtener ubicación del uniform TextureSize
// Obtener ubicaciones de uniforms y configurar valores iniciales
glUseProgram(program_id_);
texture_size_location_ = glGetUniformLocation(program_id_, "TextureSize");
if (texture_size_location_ != -1) {
@@ -334,6 +336,14 @@ auto OpenGLShader::init(SDL_Window* window,
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Uniform 'TextureSize' not found in shader");
}
// Uniforms PostFX
vignette_location_ = glGetUniformLocation(program_id_, "uVignette");
scanlines_location_ = glGetUniformLocation(program_id_, "uScanlines");
chroma_location_ = glGetUniformLocation(program_id_, "uChroma");
if (vignette_location_ != -1) { glUniform1f(vignette_location_, postfx_vignette_); }
if (scanlines_location_ != -1) { glUniform1f(scanlines_location_, postfx_scanlines_); }
if (chroma_location_ != -1) { glUniform1f(chroma_location_, postfx_chroma_); }
glUseProgram(0);
is_initialized_ = true;
@@ -388,6 +398,11 @@ void OpenGLShader::render() {
glUseProgram(program_id_);
checkGLError("glUseProgram");
// Pasar uniforms PostFX
if (vignette_location_ != -1) { glUniform1f(vignette_location_, postfx_vignette_); }
if (scanlines_location_ != -1) { glUniform1f(scanlines_location_, postfx_scanlines_); }
if (chroma_location_ != -1) { glUniform1f(chroma_location_, postfx_chroma_); }
// Configurar viewport (obtener tamaño lógico de SDL)
int logical_w;
int logical_h;
@@ -449,6 +464,12 @@ void OpenGLShader::render() {
glViewport(old_viewport[0], old_viewport[1], old_viewport[2], old_viewport[3]);
}
void OpenGLShader::setPostFXParams(float vignette, float scanlines, float chroma) {
postfx_vignette_ = vignette;
postfx_scanlines_ = scanlines;
postfx_chroma_ = chroma;
}
void OpenGLShader::setTextureSize(float width, float height) {
if (!is_initialized_ || program_id_ == 0) {
return;

View File

@@ -30,6 +30,7 @@ class OpenGLShader : public ShaderBackend {
void render() override;
void setTextureSize(float width, float height) override;
void setPostFXParams(float vignette, float scanlines, float chroma) override;
void cleanup() final;
[[nodiscard]] auto isHardwareAccelerated() const -> bool override { return is_initialized_; }
@@ -55,6 +56,14 @@ class OpenGLShader : public ShaderBackend {
// Ubicaciones de uniforms
GLint texture_size_location_ = -1;
GLint vignette_location_ = -1;
GLint scanlines_location_ = -1;
GLint chroma_location_ = -1;
// Valores cacheados de PostFX
float postfx_vignette_ = 0.6F;
float postfx_scanlines_ = 0.7F;
float postfx_chroma_ = 0.15F;
// Tamaños
int window_width_ = 0;
@@ -83,6 +92,7 @@ class OpenGLShader : public ShaderBackend {
PFNGLUSEPROGRAMPROC glUseProgram = nullptr;
PFNGLDELETEPROGRAMPROC glDeleteProgram = nullptr;
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr;
PFNGLUNIFORM1FPROC glUniform1f = nullptr;
PFNGLUNIFORM2FPROC glUniform2f = nullptr;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = nullptr;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = nullptr;

View File

@@ -448,32 +448,13 @@ auto loadData(const std::string& filepath) -> std::vector<uint8_t> {
// Carga el contenido de los archivos GLSL
void Screen::loadShaders() {
// Obtener nombres de fichero desde el preset actual (o usar fallback)
std::string preset_vertex = "crtpi_vertex.glsl";
std::string preset_fragment = "crtpi_fragment.glsl";
if (!Options::postfx_presets.empty()) {
const auto& preset = Options::postfx_presets[static_cast<size_t>(Options::current_postfx_preset)];
if (!preset.vertex.empty()) {
preset_vertex = preset.vertex;
}
if (!preset.fragment.empty()) {
preset_fragment = preset.fragment;
}
}
if (vertex_shader_source_.empty()) {
// Detectar si necesitamos OpenGL ES (Raspberry Pi)
// Intentar cargar versión ES primero si existe (reemplaza .glsl por _es.glsl)
std::string vertex_es = preset_vertex;
auto pos = vertex_es.rfind(".glsl");
if (pos != std::string::npos) {
vertex_es.insert(pos, "_es");
}
auto data = loadData(Resource::List::get()->get(vertex_es));
// Intentar cargar versión ES primero si existe
auto data = loadData(Resource::List::get()->get("crtpi_vertex_es.glsl"));
if (data.empty()) {
// Si no existe versión ES, usar versión Desktop
data = loadData(Resource::List::get()->get(preset_vertex));
data = loadData(Resource::List::get()->get("crtpi_vertex.glsl"));
std::cout << "Usando shaders OpenGL Desktop 3.3\n";
} else {
std::cout << "Usando shaders OpenGL ES 3.0 (Raspberry Pi)\n";
@@ -485,16 +466,10 @@ void Screen::loadShaders() {
}
if (fragment_shader_source_.empty()) {
// Intentar cargar versión ES primero si existe
std::string fragment_es = preset_fragment;
auto pos = fragment_es.rfind(".glsl");
if (pos != std::string::npos) {
fragment_es.insert(pos, "_es");
}
auto data = loadData(Resource::List::get()->get(fragment_es));
auto data = loadData(Resource::List::get()->get("crtpi_fragment_es.glsl"));
if (data.empty()) {
// Si no existe versión ES, usar versión Desktop
data = loadData(Resource::List::get()->get(preset_fragment));
data = loadData(Resource::List::get()->get("crtpi_fragment.glsl"));
}
if (!data.empty()) {
@@ -503,6 +478,14 @@ void Screen::loadShaders() {
}
}
// Aplica los parámetros del preset actual al backend de shaders
void Screen::applyCurrentPostFXPreset() {
if (shader_backend_ && !Options::postfx_presets.empty()) {
const auto& p = Options::postfx_presets[static_cast<size_t>(Options::current_postfx_preset)];
shader_backend_->setPostFXParams(p.vignette, p.scanlines, p.chroma);
}
}
// Inicializa los shaders
void Screen::initShaders() {
if (!Options::video.postfx) {
@@ -525,6 +508,8 @@ void Screen::initShaders() {
}
shader_backend_->init(window_, tex, vertex_shader_source_, fragment_shader_source_);
#endif
applyCurrentPostFXPreset();
}
// Obtiene información sobre la pantalla

View File

@@ -117,6 +117,7 @@ class Screen {
auto findPalette(const std::string& name) -> size_t; // Localiza la paleta dentro del vector de paletas
void initShaders(); // Inicializa los shaders
void loadShaders(); // Carga el contenido del archivo GLSL
void applyCurrentPostFXPreset(); // Aplica los parámetros del preset actual al backend
void renderInfo(); // Muestra información por pantalla
void getDisplayInfo(); // Obtiene información sobre la pantalla
auto initSDLVideo() -> bool; // Arranca SDL VIDEO y crea la ventana

View File

@@ -416,4 +416,10 @@ auto SDL3GPUShader::createShaderSPIRV(SDL_GPUDevice* device,
return shader;
}
void SDL3GPUShader::setPostFXParams(float vignette, float scanlines, float chroma) {
uniforms_.vignette_strength = vignette;
uniforms_.scanline_strength = scanlines;
uniforms_.chroma_strength = chroma;
}
} // namespace Rendering

View File

@@ -41,6 +41,9 @@ class SDL3GPUShader : public ShaderBackend {
// Sube píxeles ARGB8888 desde CPU; llamado antes de render()
void uploadPixels(const Uint32* pixels, int width, int height) override;
// Actualiza los parámetros de intensidad de los efectos PostFX
void setPostFXParams(float vignette, float scanlines, float chroma) override;
private:
static auto createShaderMSL(SDL_GPUDevice* device,
const char* msl_source,

View File

@@ -52,6 +52,14 @@ class ShaderBackend {
*/
virtual void uploadPixels(const Uint32* /*pixels*/, int /*width*/, int /*height*/) {}
/**
* @brief Establece los parámetros de intensidad de los efectos PostFX
* @param vignette Intensidad de la viñeta (0.0 = ninguna, 1.0 = máxima)
* @param scanlines Intensidad de las scanlines (0.0 = desactivadas, 1.0 = máximas)
* @param chroma Intensidad de la aberración cromática (0.0 = ninguna, 1.0 = máxima)
*/
virtual void setPostFXParams(float /*vignette*/, float /*scanlines*/, float /*chroma*/) {}
/**
* @brief Verifica si el backend está usando aceleración por hardware
* @return true si usa aceleración (OpenGL/Metal/Vulkan)

View File

@@ -681,11 +681,14 @@ auto loadPostFXFromFile() -> bool {
if (p.contains("name")) {
preset.name = p["name"].get_value<std::string>();
}
if (p.contains("vertex")) {
preset.vertex = p["vertex"].get_value<std::string>();
if (p.contains("vignette")) {
try { preset.vignette = p["vignette"].get_value<float>(); } catch (...) {}
}
if (p.contains("fragment")) {
preset.fragment = p["fragment"].get_value<std::string>();
if (p.contains("scanlines")) {
try { preset.scanlines = p["scanlines"].get_value<float>(); } catch (...) {}
}
if (p.contains("chroma")) {
try { preset.chroma = p["chroma"].get_value<float>(); } catch (...) {}
}
postfx_presets.push_back(preset);
}
@@ -720,13 +723,24 @@ auto savePostFXToFile() -> bool {
}
file << "# JailDoctor's Dilemma - PostFX Presets\n";
file << "# Add or modify presets to customize post-processing effects.\n";
file << "# vertex and fragment reference shader filenames from the shaders directory.\n";
file << "# Each preset defines the intensity of post-processing effects (0.0 to 1.0).\n";
file << "# vignette: screen darkening at the edges\n";
file << "# scanlines: horizontal scanline effect\n";
file << "# chroma: chromatic aberration (RGB color fringing)\n";
file << "\n";
file << "presets:\n";
file << " - name: \"CRT\"\n";
file << " vertex: \"crtpi_vertex.glsl\"\n";
file << " fragment: \"crtpi_fragment.glsl\"\n";
file << " vignette: 0.6\n";
file << " scanlines: 0.7\n";
file << " chroma: 0.15\n";
file << " - name: \"SCANLINES\"\n";
file << " vignette: 0.0\n";
file << " scanlines: 0.8\n";
file << " chroma: 0.0\n";
file << " - name: \"SUBTLE\"\n";
file << " vignette: 0.3\n";
file << " scanlines: 0.4\n";
file << " chroma: 0.05\n";
file.close();
@@ -736,7 +750,9 @@ auto savePostFXToFile() -> bool {
// Cargar los presets recién creados
postfx_presets.clear();
postfx_presets.push_back({"CRT", "crtpi_vertex.glsl", "crtpi_fragment.glsl"});
postfx_presets.push_back({"CRT", 0.6F, 0.7F, 0.15F});
postfx_presets.push_back({"SCANLINES", 0.0F, 0.8F, 0.0F});
postfx_presets.push_back({"SUBTLE", 0.3F, 0.4F, 0.05F});
current_postfx_preset = 0;
return true;

View File

@@ -116,9 +116,10 @@ struct Game {
// Estructura para un preset de PostFX
struct PostFXPreset {
std::string name; // Nombre del preset
std::string vertex; // Nombre del fichero vertex shader
std::string fragment; // Nombre del fichero fragment shader
std::string name; // Nombre del preset
float vignette{0.6F}; // Intensidad de la viñeta (0.0 = ninguna, 1.0 = máxima)
float scanlines{0.7F}; // Intensidad de las scanlines (0.0 = desactivadas, 1.0 = máximas)
float chroma{0.15F}; // Intensidad de la aberración cromática (0.0 = ninguna, 1.0 = máxima)
};
// --- Variables globales ---