From e7359a146784fc5b57a22deaddf5b96924010d53 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 16 Mar 2025 09:39:24 +0100 Subject: [PATCH] Acabat de repasar jail_shader.cpp --- source/jail_shader.cpp | 174 +++++++++++++++++++++-------------------- source/jail_shader.h | 6 +- source/screen.cpp | 2 +- 3 files changed, 94 insertions(+), 88 deletions(-) diff --git a/source/jail_shader.cpp b/source/jail_shader.cpp index 2317996..c028fb1 100644 --- a/source/jail_shader.cpp +++ b/source/jail_shader.cpp @@ -1,8 +1,8 @@ #include "jail_shader.h" #include // para SDL_Point -#include // para NULL, free, malloc, exit -#include // para strncmp -#include // para basic_ostream, char_traits, operator<< +#include // para NULL, free, malloc, exit +#include // para strncmp +#include // para std::cout, std::endl #ifdef __APPLE__ #include "CoreFoundation/CoreFoundation.h" @@ -10,10 +10,11 @@ #if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3 #include -#else // NOT ESSENTIAL_GL_PRACTICES_SUPPORT_GL3 +#else // NO ESSENTIAL_GL_PRACTICES_SUPPORT_GL3 #include #endif // ESSENTIAL_GL_PRACTICES_SUPPORT_GL3 -#else // NOT __APPLE__ + +#else // SI NO ES __APPLE__ #include #endif // __APPLE__ @@ -25,12 +26,10 @@ namespace shader SDL_Texture *backBuffer = nullptr; SDL_Point win_size = {320 * 4, 256 * 4}; SDL_Point tex_size = {320, 256}; - bool usingOpenGL; + bool usingOpenGL = false; #ifndef __APPLE__ - - // I'm avoiding the use of GLEW or some extensions handler, but that - // doesn't mean you should... + // Declaración de funciones de extensión de OpenGL (evitando GLEW) PFNGLCREATESHADERPROC glCreateShader; PFNGLSHADERSOURCEPROC glShaderSource; PFNGLCOMPILESHADERPROC glCompileShader; @@ -66,119 +65,125 @@ namespace shader glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog && glUseProgram; } - #endif - GLuint compileShader(const char *source, GLuint shaderType) + // Función para compilar un shader a partir de un std::string + GLuint compileShader(const std::string &source, GLuint shaderType) { - // Create ID for shader - GLuint result = glCreateShader(shaderType); - - // Add define depending on shader type - const char *sources[2] = {shaderType == GL_VERTEX_SHADER ? "#define VERTEX\n" : "#define FRAGMENT\n", source}; - - // Define shader text - glShaderSource(result, 2, sources, nullptr); - - // Compile shader - glCompileShader(result); - - // Check vertex shader for errors - GLint shaderCompiled = GL_FALSE; - glGetShaderiv(result, GL_COMPILE_STATUS, &shaderCompiled); - if (shaderCompiled != GL_TRUE) + if (source.empty()) { - std::cout << "Error en la compilación: " << result << "!" << std::endl; - GLint logLength; - glGetShaderiv(result, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) - { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(result, logLength, &logLength, log); - std::cout << "Shader compile log:" << log << std::endl; - free(log); - } - glDeleteShader(result); - result = 0; + throw std::runtime_error("ERROR FATAL: El código fuente del shader está vacío."); } - return result; + + // Crear identificador del shader + GLuint resultado = glCreateShader(shaderType); + + // Agregar una directiva según el tipo de shader + std::string directiva = (shaderType == GL_VERTEX_SHADER) + ? "#define VERTEX\n" + : "#define FRAGMENT\n"; + + const char *sources[2] = {directiva.c_str(), source.c_str()}; + + // Especificar el código fuente del shader + glShaderSource(resultado, 2, sources, nullptr); + + // Compilar el shader + glCompileShader(resultado); + + // Verificar si la compilación fue exitosa + GLint compiladoCorrectamente = GL_FALSE; + glGetShaderiv(resultado, GL_COMPILE_STATUS, &compiladoCorrectamente); + if (compiladoCorrectamente != GL_TRUE) + { + std::cout << "Error en la compilación del shader (" << resultado << ")!" << std::endl; + GLint longitudLog; + glGetShaderiv(resultado, GL_INFO_LOG_LENGTH, &longitudLog); + if (longitudLog > 0) + { + std::vector log(longitudLog); + glGetShaderInfoLog(resultado, longitudLog, &longitudLog, log.data()); + std::cout << "Registro de compilación del shader: " << log.data() << std::endl; + } + glDeleteShader(resultado); + resultado = 0; + } + return resultado; } - GLuint compileProgram(const char *vertexShaderSource, const char *fragmentShaderSource) + // Función para compilar un programa de shaders (vertex y fragment) a partir de std::string + GLuint compileProgram(const std::string &vertexShaderSource, const std::string &fragmentShaderSource) { - GLuint programId = 0; - GLuint vtxShaderId, fragShaderId; + GLuint idPrograma = glCreateProgram(); - programId = glCreateProgram(); + // Si el fragment shader está vacío, reutilizamos el código del vertex shader + GLuint idShaderVertice = compileShader(vertexShaderSource, GL_VERTEX_SHADER); + GLuint idShaderFragmento = compileShader(fragmentShaderSource.empty() ? vertexShaderSource : fragmentShaderSource, GL_FRAGMENT_SHADER); - vtxShaderId = compileShader(vertexShaderSource, GL_VERTEX_SHADER); - fragShaderId = compileShader(fragmentShaderSource ? fragmentShaderSource : vertexShaderSource, GL_FRAGMENT_SHADER); - - if (vtxShaderId && fragShaderId) + if (idShaderVertice && idShaderFragmento) { - // Associate shader with program - glAttachShader(programId, vtxShaderId); - glAttachShader(programId, fragShaderId); - glLinkProgram(programId); - glValidateProgram(programId); + // Asociar los shaders al programa + glAttachShader(idPrograma, idShaderVertice); + glAttachShader(idPrograma, idShaderFragmento); + glLinkProgram(idPrograma); + glValidateProgram(idPrograma); - // Check the status of the compile/link - GLint logLen; - glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen); - if (logLen > 0) + // Verificar el estado del enlace + GLint longitudLog; + glGetProgramiv(idPrograma, GL_INFO_LOG_LENGTH, &longitudLog); + if (longitudLog > 0) { - char *log = (char *)malloc(logLen * sizeof(char)); - - // Show any errors as appropriate - glGetProgramInfoLog(programId, logLen, &logLen, log); - std::cout << "Prog Info Log: " << std::endl - << log << std::endl; - free(log); + std::vector log(longitudLog); + glGetProgramInfoLog(idPrograma, longitudLog, &longitudLog, log.data()); + std::cout << "Registro de información del programa:" << std::endl + << log.data() << std::endl; } } - if (vtxShaderId) + if (idShaderVertice) { - glDeleteShader(vtxShaderId); + glDeleteShader(idShaderVertice); } - if (fragShaderId) + if (idShaderFragmento) { - glDeleteShader(fragShaderId); + glDeleteShader(idShaderFragmento); } - return programId; + return idPrograma; } - const bool init(SDL_Window *win, SDL_Texture *backBuffer, const char *vertexShader, const char *fragmentShader) + bool init(SDL_Window *ventana, SDL_Texture *texturaBackBuffer, const std::string &vertexShader, const std::string &fragmentShader) { - shader::win = win; - shader::renderer = SDL_GetRenderer(win); - shader::backBuffer = backBuffer; - SDL_GetWindowSize(win, &win_size.x, &win_size.y); - int access; - SDL_QueryTexture(backBuffer, nullptr, &access, &tex_size.x, &tex_size.y); - if (access != SDL_TEXTUREACCESS_TARGET) + shader::win = ventana; + shader::renderer = SDL_GetRenderer(ventana); + shader::backBuffer = texturaBackBuffer; + SDL_GetWindowSize(ventana, &win_size.x, &win_size.y); + + int acceso; + SDL_QueryTexture(texturaBackBuffer, nullptr, &acceso, &tex_size.x, &tex_size.y); + if (acceso != SDL_TEXTUREACCESS_TARGET) { - throw std::runtime_error("ERROR FATAL: La textura debe tener SDL_TEXTUREACCESS_TARGET definido."); + throw std::runtime_error("ERROR FATAL: La textura debe tener definido SDL_TEXTUREACCESS_TARGET."); } - SDL_RendererInfo rendererInfo; - SDL_GetRendererInfo(renderer, &rendererInfo); + SDL_RendererInfo infoRenderer; + SDL_GetRendererInfo(renderer, &infoRenderer); - if (!strncmp(rendererInfo.name, "opengl", 6)) + // Verificar que el renderer sea OpenGL + if (!strncmp(infoRenderer.name, "opengl", 6)) { #ifndef __APPLE__ if (!initGLExtensions()) { - std::cout << "WARNING: No s'han pogut inicialitzar les extensions d'OpenGL!" << std::endl; + std::cout << "ADVERTENCIA: No se han podido inicializar las extensiones de OpenGL." << std::endl; usingOpenGL = false; return false; } #endif - // Compilar el shader y dejarlo listo para usar. + // Compilar el programa de shaders utilizando std::string programId = compileProgram(vertexShader, fragmentShader); } else { - std::cout << "WARNING: El driver del renderer no es OpenGL." << std::endl; + std::cout << "ADVERTENCIA: El driver del renderer no es OpenGL." << std::endl; usingOpenGL = false; return false; } @@ -249,6 +254,7 @@ namespace shader // Configurar la proyección ortográfica usando el espacio lógico glMatrixMode(GL_PROJECTION); glLoadIdentity(); + // Queremos que el origen esté en la esquina superior izquierda del espacio lógico. glOrtho(0, static_cast(logicalW), static_cast(logicalH), 0, -1, 1); glMatrixMode(GL_MODELVIEW); diff --git a/source/jail_shader.h b/source/jail_shader.h index ba99f0c..42a6e80 100644 --- a/source/jail_shader.h +++ b/source/jail_shader.h @@ -2,6 +2,7 @@ #include // para SDL_Texture #include // para SDL_Window +#include // TIPS: // ======================================================================= @@ -38,8 +39,7 @@ namespace shader { - const bool init(SDL_Window *win, SDL_Texture *backBuffer, - const char *vertexShader, const char *fragmentShader = nullptr); - + //const bool init(SDL_Window *ventana, SDL_Texture *texturaBackBuffer, const char *vertexShader, const char *fragmentShader = nullptr); + bool init(SDL_Window *ventana, SDL_Texture *texturaBackBuffer, const std::string &vertexShader, const std::string &fragmentShader = ""); void render(); } \ No newline at end of file diff --git a/source/screen.cpp b/source/screen.cpp index 8ec7b2e..9a2bab8 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -327,7 +327,7 @@ void Screen::initShaders() { loadShaders(); } - shader::init(window_, game_canvas_, shaderSource.c_str()); + shader::init(window_, game_canvas_, shaderSource); } // Calcula el tamaño de la ventana