From 14a0481645dbd886bb41677345d52bd63ddc17ba Mon Sep 17 00:00:00 2001 From: Jerboa-app Date: Sun, 24 Nov 2024 13:39:42 +0000 Subject: [PATCH] Add line numbers to shader error output --- include/jGL/OpenGL/gl.h | 24 ++++++++--- include/jGL/shader.h | 25 +++++++++++ src/jGL/OpenGL/Shader/glShader.cpp | 64 +++++++++++++++++++++++++++- src/jGL/OpenGL/gl.cpp | 67 ------------------------------ 4 files changed, 107 insertions(+), 73 deletions(-) diff --git a/include/jGL/OpenGL/gl.h b/include/jGL/OpenGL/gl.h index f413e67c..e01fa6b9 100644 --- a/include/jGL/OpenGL/gl.h +++ b/include/jGL/OpenGL/gl.h @@ -40,14 +40,28 @@ namespace jGL::GL { - class GLRuntimeException; + class GLRuntimeException: public std::exception + { + + public: + + GLRuntimeException(std::string msg) + : msg(msg) + {} + + private: + + virtual const char * what() const throw() + { + return msg.c_str(); + } + + std::string msg; + + }; // print buffer status errors GLuint glBufferStatus(const std::string msg = ""); // print gl error codes GLuint glError(const std::string msg = ""); - - // compile a gl shader given a program and source code as const char * - void compileShader(GLuint & shaderProgram, const char * vert, const char * frag); - } #endif \ No newline at end of file diff --git a/include/jGL/shader.h b/include/jGL/shader.h index 0bfab6d3..c2a0a11a 100644 --- a/include/jGL/shader.h +++ b/include/jGL/shader.h @@ -125,6 +125,9 @@ namespace jGL virtual void use() = 0; + std::string displayVertexSource() const { return formatWithLineNumbers(vertex); } + std::string displayFragmentSource() const { return formatWithLineNumbers(fragment); } + protected: std::string vertex; @@ -137,6 +140,28 @@ namespace jGL virtual void compile() = 0; bool parseUniforms(); + + std::string formatWithLineNumbers(std::string shader) const + { + if (shader.length() == 0) { return shader; } + std::string source = "1: "; + uint32_t line = 1; + auto iter = shader.begin(); + while (iter != shader.end()) + { + if (*iter == '\n' && iter+1 != shader.end()) + { + line += 1; + source += "\n" + std::to_string(line)+": "; + } + else + { + source += *iter; + } + iter++; + } + return source; + } template void detectUniformsAndCreate(std::string code) diff --git a/src/jGL/OpenGL/Shader/glShader.cpp b/src/jGL/OpenGL/Shader/glShader.cpp index 7c2daade..36736848 100644 --- a/src/jGL/OpenGL/Shader/glShader.cpp +++ b/src/jGL/OpenGL/Shader/glShader.cpp @@ -30,7 +30,69 @@ namespace jGL::GL parseUniforms(); - compileShader(program,vertex.c_str(),fragment.c_str()); + GLuint vertexShader; + vertexShader = glCreateShader(GL_VERTEX_SHADER); + auto v = vertex.c_str(); + glShaderSource(vertexShader,1,&v,NULL); + glCompileShader(vertexShader); + + // check it worked! + int success; + const unsigned logSize = 512*4; + char infoLog[logSize]; + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); + + if(!success) + { + glGetShaderInfoLog(vertexShader, logSize, NULL, infoLog); + throw + ( + GLRuntimeException + ( + std::string("GLSL (VERTEX) ERROR: \n") + infoLog + "\n"+displayVertexSource()+"\n" + ) + ); + } + + GLuint fragmentShader; + fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + auto f = fragment.c_str(); + glShaderSource(fragmentShader,1,&f,NULL); + glCompileShader(fragmentShader); + + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); + + if(!success) + { + glGetShaderInfoLog(fragmentShader, logSize, NULL, infoLog); + throw + ( + GLRuntimeException + ( + std::string("GLSL (FRAGMENT) ERROR: \n") + infoLog + "\n"+displayFragmentSource()+"\n" + ) + ); + } + + glAttachShader(program,vertexShader); + glAttachShader(program,fragmentShader); + glLinkProgram(program); + + // check it linked + glGetProgramiv(program, GL_LINK_STATUS, &success); + if(!success) + { + glGetProgramInfoLog(program, logSize, NULL, infoLog); + throw + ( + GLRuntimeException + ( + std::string("GLSL (LINK) ERROR: \n") + infoLog + "\n"+displayVertexSource()+"\n"+displayFragmentSource()+"\n" + ) + ); + } + glGetProgramInfoLog(program, logSize, NULL, infoLog); + compiled = true; for (auto uniform = uniforms.cbegin(); uniform != uniforms.cend(); uniform++) diff --git a/src/jGL/OpenGL/gl.cpp b/src/jGL/OpenGL/gl.cpp index 63b10d63..d8962536 100644 --- a/src/jGL/OpenGL/gl.cpp +++ b/src/jGL/OpenGL/gl.cpp @@ -3,27 +3,6 @@ namespace jGL::GL { - - class GLRuntimeException: public std::exception - { - - public: - - GLRuntimeException(std::string msg) - : msg(msg) - {} - - private: - - virtual const char * what() const throw() - { - return msg.c_str(); - } - - std::string msg; - - }; - // print buffer status errors GLuint glBufferStatus(const std::string msg) { @@ -79,50 +58,4 @@ namespace jGL::GL return e; } - // compile a gl shader given a program and source code as const char * - void compileShader(GLuint & shaderProgram, const char * vert, const char * frag) - { - GLuint vertexShader; - vertexShader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShader,1,&vert,NULL); - glCompileShader(vertexShader); - - // check it worked! - int success; - const unsigned logSize = 512*4; - char infoLog[logSize]; - glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); - - if(!success) - { - glGetShaderInfoLog(vertexShader, logSize, NULL, infoLog); - throw( GLRuntimeException( std::string("GLSL (VERTEX) ERROR: \n") + infoLog + "\n"+vert+"\n") ); - } - - GLuint fragmentShader; - fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShader,1,&frag,NULL); - glCompileShader(fragmentShader); - - glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); - - if(!success) - { - glGetShaderInfoLog(fragmentShader, logSize, NULL, infoLog); - throw( GLRuntimeException( std::string("GLSL (FRAGMENT) ERROR: \n") + infoLog +"\n"+frag+"\n") ); - } - - glAttachShader(shaderProgram,vertexShader); - glAttachShader(shaderProgram,fragmentShader); - glLinkProgram(shaderProgram); - - // check it linked - glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); - if(!success) - { - glGetProgramInfoLog(shaderProgram, logSize, NULL, infoLog); - throw( GLRuntimeException( std::string("GLSL (LINK) ERROR: \n") + infoLog + "\n"+vert+"\n"+frag+"\n") ); - } - glGetProgramInfoLog(shaderProgram, logSize, NULL, infoLog); - } } \ No newline at end of file