#include "Shader.hpp" Shader::Shader(const GLchar *vertexPath, const GLchar *fragmentPath) { vertex = vertexPath; fragment = fragmentPath; // 1. Получаем исходный код шейдера из filePath std::string vertexCode; std::string fragmentCode; std::ifstream vShaderFile; std::ifstream fShaderFile; // Удостоверимся, что ifstream объекты могут выкидывать исключения vShaderFile.exceptions(std::ifstream::failbit); fShaderFile.exceptions(std::ifstream::failbit); try { // Открываем файлы vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath); std::stringstream vShaderStream, fShaderStream; // Считываем данные в потоки vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); // Закрываем файлы vShaderFile.close(); fShaderFile.close(); // Преобразовываем потоки в массив GLchar vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch (std::ifstream::failure e) { LOG(ERROR) << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ"; } const GLchar *vShaderCode = vertexCode.c_str(); const GLchar *fShaderCode = fragmentCode.c_str(); // 2. Сборка шейдеров GLuint vertex, fragment; GLint success; GLchar infoLog[512]; // Вершинный шейдер vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vShaderCode, NULL); glCompileShader(vertex); // Если есть ошибки - вывести их glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertex, 512, NULL, infoLog); LOG(ERROR) << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog; }; // Вершинный шейдер fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fShaderCode, NULL); glCompileShader(fragment); // Если есть ошибки - вывести их glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragment, 512, NULL, infoLog); LOG(ERROR) << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog; }; // Шейдерная программа this->Program = glCreateProgram(); glAttachShader(this->Program, vertex); glAttachShader(this->Program, fragment); glLinkProgram(this->Program); //Если есть ошибки - вывести их glGetProgramiv(this->Program, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(this->Program, 512, NULL, infoLog); LOG(FATAL) << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog; } // Удаляем шейдеры, поскольку они уже в программу и нам больше не нужны. glDeleteShader(vertex); glDeleteShader(fragment); } void Shader::Use() { glUseProgram(this->Program); } void Shader::Reload() { const GLchar *vertexPath = vertex; const GLchar *fragmentPath = fragment; this->~Shader(); new(this) Shader(vertexPath, fragmentPath); LOG(INFO) << "Shader is realoded!"; }