diff options
Diffstat (limited to 'graphics/Shader.cpp')
-rw-r--r-- | graphics/Shader.cpp | 102 |
1 files changed, 78 insertions, 24 deletions
diff --git a/graphics/Shader.cpp b/graphics/Shader.cpp index 2b72917..c84e169 100644 --- a/graphics/Shader.cpp +++ b/graphics/Shader.cpp @@ -1,36 +1,90 @@ -#include <GL/glew.h> -#include <iostream> -#include <fstream> #include "Shader.hpp" -Shader::Shader(std::string fileName, bool vertex) { - this->isVertex = vertex; - std::ifstream in(fileName); - if (!in){ - std::cout<<"Can't open shader source at "<<fileName<<std::endl; - throw 519; +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(); } - shaderSource = std::string((std::istreambuf_iterator<char>(in)), - std::istreambuf_iterator<char>()); - shaderId = glCreateShader(isVertex?GL_VERTEX_SHADER:GL_FRAGMENT_SHADER); - const char* shaderSrc = shaderSource.c_str(); - glShaderSource(shaderId, 1, &shaderSrc, NULL); - glCompileShader(shaderId); + catch (std::ifstream::failure e) { + std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; + } + const GLchar *vShaderCode = vertexCode.c_str(); + const GLchar *fShaderCode = fragmentCode.c_str(); + + + // 2. Сборка шейдеров + GLuint vertex, fragment; GLint success; GLchar infoLog[512]; - glGetShaderiv(shaderId, GL_COMPILE_STATUS, &success); - if(!success) - { - glGetShaderInfoLog(shaderId, 512, NULL, infoLog); + + // Вершинный шейдер + 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); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; - throw 518; + }; + + // Вершинный шейдер + 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); + std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; + }; + + // Шейдерная программа + 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); + std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } -} -Shader::~Shader() { - glDeleteShader(shaderId); + // Удаляем шейдеры, поскольку они уже в программу и нам больше не нужны. + glDeleteShader(vertex); + glDeleteShader(fragment); } -void Shader::bind() { +void Shader::Use() { + glUseProgram(this->Program); +} +void Shader::Reload() { + const GLchar *vertexPath = vertex; + const GLchar *fragmentPath = fragment; + this->~Shader(); + new(this) Shader(vertexPath, fragmentPath); + std::cout<<"Shader is realoded!"<<std::endl; } |