From 43a6cc2d7a17dbbd380da7d3210fafde42b36f7c Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 21 Mar 2026 17:11:26 +0100 Subject: [PATCH] llevant el soport de opengl --- CMakeLists.txt | 38 +- config/assets.yaml | 11 - data/shaders/crtpi_fragment.glsl | 160 ------ data/shaders/crtpi_fragment_es.glsl | 163 ------ data/shaders/crtpi_vertex.glsl | 48 -- data/shaders/crtpi_vertex_es.glsl | 51 -- .../core/rendering/opengl/opengl_shader.cpp | 542 ------------------ .../core/rendering/opengl/opengl_shader.hpp | 119 ---- source/core/rendering/screen.cpp | 94 +-- source/core/rendering/screen.hpp | 7 +- 10 files changed, 13 insertions(+), 1220 deletions(-) delete mode 100644 data/shaders/crtpi_fragment.glsl delete mode 100644 data/shaders/crtpi_fragment_es.glsl delete mode 100644 data/shaders/crtpi_vertex.glsl delete mode 100644 data/shaders/crtpi_vertex_es.glsl delete mode 100644 source/core/rendering/opengl/opengl_shader.cpp delete mode 100644 source/core/rendering/opengl/opengl_shader.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7be65305..02185516 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,13 +10,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) # Exportar comandos de compilación para herramientas de análisis set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -# Establece la política CMP0072 para indicar cómo se debe seleccionar la implementación de OpenGL. -# En este caso, se elige la opción "GLVND", que utiliza bibliotecas modernas y modulares (libOpenGL, libGLX), -# en lugar de la biblioteca OpenGL clásica (libGL). Esto mejora la compatibilidad con drivers recientes -# y evita ambigüedades cuando se encuentran múltiples implementaciones de OpenGL en el sistema. -cmake_policy(SET CMP0072 NEW) -set(OpenGL_GL_PREFERENCE GLVND) - # --- GENERACIÓN DE VERSIÓN AUTOMÁTICA --- find_package(Git QUIET) if(GIT_FOUND) @@ -110,18 +103,10 @@ set(APP_SOURCES source/main.cpp ) -# Fuentes del sistema de renderizado -# En macOS usamos SDL3 GPU (Metal), no OpenGL -if(APPLE) - set(RENDERING_SOURCES - source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp - ) -else() - set(RENDERING_SOURCES - source/core/rendering/opengl/opengl_shader.cpp - source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp - ) -endif() +# Fuentes del sistema de renderizado (SDL3 GPU para todas las plataformas) +set(RENDERING_SOURCES + source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp +) # Fuentes de debug (solo en modo Debug) set(DEBUG_SOURCES @@ -160,7 +145,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE $<$:RELEASE_B # Configuración específica para cada plataforma if(WIN32) target_compile_definitions(${PROJECT_NAME} PRIVATE WINDOWS_BUILD) - target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32 mingw32 opengl32) + target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32 mingw32) elseif(APPLE) target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUILD) target_compile_options(${PROJECT_NAME} PRIVATE -Wno-deprecated) @@ -169,19 +154,6 @@ elseif(UNIX AND NOT APPLE) target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD) endif() -# Configuración común para OpenGL (no requerido en macOS: usamos SDL3 GPU API / Metal) -if(WIN32) - target_link_libraries(${PROJECT_NAME} PRIVATE opengl32) -elseif(NOT APPLE) - find_package(OpenGL REQUIRED) - if(OPENGL_FOUND) - message(STATUS "OpenGL encontrado: ${OPENGL_LIBRARIES}") - target_link_libraries(${PROJECT_NAME} PRIVATE ${OPENGL_LIBRARIES}) - else() - message(FATAL_ERROR "OpenGL no encontrado") - endif() -endif() - # Especificar la ubicación del ejecutable set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}) diff --git a/config/assets.yaml b/config/assets.yaml index 55d3a8ed..fe00de98 100644 --- a/config/assets.yaml +++ b/config/assets.yaml @@ -56,17 +56,6 @@ assets: - type: PALETTE path: ${PREFIX}/data/palette/steam-lords.pal - # SHADERS - shaders: - - type: DATA - path: ${PREFIX}/data/shaders/crtpi_vertex.glsl - - type: DATA - path: ${PREFIX}/data/shaders/crtpi_fragment.glsl - - type: DATA - path: ${PREFIX}/data/shaders/crtpi_vertex_es.glsl - - type: DATA - path: ${PREFIX}/data/shaders/crtpi_fragment_es.glsl - # INPUT input: - type: DATA diff --git a/data/shaders/crtpi_fragment.glsl b/data/shaders/crtpi_fragment.glsl deleted file mode 100644 index a6f2991f..00000000 --- a/data/shaders/crtpi_fragment.glsl +++ /dev/null @@ -1,160 +0,0 @@ -#version 330 core - -// Configuración -#define SCANLINES -#define MULTISAMPLE - -#define SCANLINE_WEIGHT 6.0 -#define SCANLINE_GAP_BRIGHTNESS 0.12 -#define BLOOM_FACTOR 3.5 - -// Inputs desde vertex shader -in vec2 vTexCoord; -in float vFilterWidth; - -// Output -out vec4 FragColor; - -// Uniforms existentes -uniform sampler2D Texture; -uniform vec2 TextureSize; -uniform float uVignette; // 0 = sin viñeta, 1 = máxima -uniform float uScanlines; // 0 = desactivadas, 1 = plenas -uniform float uChroma; // 0 = sin aberración, 1 = máxima -uniform float uOutputHeight; // altura del viewport en pixels de pantalla - -// Nuevos uniforms -uniform float uMask; // 0 = sin máscara de fósforo, 1 = máxima -uniform float uGamma; // 0 = sin corrección gamma, 1 = gamma 2.4/2.2 plena -uniform float uCurvature; // 0 = plana, 1 = curvatura barrel máxima -uniform float uBleeding; // 0 = sin sangrado NTSC, 1 = máximo - -// Conversores YCbCr para efecto NTSC -vec3 rgb_to_ycc(vec3 rgb) { - return vec3( - 0.299*rgb.r + 0.587*rgb.g + 0.114*rgb.b, - -0.169*rgb.r - 0.331*rgb.g + 0.500*rgb.b + 0.5, - 0.500*rgb.r - 0.419*rgb.g - 0.081*rgb.b + 0.5 - ); -} -vec3 ycc_to_rgb(vec3 ycc) { - float y = ycc.x; - float cb = ycc.y - 0.5; - float cr = ycc.z - 0.5; - return clamp(vec3( - y + 1.402*cr, - y - 0.344*cb - 0.714*cr, - y + 1.772*cb - ), 0.0, 1.0); -} - -float CalcScanLineWeight(float dist) -{ - return max(1.0 - dist * dist * SCANLINE_WEIGHT, SCANLINE_GAP_BRIGHTNESS); -} - -void main() -{ - vec2 texcoord = vTexCoord; - - // Curvatura barrel CRT (distorsión en UV antes de muestrear) - if (uCurvature > 0.0) { - vec2 c = texcoord - 0.5; - float rsq = dot(c, c); - vec2 dist = vec2(0.05, 0.1) * uCurvature; - vec2 barrelScale = 1.0 - 0.23 * dist; - c += c * (dist * rsq); - c *= barrelScale; - if (abs(c.x) >= 0.5 || abs(c.y) >= 0.5) { - FragColor = vec4(0.0); - return; - } - texcoord = c + 0.5; - } - - vec2 texcoordInPixels = texcoord * TextureSize; - - float tempY = floor(texcoordInPixels.y) + 0.5; - float yCoord = tempY / TextureSize.y; - - // Scanline en espacio de pantalla (subpíxel) - float scaleY = uOutputHeight / TextureSize.y; - float screenY = texcoord.y * uOutputHeight; - float posInRow = mod(screenY, scaleY); - float scanLineDY = posInRow / scaleY - 0.5; - float localFilterWidth = 1.0 / scaleY; - float scanLineWeight = CalcScanLineWeight(scanLineDY); - scanLineWeight += CalcScanLineWeight(scanLineDY - localFilterWidth); - scanLineWeight += CalcScanLineWeight(scanLineDY + localFilterWidth); - scanLineWeight *= 0.3333333; - - // Phosphor blur en espacio textura - float dy = texcoordInPixels.y - tempY; - float signY = sign(dy); - dy = dy * dy; - dy = dy * dy; - dy *= 8.0; - dy /= TextureSize.y; - dy *= signY; - vec2 tc = vec2(texcoord.x, yCoord + dy); - - // Muestra base en centro - vec3 base = texture(Texture, tc).rgb; - - // Sangrado NTSC — difuminado horizontal de crominancia - vec3 colour; - if (uBleeding > 0.0) { - float tw = TextureSize.x; - vec3 ycc = rgb_to_ycc(base); - vec3 ycc_l2 = rgb_to_ycc(texture(Texture, tc - vec2(2.0/tw, 0.0)).rgb); - vec3 ycc_l1 = rgb_to_ycc(texture(Texture, tc - vec2(1.0/tw, 0.0)).rgb); - vec3 ycc_r1 = rgb_to_ycc(texture(Texture, tc + vec2(1.0/tw, 0.0)).rgb); - vec3 ycc_r2 = rgb_to_ycc(texture(Texture, tc + vec2(2.0/tw, 0.0)).rgb); - ycc.yz = (ycc_l2.yz + ycc_l1.yz*2.0 + ycc.yz*2.0 + ycc_r1.yz*2.0 + ycc_r2.yz) / 8.0; - colour = mix(base, ycc_to_rgb(ycc), uBleeding); - } else { - colour = base; - } - - // Aberración cromática - float ca = uChroma * 0.005; - colour.r = texture(Texture, tc + vec2(ca, 0.0)).r; - colour.b = texture(Texture, tc - vec2(ca, 0.0)).b; - - // Corrección gamma (linealizar antes de scanlines, codificar después) - if (uGamma > 0.0) { - vec3 lin = pow(colour, vec3(2.4)); - colour = mix(colour, lin, uGamma); - } - - // Scanlines - scanLineWeight *= BLOOM_FACTOR; - colour *= mix(1.0, scanLineWeight, uScanlines); - - if (uGamma > 0.0) { - vec3 enc = pow(colour, vec3(1.0 / 2.2)); - colour = mix(colour, enc, uGamma); - } - - // Viñeta - if (uVignette > 0.0) { - vec2 uv = texcoord - vec2(0.5); - float vig = 1.0 - dot(uv, uv) * uVignette * 4.0; - colour *= clamp(vig, 0.0, 1.0); - } - - // Máscara de fósforo RGB - if (uMask > 0.0) { - float whichMask = fract(gl_FragCoord.x * 0.3333333); - vec3 mask = vec3(0.80); - if (whichMask < 0.3333333) - mask.x = 1.0; - else if (whichMask < 0.6666666) - mask.y = 1.0; - else - mask.z = 1.0; - colour = mix(colour, colour * mask, uMask); - } - - FragColor = vec4(colour, 1.0); -} diff --git a/data/shaders/crtpi_fragment_es.glsl b/data/shaders/crtpi_fragment_es.glsl deleted file mode 100644 index 7b2e31d4..00000000 --- a/data/shaders/crtpi_fragment_es.glsl +++ /dev/null @@ -1,163 +0,0 @@ -#version 300 es - -// OpenGL ES 3.0 - Compatible con Raspberry Pi 5 -precision highp float; - -// Configuración -#define SCANLINES -#define MULTISAMPLE - -#define SCANLINE_WEIGHT 6.0 -#define SCANLINE_GAP_BRIGHTNESS 0.12 -#define BLOOM_FACTOR 3.5 - -// Inputs desde vertex shader -in vec2 vTexCoord; -in float vFilterWidth; - -// Output -out vec4 FragColor; - -// Uniforms existentes -uniform sampler2D Texture; -uniform vec2 TextureSize; -uniform float uVignette; // 0 = sin viñeta, 1 = máxima -uniform float uScanlines; // 0 = desactivadas, 1 = plenas -uniform float uChroma; // 0 = sin aberración, 1 = máxima -uniform float uOutputHeight; // altura del viewport en pixels de pantalla - -// Nuevos uniforms -uniform float uMask; // 0 = sin máscara de fósforo, 1 = máxima -uniform float uGamma; // 0 = sin corrección gamma, 1 = gamma 2.4/2.2 plena -uniform float uCurvature; // 0 = plana, 1 = curvatura barrel máxima -uniform float uBleeding; // 0 = sin sangrado NTSC, 1 = máximo - -// Conversores YCbCr para efecto NTSC -vec3 rgb_to_ycc(vec3 rgb) { - return vec3( - 0.299*rgb.r + 0.587*rgb.g + 0.114*rgb.b, - -0.169*rgb.r - 0.331*rgb.g + 0.500*rgb.b + 0.5, - 0.500*rgb.r - 0.419*rgb.g - 0.081*rgb.b + 0.5 - ); -} -vec3 ycc_to_rgb(vec3 ycc) { - float y = ycc.x; - float cb = ycc.y - 0.5; - float cr = ycc.z - 0.5; - return clamp(vec3( - y + 1.402*cr, - y - 0.344*cb - 0.714*cr, - y + 1.772*cb - ), 0.0, 1.0); -} - -float CalcScanLineWeight(float dist) -{ - return max(1.0 - dist * dist * SCANLINE_WEIGHT, SCANLINE_GAP_BRIGHTNESS); -} - -void main() -{ - vec2 texcoord = vTexCoord; - - // Curvatura barrel CRT (distorsión en UV antes de muestrear) - if (uCurvature > 0.0) { - vec2 c = texcoord - vec2(0.5); - float rsq = dot(c, c); - vec2 dist = vec2(0.05, 0.1) * uCurvature; - vec2 barrelScale = vec2(1.0) - 0.23 * dist; - c += c * (dist * rsq); - c *= barrelScale; - if (abs(c.x) >= 0.5 || abs(c.y) >= 0.5) { - FragColor = vec4(0.0); - return; - } - texcoord = c + vec2(0.5); - } - - vec2 texcoordInPixels = texcoord * TextureSize; - - float tempY = floor(texcoordInPixels.y) + 0.5; - float yCoord = tempY / TextureSize.y; - - // Scanline en espacio de pantalla (subpíxel) - float scaleY = uOutputHeight / TextureSize.y; - float screenY = texcoord.y * uOutputHeight; - float posInRow = mod(screenY, scaleY); - float scanLineDY = posInRow / scaleY - 0.5; - float localFilterWidth = 1.0 / scaleY; - float scanLineWeight = CalcScanLineWeight(scanLineDY); - scanLineWeight += CalcScanLineWeight(scanLineDY - localFilterWidth); - scanLineWeight += CalcScanLineWeight(scanLineDY + localFilterWidth); - scanLineWeight *= 0.3333333; - - // Phosphor blur en espacio textura - float dy = texcoordInPixels.y - tempY; - float signY = sign(dy); - dy = dy * dy; - dy = dy * dy; - dy *= 8.0; - dy /= TextureSize.y; - dy *= signY; - vec2 tc = vec2(texcoord.x, yCoord + dy); - - // Muestra base en centro - vec3 base = texture(Texture, tc).rgb; - - // Sangrado NTSC — difuminado horizontal de crominancia - vec3 colour; - if (uBleeding > 0.0) { - float tw = TextureSize.x; - vec3 ycc = rgb_to_ycc(base); - vec3 ycc_l2 = rgb_to_ycc(texture(Texture, tc - vec2(2.0/tw, 0.0)).rgb); - vec3 ycc_l1 = rgb_to_ycc(texture(Texture, tc - vec2(1.0/tw, 0.0)).rgb); - vec3 ycc_r1 = rgb_to_ycc(texture(Texture, tc + vec2(1.0/tw, 0.0)).rgb); - vec3 ycc_r2 = rgb_to_ycc(texture(Texture, tc + vec2(2.0/tw, 0.0)).rgb); - ycc.yz = (ycc_l2.yz + ycc_l1.yz*2.0 + ycc.yz*2.0 + ycc_r1.yz*2.0 + ycc_r2.yz) / 8.0; - colour = mix(base, ycc_to_rgb(ycc), uBleeding); - } else { - colour = base; - } - - // Aberración cromática - float ca = uChroma * 0.005; - colour.r = texture(Texture, tc + vec2(ca, 0.0)).r; - colour.b = texture(Texture, tc - vec2(ca, 0.0)).b; - - // Corrección gamma (linealizar antes de scanlines, codificar después) - if (uGamma > 0.0) { - vec3 lin = pow(colour, vec3(2.4)); - colour = mix(colour, lin, uGamma); - } - - // Scanlines - scanLineWeight *= BLOOM_FACTOR; - colour *= mix(1.0, scanLineWeight, uScanlines); - - if (uGamma > 0.0) { - vec3 enc = pow(colour, vec3(1.0 / 2.2)); - colour = mix(colour, enc, uGamma); - } - - // Viñeta - if (uVignette > 0.0) { - vec2 uv = texcoord - vec2(0.5); - float vig = 1.0 - dot(uv, uv) * uVignette * 4.0; - colour *= clamp(vig, 0.0, 1.0); - } - - // Máscara de fósforo RGB - if (uMask > 0.0) { - float whichMask = fract(gl_FragCoord.x * 0.3333333); - vec3 mask = vec3(0.80); - if (whichMask < 0.3333333) - mask.x = 1.0; - else if (whichMask < 0.6666666) - mask.y = 1.0; - else - mask.z = 1.0; - colour = mix(colour, colour * mask, uMask); - } - - FragColor = vec4(colour, 1.0); -} diff --git a/data/shaders/crtpi_vertex.glsl b/data/shaders/crtpi_vertex.glsl deleted file mode 100644 index 66102c63..00000000 --- a/data/shaders/crtpi_vertex.glsl +++ /dev/null @@ -1,48 +0,0 @@ -#version 330 core - -// Configuración -#define SCANLINES -#define MULTISAMPLE -#define GAMMA -//#define FAKE_GAMMA -//#define CURVATURE -//#define SHARPER -#define MASK_TYPE 2 - -#define CURVATURE_X 0.05 -#define CURVATURE_Y 0.1 -#define MASK_BRIGHTNESS 0.80 -#define SCANLINE_WEIGHT 6.0 -#define SCANLINE_GAP_BRIGHTNESS 0.12 -#define BLOOM_FACTOR 3.5 -#define INPUT_GAMMA 2.4 -#define OUTPUT_GAMMA 2.2 - -// Inputs (desde VAO) -layout(location = 0) in vec2 aPosition; -layout(location = 1) in vec2 aTexCoord; - -// Outputs al fragment shader -out vec2 vTexCoord; -out float vFilterWidth; -#if defined(CURVATURE) -out vec2 vScreenScale; -#endif - -// Uniforms -uniform vec2 TextureSize; - -void main() -{ -#if defined(CURVATURE) - vScreenScale = vec2(1.0, 1.0); -#endif - // Calcula filterWidth dinámicamente basándose en la altura de la textura - vFilterWidth = (768.0 / TextureSize.y) / 3.0; - - // Pasar coordenadas de textura (invertir Y para SDL) - vTexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y) * 1.0001; - - // Posición del vértice (ya en espacio de clip [-1, 1]) - gl_Position = vec4(aPosition, 0.0, 1.0); -} diff --git a/data/shaders/crtpi_vertex_es.glsl b/data/shaders/crtpi_vertex_es.glsl deleted file mode 100644 index dd04db5a..00000000 --- a/data/shaders/crtpi_vertex_es.glsl +++ /dev/null @@ -1,51 +0,0 @@ -#version 300 es - -// OpenGL ES 3.0 - Compatible con Raspberry Pi 5 -precision highp float; - -// Configuración -#define SCANLINES -#define MULTISAMPLE -#define GAMMA -//#define FAKE_GAMMA -//#define CURVATURE -//#define SHARPER -#define MASK_TYPE 2 - -#define CURVATURE_X 0.05 -#define CURVATURE_Y 0.1 -#define MASK_BRIGHTNESS 0.80 -#define SCANLINE_WEIGHT 6.0 -#define SCANLINE_GAP_BRIGHTNESS 0.12 -#define BLOOM_FACTOR 3.5 -#define INPUT_GAMMA 2.4 -#define OUTPUT_GAMMA 2.2 - -// Inputs (desde VAO) -layout(location = 0) in vec2 aPosition; -layout(location = 1) in vec2 aTexCoord; - -// Outputs al fragment shader -out vec2 vTexCoord; -out float vFilterWidth; -#if defined(CURVATURE) -out vec2 vScreenScale; -#endif - -// Uniforms -uniform vec2 TextureSize; - -void main() -{ -#if defined(CURVATURE) - vScreenScale = vec2(1.0, 1.0); -#endif - // Calcula filterWidth dinámicamente basándose en la altura de la textura - vFilterWidth = (768.0 / TextureSize.y) / 3.0; - - // Pasar coordenadas de textura (invertir Y para SDL) - vTexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y) * 1.0001; - - // Posición del vértice (ya en espacio de clip [-1, 1]) - gl_Position = vec4(aPosition, 0.0, 1.0); -} diff --git a/source/core/rendering/opengl/opengl_shader.cpp b/source/core/rendering/opengl/opengl_shader.cpp deleted file mode 100644 index d01a19c3..00000000 --- a/source/core/rendering/opengl/opengl_shader.cpp +++ /dev/null @@ -1,542 +0,0 @@ -#include "core/rendering/opengl/opengl_shader.hpp" - -#include - -#include -#include -#include -#include - -namespace Rendering { - -OpenGLShader::~OpenGLShader() { - cleanup(); -} - -#ifndef __APPLE__ -auto OpenGLShader::initGLExtensions() -> bool { - glCreateShader = (PFNGLCREATESHADERPROC)SDL_GL_GetProcAddress("glCreateShader"); - glShaderSource = (PFNGLSHADERSOURCEPROC)SDL_GL_GetProcAddress("glShaderSource"); - glCompileShader = (PFNGLCOMPILESHADERPROC)SDL_GL_GetProcAddress("glCompileShader"); - glGetShaderiv = (PFNGLGETSHADERIVPROC)SDL_GL_GetProcAddress("glGetShaderiv"); - glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)SDL_GL_GetProcAddress("glGetShaderInfoLog"); - glDeleteShader = (PFNGLDELETESHADERPROC)SDL_GL_GetProcAddress("glDeleteShader"); - glAttachShader = (PFNGLATTACHSHADERPROC)SDL_GL_GetProcAddress("glAttachShader"); - glCreateProgram = (PFNGLCREATEPROGRAMPROC)SDL_GL_GetProcAddress("glCreateProgram"); - glLinkProgram = (PFNGLLINKPROGRAMPROC)SDL_GL_GetProcAddress("glLinkProgram"); - glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)SDL_GL_GetProcAddress("glValidateProgram"); - glGetProgramiv = (PFNGLGETPROGRAMIVPROC)SDL_GL_GetProcAddress("glGetProgramiv"); - glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)SDL_GL_GetProcAddress("glGetProgramInfoLog"); - 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"); - glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)SDL_GL_GetProcAddress("glDeleteVertexArrays"); - glGenBuffers = (PFNGLGENBUFFERSPROC)SDL_GL_GetProcAddress("glGenBuffers"); - glBindBuffer = (PFNGLBINDBUFFERPROC)SDL_GL_GetProcAddress("glBindBuffer"); - glBufferData = (PFNGLBUFFERDATAPROC)SDL_GL_GetProcAddress("glBufferData"); - glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)SDL_GL_GetProcAddress("glDeleteBuffers"); - glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)SDL_GL_GetProcAddress("glVertexAttribPointer"); - glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)SDL_GL_GetProcAddress("glEnableVertexAttribArray"); - - 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) && - (glUniform1f != nullptr) && (glUniform2f != nullptr) && - (glGenVertexArrays != nullptr) && (glBindVertexArray != nullptr) && (glDeleteVertexArrays != nullptr) && - (glGenBuffers != nullptr) && (glBindBuffer != nullptr) && (glBufferData != nullptr) && (glDeleteBuffers != nullptr) && - (glVertexAttribPointer != nullptr) && (glEnableVertexAttribArray != nullptr); -} -#endif - -void OpenGLShader::checkGLError(const char* operation) { - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Error OpenGL en %s: 0x%x", - operation, - error); - } -} - -auto OpenGLShader::compileShader(const std::string& source, GLenum shader_type) -> GLuint { - if (source.empty()) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "ERROR: El código fuente del shader está vacío"); - return 0; - } - - GLuint shader_id = glCreateShader(shader_type); - if (shader_id == 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error al crear shader"); - checkGLError("glCreateShader"); - return 0; - } - - const char* sources[1] = {source.c_str()}; - glShaderSource(shader_id, 1, sources, nullptr); - checkGLError("glShaderSource"); - - glCompileShader(shader_id); - checkGLError("glCompileShader"); - - // Verificar compilación - GLint compiled = GL_FALSE; - glGetShaderiv(shader_id, GL_COMPILE_STATUS, &compiled); - if (compiled != GL_TRUE) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Error en compilación del shader"); - GLint log_length; - glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &log_length); - if (log_length > 0) { - std::vector log(log_length); - glGetShaderInfoLog(shader_id, log_length, &log_length, log.data()); - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Log de compilación: %s", - log.data()); - } - glDeleteShader(shader_id); - return 0; - } - - return shader_id; -} - -auto OpenGLShader::linkProgram(GLuint vertex_shader, GLuint fragment_shader) -> GLuint { - GLuint program = glCreateProgram(); - if (program == 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Error al crear programa de shaders"); - return 0; - } - - glAttachShader(program, vertex_shader); - checkGLError("glAttachShader(vertex)"); - glAttachShader(program, fragment_shader); - checkGLError("glAttachShader(fragment)"); - - glLinkProgram(program); - checkGLError("glLinkProgram"); - - // Verificar enlace - GLint linked = GL_FALSE; - glGetProgramiv(program, GL_LINK_STATUS, &linked); - if (linked != GL_TRUE) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Error al enlazar programa"); - GLint log_length; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length); - if (log_length > 0) { - std::vector log(log_length); - glGetProgramInfoLog(program, log_length, &log_length, log.data()); - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Log de enlace: %s", - log.data()); - } - glDeleteProgram(program); - return 0; - } - - glValidateProgram(program); - checkGLError("glValidateProgram"); - - return program; -} - -void OpenGLShader::createQuadGeometry() { - // Datos del quad: posición (x, y) + coordenadas de textura (u, v) - // Formato: x, y, u, v - float vertices[] = { - // Posición // TexCoords - -1.0F, - -1.0F, - 0.0F, - 0.0F, // Inferior izquierda - 1.0F, - -1.0F, - 1.0F, - 0.0F, // Inferior derecha - 1.0F, - 1.0F, - 1.0F, - 1.0F, // Superior derecha - -1.0F, - 1.0F, - 0.0F, - 1.0F // Superior izquierda - }; - - // Índices para dibujar el quad con dos triángulos - unsigned int indices[] = { - 0, - 1, - 2, // Primer triángulo - 2, - 3, - 0 // Segundo triángulo - }; - - // Generar y configurar VAO - glGenVertexArrays(1, &vao_); - glBindVertexArray(vao_); - checkGLError("glBindVertexArray"); - - // Generar y configurar VBO - glGenBuffers(1, &vbo_); - glBindBuffer(GL_ARRAY_BUFFER, vbo_); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - checkGLError("glBufferData(VBO)"); - - // Generar y configurar EBO - glGenBuffers(1, &ebo_); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - checkGLError("glBufferData(EBO)"); - - // Atributo 0: Posición (2 floats) - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)nullptr); - glEnableVertexAttribArray(0); - checkGLError("glVertexAttribPointer(position)"); - - // Atributo 1: Coordenadas de textura (2 floats) - // NOLINTNEXTLINE(performance-no-int-to-ptr) - OpenGL uses pointer as buffer offset - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), reinterpret_cast(static_cast(2 * sizeof(float)))); - glEnableVertexAttribArray(1); - checkGLError("glVertexAttribPointer(texcoord)"); - - // Desvincular - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); -} - -auto OpenGLShader::getTextureID(SDL_Texture* texture) -> GLuint { - if (texture == nullptr) { - return 1; - } - - SDL_PropertiesID props = SDL_GetTextureProperties(texture); - GLuint texture_id = 0; - - // Intentar obtener ID de textura OpenGL - texture_id = (GLuint)(uintptr_t)SDL_GetPointerProperty(props, "SDL.texture.opengl.texture", nullptr); - - if (texture_id == 0) { - texture_id = (GLuint)(uintptr_t)SDL_GetPointerProperty(props, "texture.opengl.texture", nullptr); - } - - if (texture_id == 0) { - texture_id = (GLuint)SDL_GetNumberProperty(props, "SDL.texture.opengl.texture", 1); - } - - if (texture_id == 0) { - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "No se pudo obtener ID de textura OpenGL, usando 1 por defecto"); - texture_id = 1; - } - - return texture_id; -} - -auto OpenGLShader::init(SDL_Window* window, - SDL_Texture* texture, - const std::string& vertex_source, - const std::string& fragment_source) -> bool { - window_ = window; - back_buffer_ = texture; - renderer_ = SDL_GetRenderer(window); - - if (renderer_ == nullptr) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Error: No se pudo obtener el renderer"); - return false; - } - - // Obtener tamaños - SDL_GetWindowSize(window_, &window_width_, &window_height_); - SDL_GetTextureSize(back_buffer_, &texture_width_, &texture_height_); - - SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, - "Initializing shaders: window=%dx%d, texture=%.0fx%.0f", - window_width_, - window_height_, - texture_width_, - texture_height_); - - // Verificar que es OpenGL - const char* renderer_name = SDL_GetRendererName(renderer_); - if ((renderer_name == nullptr) || strncmp(renderer_name, "opengl", 6) != 0) { - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "Renderer is not OpenGL: %s", - (renderer_name != nullptr) ? renderer_name : "unknown"); - return false; - } - -#ifndef __APPLE__ - // Inicializar extensiones OpenGL en Windows/Linux - if (!initGLExtensions()) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Failed to initialize OpenGL extensions"); - return false; - } -#endif - - // Limpiar shader anterior si existe - if (program_id_ != 0) { - glDeleteProgram(program_id_); - program_id_ = 0; - } - - // Compilar shaders - GLuint vertex_shader = compileShader(vertex_source, GL_VERTEX_SHADER); - GLuint fragment_shader = compileShader(fragment_source, GL_FRAGMENT_SHADER); - - if (vertex_shader == 0 || fragment_shader == 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Failed to compile shaders"); - if (vertex_shader != 0) { - glDeleteShader(vertex_shader); - } - if (fragment_shader != 0) { - glDeleteShader(fragment_shader); - } - return false; - } - - // Enlazar programa - program_id_ = linkProgram(vertex_shader, fragment_shader); - - // Limpiar shaders (ya no necesarios tras el enlace) - glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); - - if (program_id_ == 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Failed to create shader program"); - return false; - } - - // Crear geometría del quad - createQuadGeometry(); - - // Obtener ubicaciones de uniforms y configurar valores iniciales - glUseProgram(program_id_); - texture_size_location_ = glGetUniformLocation(program_id_, "TextureSize"); - if (texture_size_location_ != -1) { - SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, - "Configuring TextureSize uniform: %.0fx%.0f", - texture_width_, - texture_height_); - glUniform2f(texture_size_location_, texture_width_, texture_height_); - checkGLError("glUniform2f(TextureSize)"); - } else { - 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"); - output_height_location_ = glGetUniformLocation(program_id_, "uOutputHeight"); - mask_location_ = glGetUniformLocation(program_id_, "uMask"); - gamma_location_ = glGetUniformLocation(program_id_, "uGamma"); - curvature_location_ = glGetUniformLocation(program_id_, "uCurvature"); - bleeding_location_ = glGetUniformLocation(program_id_, "uBleeding"); - 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_); } - if (mask_location_ != -1) { glUniform1f(mask_location_, postfx_mask_); } - if (gamma_location_ != -1) { glUniform1f(gamma_location_, postfx_gamma_); } - if (curvature_location_ != -1) { glUniform1f(curvature_location_, postfx_curvature_); } - if (bleeding_location_ != -1) { glUniform1f(bleeding_location_, postfx_bleeding_); } - glUseProgram(0); - - is_initialized_ = true; - SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, - "** OpenGL 3.3 Shader Backend initialized successfully"); - - return true; -} - -void OpenGLShader::render() { - if (!is_initialized_ || program_id_ == 0) { - // Fallback: renderizado SDL normal - SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255); - SDL_SetRenderTarget(renderer_, nullptr); - SDL_RenderClear(renderer_); - SDL_RenderTexture(renderer_, back_buffer_, nullptr, nullptr); - SDL_RenderPresent(renderer_); - return; - } - - // Obtener tamaño actual de ventana (puede haber cambiado) - int current_width; - int current_height; - SDL_GetWindowSize(window_, ¤t_width, ¤t_height); - - // Guardar estados OpenGL - GLint old_program; - glGetIntegerv(GL_CURRENT_PROGRAM, &old_program); - - GLint old_viewport[4]; - glGetIntegerv(GL_VIEWPORT, old_viewport); - - GLboolean was_texture_enabled = glIsEnabled(GL_TEXTURE_2D); - GLint old_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_texture); - - GLint old_vao; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao); - - // Preparar renderizado - SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255); - SDL_SetRenderTarget(renderer_, nullptr); - SDL_RenderClear(renderer_); - - // Obtener y bindear textura - GLuint texture_id = getTextureID(back_buffer_); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texture_id); - checkGLError("glBindTexture"); - - // Usar nuestro programa - 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_); } - if (mask_location_ != -1) { glUniform1f(mask_location_, postfx_mask_); } - if (gamma_location_ != -1) { glUniform1f(gamma_location_, postfx_gamma_); } - if (curvature_location_ != -1) { glUniform1f(curvature_location_, postfx_curvature_); } - if (bleeding_location_ != -1) { glUniform1f(bleeding_location_, postfx_bleeding_); } - - // Configurar viewport (obtener tamaño lógico de SDL) - int logical_w; - int logical_h; - SDL_RendererLogicalPresentation mode; - SDL_GetRenderLogicalPresentation(renderer_, &logical_w, &logical_h, &mode); - - if (logical_w == 0 || logical_h == 0) { - logical_w = current_width; - logical_h = current_height; - } - - // Calcular viewport considerando aspect ratio - int viewport_x = 0; - int viewport_y = 0; - int viewport_w = current_width; - int viewport_h = current_height; - - if (mode == SDL_LOGICAL_PRESENTATION_INTEGER_SCALE) { - int scale_x = current_width / logical_w; - int scale_y = current_height / logical_h; - int scale = (scale_x < scale_y) ? scale_x : scale_y; - scale = std::max(scale, 1); - - viewport_w = logical_w * scale; - viewport_h = logical_h * scale; - viewport_x = (current_width - viewport_w) / 2; - viewport_y = (current_height - viewport_h) / 2; - } else { - float window_aspect = static_cast(current_width) / current_height; - float logical_aspect = static_cast(logical_w) / logical_h; - - if (window_aspect > logical_aspect) { - viewport_w = static_cast(logical_aspect * current_height); - viewport_x = (current_width - viewport_w) / 2; - } else { - viewport_h = static_cast(current_width / logical_aspect); - viewport_y = (current_height - viewport_h) / 2; - } - } - - glViewport(viewport_x, viewport_y, viewport_w, viewport_h); - checkGLError("glViewport"); - - if (output_height_location_ != -1) { - glUniform1f(output_height_location_, static_cast(viewport_h)); - } - - // Dibujar quad usando VAO - glBindVertexArray(vao_); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); - checkGLError("glDrawElements"); - - // Presentar - SDL_GL_SwapWindow(window_); - - // Restaurar estados OpenGL - glUseProgram(old_program); - glBindTexture(GL_TEXTURE_2D, old_texture); - if (was_texture_enabled == 0U) { - glDisable(GL_TEXTURE_2D); - } - glBindVertexArray(old_vao); - glViewport(old_viewport[0], old_viewport[1], old_viewport[2], old_viewport[3]); -} - -void OpenGLShader::setPostFXParams(const PostFXParams& p) { - postfx_vignette_ = p.vignette; - postfx_scanlines_ = p.scanlines; - postfx_chroma_ = p.chroma; - postfx_mask_ = p.mask; - postfx_gamma_ = p.gamma; - postfx_curvature_ = p.curvature; - postfx_bleeding_ = p.bleeding; -} - -void OpenGLShader::setTextureSize(float width, float height) { - if (!is_initialized_ || program_id_ == 0) { - return; - } - - texture_width_ = width; - texture_height_ = height; - - GLint old_program; - glGetIntegerv(GL_CURRENT_PROGRAM, &old_program); - - glUseProgram(program_id_); - - if (texture_size_location_ != -1) { - glUniform2f(texture_size_location_, width, height); - checkGLError("glUniform2f(TextureSize)"); - } - - glUseProgram(old_program); -} - -void OpenGLShader::cleanup() { - if (vao_ != 0) { - glDeleteVertexArrays(1, &vao_); - vao_ = 0; - } - - if (vbo_ != 0) { - glDeleteBuffers(1, &vbo_); - vbo_ = 0; - } - - if (ebo_ != 0) { - glDeleteBuffers(1, &ebo_); - ebo_ = 0; - } - - if (program_id_ != 0) { - glDeleteProgram(program_id_); - program_id_ = 0; - } - - is_initialized_ = false; - window_ = nullptr; - renderer_ = nullptr; - back_buffer_ = nullptr; -} - -} // namespace Rendering diff --git a/source/core/rendering/opengl/opengl_shader.hpp b/source/core/rendering/opengl/opengl_shader.hpp deleted file mode 100644 index bfac91e9..00000000 --- a/source/core/rendering/opengl/opengl_shader.hpp +++ /dev/null @@ -1,119 +0,0 @@ -#pragma once - -#include "core/rendering/shader_backend.hpp" - -#ifdef __APPLE__ -#include -#else -#include -#endif - -namespace Rendering { - -/** - * @brief Backend de shaders usando OpenGL 3.3 Core Profile - * - * Implementa el renderizado de shaders usando APIs modernas de OpenGL: - * - VAO (Vertex Array Objects) - * - VBO (Vertex Buffer Objects) - * - Shaders GLSL #version 330 core - */ -class OpenGLShader : public ShaderBackend { - public: - OpenGLShader() = default; - ~OpenGLShader() override; - - auto init(SDL_Window* window, - SDL_Texture* texture, - const std::string& vertex_source, - const std::string& fragment_source) -> bool override; - - void render() override; - void setTextureSize(float width, float height) override; - void setPostFXParams(const PostFXParams& p) override; - void cleanup() final; - [[nodiscard]] auto isHardwareAccelerated() const -> bool override { return is_initialized_; } - - private: - // Funciones auxiliares - auto initGLExtensions() -> bool; - auto compileShader(const std::string& source, GLenum shader_type) -> GLuint; - auto linkProgram(GLuint vertex_shader, GLuint fragment_shader) -> GLuint; - void createQuadGeometry(); - static auto getTextureID(SDL_Texture* texture) -> GLuint; - static void checkGLError(const char* operation); - - // Estado SDL - SDL_Window* window_ = nullptr; - SDL_Renderer* renderer_ = nullptr; - SDL_Texture* back_buffer_ = nullptr; - - // Estado OpenGL - GLuint program_id_ = 0; - GLuint vao_ = 0; // Vertex Array Object - GLuint vbo_ = 0; // Vertex Buffer Object - GLuint ebo_ = 0; // Element Buffer Object - - // Ubicaciones de uniforms - GLint texture_size_location_ = -1; - GLint vignette_location_ = -1; - GLint scanlines_location_ = -1; - GLint chroma_location_ = -1; - GLint output_height_location_ = -1; - GLint mask_location_ = -1; - GLint gamma_location_ = -1; - GLint curvature_location_ = -1; - GLint bleeding_location_ = -1; - - // Valores cacheados de PostFX - float postfx_vignette_ = 0.6F; - float postfx_scanlines_ = 0.7F; - float postfx_chroma_ = 0.15F; - float postfx_mask_ = 0.0F; - float postfx_gamma_ = 0.0F; - float postfx_curvature_ = 0.0F; - float postfx_bleeding_ = 0.0F; - - // Tamaños - int window_width_ = 0; - int window_height_ = 0; - float texture_width_ = 0.0F; - float texture_height_ = 0.0F; - - // Estado - bool is_initialized_ = false; - -#ifndef __APPLE__ - // NOLINTBEGIN - // Punteros a funciones OpenGL en Windows/Linux - PFNGLCREATESHADERPROC glCreateShader = nullptr; - PFNGLSHADERSOURCEPROC glShaderSource = nullptr; - PFNGLCOMPILESHADERPROC glCompileShader = nullptr; - PFNGLGETSHADERIVPROC glGetShaderiv = nullptr; - PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = nullptr; - PFNGLDELETESHADERPROC glDeleteShader = nullptr; - PFNGLATTACHSHADERPROC glAttachShader = nullptr; - PFNGLCREATEPROGRAMPROC glCreateProgram = nullptr; - PFNGLLINKPROGRAMPROC glLinkProgram = nullptr; - PFNGLVALIDATEPROGRAMPROC glValidateProgram = nullptr; - PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr; - PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = nullptr; - PFNGLUSEPROGRAMPROC glUseProgram = nullptr; - PFNGLDELETEPROGRAMPROC glDeleteProgram = nullptr; - PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr; - PFNGLUNIFORM1FPROC glUniform1f = nullptr; - PFNGLUNIFORM2FPROC glUniform2f = nullptr; - PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = nullptr; - PFNGLBINDVERTEXARRAYPROC glBindVertexArray = nullptr; - PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = nullptr; - PFNGLGENBUFFERSPROC glGenBuffers = nullptr; - PFNGLBINDBUFFERPROC glBindBuffer = nullptr; - PFNGLBUFFERDATAPROC glBufferData = nullptr; - PFNGLDELETEBUFFERSPROC glDeleteBuffers = nullptr; - PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = nullptr; - PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = nullptr; - // NOLINTEND -#endif -}; - -} // namespace Rendering diff --git a/source/core/rendering/screen.cpp b/source/core/rendering/screen.cpp index e1c882b3..50ec7b0e 100644 --- a/source/core/rendering/screen.cpp +++ b/source/core/rendering/screen.cpp @@ -9,10 +9,7 @@ #include // Para istreambuf_iterator, operator== #include // Para char_traits, string, operator+, operator== -#include "core/input/mouse.hpp" // Para updateCursorVisibility -#ifndef __APPLE__ -#include "core/rendering/opengl/opengl_shader.hpp" // Para OpenGLShader -#endif +#include "core/input/mouse.hpp" // Para updateCursorVisibility #include "core/rendering/sdl3gpu/sdl3gpu_shader.hpp" // Para SDL3GPUShader #include "core/rendering/surface.hpp" // Para Surface, readPalFile #include "core/rendering/text.hpp" // Para Text @@ -223,8 +220,6 @@ void Screen::togglePostFX() { // Recarga el shader del preset actual sin toggle void Screen::reloadPostFX() { if (Options::video.postfx) { - vertex_shader_source_.clear(); - fragment_shader_source_.clear(); initShaders(); } } @@ -446,38 +441,6 @@ auto loadData(const std::string& filepath) -> std::vector { return Resource::Helper::loadFile(filepath); } -// Carga el contenido de los archivos GLSL -void Screen::loadShaders() { - if (vertex_shader_source_.empty()) { - // Detectar si necesitamos OpenGL ES (Raspberry Pi) - // Intentar cargar versión ES primero si existe - auto data = loadData(Resource::List::get()->get("crtpi_vertex_es.glsl")); - - if (data.empty()) { - 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"; - } - - if (!data.empty()) { - vertex_shader_source_ = std::string(data.begin(), data.end()); - } - } - if (fragment_shader_source_.empty()) { - // Intentar cargar versión ES primero si existe - auto data = loadData(Resource::List::get()->get("crtpi_fragment_es.glsl")); - - if (data.empty()) { - data = loadData(Resource::List::get()->get("crtpi_fragment.glsl")); - } - - if (!data.empty()) { - fragment_shader_source_ = std::string(data.begin(), data.end()); - } - } -} - // Aplica los parámetros del preset actual al backend de shaders void Screen::applyCurrentPostFXPreset() { if (shader_backend_ && !Options::postfx_presets.empty()) { @@ -496,20 +459,10 @@ void Screen::initShaders() { SDL_Texture* tex = Options::video.border.enabled ? border_texture_ : game_texture_; -#ifdef __APPLE__ - // macOS: usar SDL3 GPU API (Metal) via SDL3GPUShader if (!shader_backend_) { shader_backend_ = std::make_unique(); } shader_backend_->init(window_, tex, "", ""); -#else - // Win/Linux: usar OpenGL + GLSL - loadShaders(); - if (!shader_backend_) { - shader_backend_ = std::make_unique(); - } - shader_backend_->init(window_, tex, vertex_shader_source_, fragment_shader_source_); -#endif applyCurrentPostFXPreset(); } @@ -576,38 +529,12 @@ auto Screen::initSDLVideo() -> bool { if (!SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal")) { std::cout << "WARNING: Failed to set Metal hint!\n"; } -#else - // Configurar hint de render driver - if (!SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl")) { - std::cout << "WARNING: Failed to set OpenGL hint!\n"; - } - -#ifdef _WIN32 - // Windows: Pedir explícitamente OpenGL 3.3 Core Profile - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - std::cout << "Solicitando OpenGL 3.3 Core Profile\n"; -#else - // Linux: Dejar que SDL elija (Desktop 3.3 en PC, ES 3.0 en RPi automáticamente) - std::cout << "Usando OpenGL por defecto del sistema\n"; -#endif #endif // Crear ventana const auto WINDOW_WIDTH = Options::video.border.enabled ? Options::game.width + (Options::video.border.width * 2) : Options::game.width; const auto WINDOW_HEIGHT = Options::video.border.enabled ? Options::game.height + (Options::video.border.height * 2) : Options::game.height; -#ifdef __APPLE__ - // SDL_WINDOW_METAL no es necesario: SDL3GPU autodetecta Metal via SDL_CreateGPUDevice. - // SDL_Renderer también usará Metal si está disponible (via hint o autoselección). SDL_WindowFlags window_flags = 0; -#elif defined(LINUX_BUILD) - // En Linux, SDL_WINDOW_OPENGL puede entrar en conflicto con el backend del renderer; - // el hint SDL_HINT_RENDER_DRIVER="opengl" es suficiente para seleccionar OpenGL. - SDL_WindowFlags window_flags = 0; -#else - SDL_WindowFlags window_flags = SDL_WINDOW_OPENGL; -#endif if (Options::video.fullscreen) { window_flags |= SDL_WINDOW_FULLSCREEN; } @@ -622,20 +549,11 @@ auto Screen::initSDLVideo() -> bool { // Crear renderer renderer_ = SDL_CreateRenderer(window_, nullptr); if (renderer_ == nullptr) { - // Fallback: reintentar sin forzar OpenGL (SDL elige el mejor disponible) - std::cerr << "WARNING: OpenGL renderer failed (" << SDL_GetError() << "), trying auto-select...\n"; - SDL_SetHint(SDL_HINT_RENDER_DRIVER, ""); - renderer_ = SDL_CreateRenderer(window_, nullptr); - if (renderer_ == nullptr) { - std::cerr << "FATAL: Failed to create renderer! SDL Error: " << SDL_GetError() << '\n'; - SDL_DestroyWindow(window_); - window_ = nullptr; - SDL_Quit(); - return false; - } - // Sin OpenGL garantizado, deshabilitar shaders - Options::video.postfx = false; - std::cout << "WARNING: PostFX disabled (OpenGL not available)\n"; + std::cerr << "FATAL: Failed to create renderer! SDL Error: " << SDL_GetError() << '\n'; + SDL_DestroyWindow(window_); + window_ = nullptr; + SDL_Quit(); + return false; } // Configurar renderer diff --git a/source/core/rendering/screen.hpp b/source/core/rendering/screen.hpp index f85d4be7..d3c26f29 100644 --- a/source/core/rendering/screen.hpp +++ b/source/core/rendering/screen.hpp @@ -116,7 +116,6 @@ class Screen { void renderOverlays(); // Renderiza todos los overlays 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 @@ -156,10 +155,8 @@ class Screen { DisplayMonitor display_monitor_; // Información de la pantalla // Shaders - std::string info_resolution_; // Texto con la información de la pantalla - std::string vertex_shader_source_; // Almacena el vertex shader - std::string fragment_shader_source_; // Almacena el fragment shader - std::vector pixel_buffer_; // Buffer intermedio para SDL3GPU path (surface → ARGB) + std::string info_resolution_; // Texto con la información de la pantalla + std::vector pixel_buffer_; // Buffer intermedio para SDL3GPU path (surface → ARGB) #ifdef _DEBUG bool show_debug_info_{true}; // Indica si ha de mostrar la información de debug