diff options
Diffstat (limited to 'src/Shader.cpp')
-rw-r--r-- | src/Shader.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/Shader.cpp b/src/Shader.cpp index d637c3b..9447131 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -111,3 +111,88 @@ void Shader::Reload() { new(this) Shader(vertexPath, fragmentPath); LOG(INFO) << "Shader is realoded!"; } + +GLuint NewShader::GetUniformLocation(const std::string &name) { + auto it = uniforms.find(name); + if (it == uniforms.end()) { + LOG(ERROR) << "Accessed not existing uniform " << name; + return 0; + } + return it->second; +} + +NewShader::NewShader(const std::string &vertSource, const std::string &fragSource, const std::vector<std::string> &uniformsNames) +{ + bool vertFailed = false, fragFailed = false, linkFailed = false, uniformsFailed = false; + const GLchar *vertSourcePtr = vertSource.c_str(); + const GLchar *fragSourcePtr = fragSource.c_str(); + + GLuint vertex, fragment; + GLint success; + GLchar infoLog[512]; + + vertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex, 1, &vertSourcePtr, NULL); + glCompileShader(vertex); + + glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(vertex, 512, NULL, infoLog); + LOG(ERROR) << "Vertex shader compilation failed: " << std::endl << infoLog; + vertFailed = true; + }; + + fragment = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment, 1, &fragSourcePtr, NULL); + glCompileShader(fragment); + + glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(fragment, 512, NULL, infoLog); + LOG(ERROR) << "Fragment shader compilation failed: " << std::endl << infoLog; + fragFailed = true; + }; + + if (vertFailed || fragFailed) + throw std::runtime_error("Shaders not compiled"); + + program = glCreateProgram(); + glAttachShader(program, vertex); + glAttachShader(program, fragment); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(program, 512, NULL, infoLog); + LOG(ERROR) << "Shader program not linked: " << std::endl << infoLog; + linkFailed = true; + } + + glDeleteShader(vertex); + glDeleteShader(fragment); + + if (linkFailed) + throw std::runtime_error("Shader not linked"); + + + for (auto &it : uniformsNames) { + GLuint location = glGetUniformLocation(program, it.c_str()); + if (location == -1) { + glDeleteProgram(program); + LOG(ERROR) << "Uniform name \"" << it << "\" not found in shader"; + throw std::runtime_error("Invalid uniform"); + } + + uniforms[it] = location; + } +} + +NewShader::~NewShader() +{ + if (program) + glDeleteProgram(program); +} + +void NewShader::Activate() +{ + glUseProgram(program); +} |