diff options
Diffstat (limited to 'gfx/gl/shader.cpp')
-rw-r--r-- | gfx/gl/shader.cpp | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/gfx/gl/shader.cpp b/gfx/gl/shader.cpp index 0bc127a..9a4c270 100644 --- a/gfx/gl/shader.cpp +++ b/gfx/gl/shader.cpp @@ -1,4 +1,5 @@ #include "shader.h" +#include "msgException.h" #include <algorithm> #include <array> #include <format> @@ -18,6 +19,39 @@ namespace { constexpr std::array<std::tuple<std::string_view, GLenum, LookUpFunction>, 1> LOOKUPS {{ {"GL_MAX_GEOMETRY_OUTPUT_VERTICES", GL_MAX_GEOMETRY_OUTPUT_VERTICES, getInt}, }}; + + struct ShaderCompileError : public MsgException<std::invalid_argument> { + explicit ShaderCompileError(GLuint shader, Shader::Source src) : + MsgException<std::invalid_argument> {"Error compiling shader"}, shader {shader}, source {src}, + msg {getShaderText(GL_INFO_LOG_LENGTH, glGetShaderInfoLog)} + { + } + + [[nodiscard]] std::string + getMsg() const noexcept override + { + return std::format("Error compiling shader: '{}'\nSource:\n{}", + getShaderText(GL_INFO_LOG_LENGTH, glGetShaderInfoLog), source); + } + + private: + std::string + getShaderText(GLenum param, auto getTextFunc) const + { + std::string text; + text.resize_and_overwrite(static_cast<size_t>(Shader::getShaderParam(shader, param)), + [this, getTextFunc](auto buf, auto len) { + GLsizei outLen {}; + getTextFunc(shader, static_cast<GLsizei>(len), &outLen, buf); + return outLen; + }); + return text; + } + + const GLuint shader; + const Shader::Source source; + const std::string msg; + }; } Shader::ShaderRef @@ -29,8 +63,8 @@ Shader::compile() const }; if (lookups) { std::basic_string<GLchar> textMod {text}; - for (const auto & match : ctre::range<R"(\bGL_[A-Z_]+\b)">(textMod)) { - if (const auto lookup = std::find_if(LOOKUPS.begin(), LOOKUPS.end(), + for (const auto & match : ctre::search_all<R"(\bGL_[A-Z_]+\b)">(textMod)) { + if (const auto * const lookup = std::find_if(LOOKUPS.begin(), LOOKUPS.end(), [&match](const auto & lookup) { return std::get<std::string_view>(lookup) == match; }); @@ -46,31 +80,22 @@ Shader::compile() const } glCompileShader(shader); - CheckShaderError(shader, GL_COMPILE_STATUS, false, "Error compiling shader!"); + checkShaderError(shader); return shader; } void -Shader::CheckShaderError(GLuint shader, GLuint flag, bool isProgram, std::string_view errorMessage) +Shader::checkShaderError(GLuint shader) const { - GLint success = 0; - - if (isProgram) { - glGetProgramiv(shader, flag, &success); + if (getShaderParam(shader, GL_COMPILE_STATUS) == GL_FALSE) { + throw ShaderCompileError {shader, text}; } - else { - glGetShaderiv(shader, flag, &success); - } - - if (success == GL_FALSE) { - std::array<GLchar, 1024> error {}; - if (isProgram) { - glGetProgramInfoLog(shader, error.size(), nullptr, error.data()); - } - else { - glGetShaderInfoLog(shader, error.size(), nullptr, error.data()); - } +} - throw std::runtime_error {std::format("{}: '{}'", errorMessage, error.data())}; - } +GLint +Shader::getShaderParam(GLuint shader, GLenum pname) +{ + GLint pvalue {}; + glGetShaderiv(shader, pname, &pvalue); + return pvalue; } |