diff options
Diffstat (limited to 'src/brussel.engine/Shader.cpp')
-rw-r--r-- | src/brussel.engine/Shader.cpp | 140 |
1 files changed, 55 insertions, 85 deletions
diff --git a/src/brussel.engine/Shader.cpp b/src/brussel.engine/Shader.cpp index 9bf2e0e..d795188 100644 --- a/src/brussel.engine/Shader.cpp +++ b/src/brussel.engine/Shader.cpp @@ -1,4 +1,5 @@ #include "Shader.hpp" +#include "Shader_p.hpp" #include "AppConfig.hpp" @@ -19,20 +20,23 @@ using namespace std::literals; void ShaderMathVariable::ShowInfo() const { + auto semantic = Metadata::EnumToString(this->semantic); + auto scalarType = Tags::GLTypeToString(this->scalarType); ImGui::BulletText("Location: %d\nName: %s\nSemantic: %.*s\nType: %.*s %dx%d", location, name.c_str(), - PRINTF_STRING_VIEW(Metadata::EnumToString(semantic)), - PRINTF_STRING_VIEW(Tags::GLTypeToString(scalarType)), + PRINTF_STRING_VIEW(semantic), + PRINTF_STRING_VIEW(scalarType), width, height); } void ShaderSamplerVariable::ShowInfo() const { + auto semantic = Metadata::EnumToString(this->semantic); ImGui::BulletText("Location: %d\nName: %s\nSemantic: %.*s\nType: Sampler", location, name.c_str(), - PRINTF_STRING_VIEW(Metadata::EnumToString(semantic))); + PRINTF_STRING_VIEW(semantic)); } namespace ProjectBrussel_UNITY_ID { @@ -66,12 +70,12 @@ void InitAutoFills(Shader& shader) { } } // namespace ProjectBrussel_UNITY_ID -GLuint ShaderInfo::FindInputLocation(Tags::VertexElementSemantic semantic) { +GLuint ShaderInfo::FindInputLocation(Tags::VertexElementSemantic semantic) const { using namespace ProjectBrussel_UNITY_ID; return FindLocation(inputs, semantic); } -GLuint ShaderInfo::FindOutputLocation(Tags::VertexElementSemantic semantic) { +GLuint ShaderInfo::FindOutputLocation(Tags::VertexElementSemantic semantic) const { using namespace ProjectBrussel_UNITY_ID; return FindLocation(outputs, semantic); } @@ -85,31 +89,35 @@ Shader::~Shader() { namespace ProjectBrussel_UNITY_ID { // Grabs section [begin, end) -Shader::ErrorCode CreateShader(GLuint& out, const char* src, int beginIdx, int endIdx, GLenum type) { - out = glCreateShader(type); +Shader::ErrorCode CreateShader(OGLShader& out, const char* src, int beginIdx, int endIdx, GLenum type) { + GLuint shader = glCreateShader(type); const GLchar* begin = &src[beginIdx]; const GLint len = endIdx - beginIdx; - glShaderSource(out, 1, &begin, &len); + glShaderSource(shader, 1, &begin, &len); - glCompileShader(out); + glCompileShader(shader); GLint compileStatus; - glGetShaderiv(out, GL_COMPILE_STATUS, &compileStatus); + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); if (compileStatus == GL_FALSE) { GLint len; - glGetShaderiv(out, GL_INFO_LOG_LENGTH, &len); + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); std::string log(len, '\0'); - glGetShaderInfoLog(out, len, nullptr, log.data()); + glGetShaderInfoLog(shader, len, nullptr, log.data()); - return Shader ::EC_CompilationFailed; + std::fprintf(stderr, "Error compiling shader: %s", log.c_str()); + + glDeleteShader(shader); + return Shader::EC_CompilationFailed; } + out = shader; return Shader::EC_Success; } -Shader::ErrorCode CreateShader(GLuint& out, std::string_view str, GLenum type) { - return CreateShader(out, str.data(), 0, str.size(), type); +Shader::ErrorCode CreateShader(OGLShader& out, std::string_view str, GLenum type) { + return CreateShader(out, str.data(), 0, static_cast<int>(str.size()), type); } Shader::ErrorCode LinkShaderProgram(GLuint program) { @@ -144,58 +152,41 @@ Shader::ErrorCode Shader::InitFromSources(const ShaderSources& sources) { return EC_AlreadyInitialized; } - GLuint program = glCreateProgram(); - ScopeGuard sg = [&]() { glDeleteProgram(program); }; + OGLShaderProgram program(glCreateProgram()); - GLuint vertex = 0; - DEFER { - glDeleteShader(vertex); - }; + OGLShader vertex; if (!sources.vertex.empty()) { CATCH_ERROR(CreateShader(vertex, sources.vertex, GL_VERTEX_SHADER)); - glAttachShader(program, vertex); + glAttachShader(program.get(), vertex.get()); } - GLuint geometry = 0; - DEFER { - glDeleteShader(geometry); - }; + OGLShader geometry; if (!sources.geometry.empty()) { CATCH_ERROR(CreateShader(geometry, sources.geometry, GL_GEOMETRY_SHADER)); - glAttachShader(program, geometry); + glAttachShader(program.get(), geometry.get()); } - GLuint tessControl = 0; - DEFER { - glDeleteShader(tessControl); - }; + OGLShader tessControl; if (!sources.tessControl.empty()) { CATCH_ERROR(CreateShader(tessControl, sources.tessControl, GL_TESS_CONTROL_SHADER)); - glAttachShader(program, tessControl); + glAttachShader(program.get(), tessControl.get()); } - GLuint tessEval = 0; - DEFER { - glDeleteShader(tessEval); - }; + OGLShader tessEval; if (!sources.tessEval.empty()) { CATCH_ERROR(CreateShader(tessEval, sources.tessEval, GL_TESS_EVALUATION_SHADER)); - glAttachShader(program, tessEval); + glAttachShader(program.get(), tessEval.get()); } - GLuint fragment = 0; - DEFER { - glDeleteShader(fragment); - }; + OGLShader fragment; if (!sources.fragment.empty()) { CATCH_ERROR(CreateShader(fragment, sources.fragment, GL_FRAGMENT_SHADER)); - glAttachShader(program, fragment); + glAttachShader(program.get(), fragment.get()); } - CATCH_ERROR(LinkShaderProgram(program)); + CATCH_ERROR(LinkShaderProgram(program.get())); - sg.Dismiss(); - mProgram = program; + mProgram = program.release(); InitAutoFills(*this); @@ -205,30 +196,11 @@ Shader::ErrorCode Shader::InitFromSources(const ShaderSources& sources) { Shader::ErrorCode Shader::InitFromSource(std::string_view source) { using namespace ProjectBrussel_UNITY_ID; - GLuint vertex = 0; - DEFER { - glDeleteShader(vertex); - }; - - GLuint geometry = 0; - DEFER { - glDeleteShader(geometry); - }; - - GLuint tessControl = 0; - DEFER { - glDeleteShader(tessControl); - }; - - GLuint tessEval = 0; - DEFER { - glDeleteShader(tessEval); - }; - - GLuint fragment = 0; - DEFER { - glDeleteShader(fragment); - }; + OGLShader vertex; + OGLShader geometry; + OGLShader tessControl; + OGLShader tessEval; + OGLShader fragment; int prevBegin = -1; // Excluding #type marker int prevEnd = -1; // [begin, end) @@ -240,15 +212,15 @@ Shader::ErrorCode Shader::InitFromSource(std::string_view source) { return EC_Success; } - if (prevShaderVariant == "vertex" && !vertex) { + if (prevShaderVariant == "vertex" && vertex.get() == 0) { CATCH_ERROR(CreateShader(vertex, source.data(), prevBegin, prevEnd, GL_VERTEX_SHADER)); - } else if (prevShaderVariant == "geometry" && !geometry) { + } else if (prevShaderVariant == "geometry" && geometry.get() == 0) { CATCH_ERROR(CreateShader(geometry, source.data(), prevBegin, prevEnd, GL_GEOMETRY_SHADER)); - } else if (prevShaderVariant == "tessellation_control" && !tessControl) { + } else if (prevShaderVariant == "tessellation_control" && tessControl.get() == 0) { CATCH_ERROR(CreateShader(tessControl, source.data(), prevBegin, prevEnd, GL_TESS_CONTROL_SHADER)); - } else if (prevShaderVariant == "tessellation_evaluation" && !tessEval) { + } else if (prevShaderVariant == "tessellation_evaluation" && tessEval.get() == 0) { CATCH_ERROR(CreateShader(tessEval, source.data(), prevBegin, prevEnd, GL_TESS_EVALUATION_SHADER)); - } else if (prevShaderVariant == "fragment" && !fragment) { + } else if (prevShaderVariant == "fragment" && fragment.get() == 0) { CATCH_ERROR(CreateShader(fragment, source.data(), prevBegin, prevEnd, GL_FRAGMENT_SHADER)); } else { return EC_InvalidShaderVariant; @@ -312,19 +284,17 @@ Shader::ErrorCode Shader::InitFromSource(std::string_view source) { prevEnd = static_cast<int>(source.size()); CATCH_ERROR(CommitSection()); - GLuint program = glCreateProgram(); - ScopeGuard sg = [&]() { glDeleteProgram(program); }; + OGLShaderProgram program(glCreateProgram()); - if (vertex) glAttachShader(program, vertex); - if (geometry) glAttachShader(program, geometry); - if (tessControl) glAttachShader(program, tessControl); - if (tessEval) glAttachShader(program, tessEval); - if (fragment) glAttachShader(program, fragment); + if (vertex) glAttachShader(program.get(), vertex.get()); + if (geometry) glAttachShader(program.get(), geometry.get()); + if (tessControl) glAttachShader(program.get(), tessControl.get()); + if (tessEval) glAttachShader(program.get(), tessEval.get()); + if (fragment) glAttachShader(program.get(), fragment.get()); - CATCH_ERROR(LinkShaderProgram(program)); + CATCH_ERROR(LinkShaderProgram(program.get())); - sg.Dismiss(); - mProgram = program; + mProgram = program.release(); InitAutoFills(*this); @@ -610,7 +580,7 @@ void IresShader::Write(IresWritingContext& ctx, rapidjson::Value& value, rapidjs using namespace ProjectBrussel_UNITY_ID; IresObject::Write(ctx, value, root); - json_dto::json_output_t out( value, root.GetAllocator() ); + json_dto::json_output_t out(value, root.GetAllocator()); out << mInstance->mInfo; } |