From 354d7df4d2779ed7391701d1ef4344e959b64582 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Wed, 27 Dec 2017 19:21:12 +0000 Subject: [Broken] Texture is black. --- yage/render/shader.cpp | 132 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 yage/render/shader.cpp (limited to 'yage/render/shader.cpp') diff --git a/yage/render/shader.cpp b/yage/render/shader.cpp new file mode 100644 index 00000000..be2e77e2 --- /dev/null +++ b/yage/render/shader.cpp @@ -0,0 +1,132 @@ +/** --------------------------------------------------------------------------- + * @file: shader.cpp + * + * Copyright (c) 2017 Yann Herklotz Grave + * MIT License, see LICENSE file for more details. + * ---------------------------------------------------------------------------- + */ + +#include "shader.h" + +#include +#include +#include +#include +#include + +using std::runtime_error; + +namespace yage +{ + +Shader::Shader(const std::string &vertex_path, const std::string &fragment_path) +{ + std::string vertex_source, fragment_source; + std::ifstream vertex_file, fragment_file; + + vertex_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + fragment_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + + try { + vertex_file.open(vertex_path); + fragment_file.open(fragment_path); + + std::ostringstream vertex_stream, fragment_stream; + vertex_stream << vertex_file.rdbuf(); + fragment_stream << fragment_file.rdbuf(); + + vertex_file.close(); + fragment_file.close(); + + vertex_source = vertex_stream.str(); + fragment_source = fragment_stream.str(); + } catch (std::ifstream::failure e) { + throw runtime_error("File could not be opened: " + + std::string(e.what())); + } + + const char *vertex_source_c = vertex_source.c_str(); + const char *fragment_source_c = fragment_source.c_str(); + + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, &vertex_source_c, NULL); + glCompileShader(vertex_shader); + errorCheck(vertex_shader, "vertex"); + + GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragment_source_c, NULL); + glCompileShader(fragment_shader); + errorCheck(fragment_shader, "fragment"); + + program_id_ = glCreateProgram(); + glAttachShader(program_id_, vertex_shader); + glAttachShader(program_id_, fragment_shader); + glLinkProgram(program_id_); + errorCheck(program_id_, "program"); + + glDetachShader(program_id_, vertex_shader); + glDetachShader(program_id_, fragment_shader); + + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); +} + +Shader::~Shader() +{ + /// cleans up all the shaders and the program + if (program_id_ != 0) { + glDeleteProgram(program_id_); + } +} + +void Shader::use() const +{ + glUseProgram(program_id_); +} + +void Shader::setUniform(const std::string &name, int value) const +{ + glUniform1i(getUniformLocation(name), static_cast(value)); +} + +void Shader::setUniform(const std::string &name, float value) const +{ + glUniform1f(getUniformLocation(name), static_cast(value)); +} + +void Shader::setUniform(const std::string &name, const glm::mat4 &matrix) const +{ + glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, &(matrix[0][0])); +} + +GLint Shader::getUniformLocation(const std::string &uniform_name) const +{ + GLint location = glGetUniformLocation(program_id_, uniform_name.c_str()); + if (location == GL_INVALID_INDEX) { + throw std::runtime_error("'" + uniform_name + "' not found"); + } + return location; +} + +void Shader::errorCheck(GLuint shader, const std::string &shader_type) const +{ + int success; + char info_log[1024]; + if (shader_type != std::string("program")) { + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(shader, 1024, NULL, info_log); + throw runtime_error(shader_type + + " failed to compile: " + std::string(info_log)); + } + } else { + glGetProgramiv(shader, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(shader, 1024, NULL, info_log); + throw runtime_error(shader_type + + " failed to link: " + std::string(info_log)); + } + } +} + +} // namespace yage -- cgit