/* * ShaderProgram.cpp * * Created on: 31 janv. 2020 * Author: simon */ #include "render/shaders/ShaderProgram.h" #include #include #include #ifdef __ANDROID__ #include #endif ShaderProgram::ShaderProgram() : programID(0), vertexShaderID(0), fragmentShaderID(0) { } ShaderProgram::~ShaderProgram() { cleanUp(); } void ShaderProgram::start() const { glUseProgram(programID); } void ShaderProgram::stop() const { glUseProgram(0); } int ShaderProgram::getUniformLocation(const std::string& uniformName) const { const int location = glGetUniformLocation(programID, uniformName.c_str()); if (location == -1) { std::cout << "Warning ! Uniform variable " << uniformName << " not found !\n"; } return location; } void ShaderProgram::loadFloat(const int location, const float value) const { glUniform1f(location, value); } void ShaderProgram::loadInt(const int& location, const int& value) const { glUniform1i(location, value); } void ShaderProgram::loadVector(const int& location, const glm::vec2& vector) const { glUniform2f(location, vector.x, vector.y); } void ShaderProgram::loadVector(const int& location, const glm::vec3& vector) const { glUniform3f(location, vector.x, vector.y, vector.z); } void ShaderProgram::loadVector(const int& location, const glm::vec4& vector) const { glUniform4f(location, vector.x, vector.y, vector.z, vector.w); } void ShaderProgram::loadBoolean(const int& location, const bool& value) const { glUniform1i(location, value); } void ShaderProgram::cleanUp() const { stop(); glDetachShader(programID, vertexShaderID); glDetachShader(programID, fragmentShaderID); glDeleteShader(vertexShaderID); glDeleteShader(fragmentShaderID); glDeleteProgram(programID); } void ShaderProgram::loadProgramFile(const std::string& vertexFile, const std::string& fragmentFile) { vertexShaderID = loadShaderFromFile(vertexFile, GL_VERTEX_SHADER); fragmentShaderID = loadShaderFromFile(fragmentFile, GL_FRAGMENT_SHADER); programID = glCreateProgram(); glAttachShader(programID, vertexShaderID); glAttachShader(programID, fragmentShaderID); glLinkProgram(programID); glValidateProgram(programID); getAllUniformLocation(); } void ShaderProgram::loadProgram(const std::string& vertexSource, const std::string& fragmentSource) { vertexShaderID = loadShader(vertexSource, GL_VERTEX_SHADER); fragmentShaderID = loadShader(fragmentSource, GL_FRAGMENT_SHADER); programID = glCreateProgram(); glAttachShader(programID, vertexShaderID); glAttachShader(programID, fragmentShaderID); glLinkProgram(programID); glValidateProgram(programID); getAllUniformLocation(); } int ShaderProgram::loadShader(const std::string& source, GLenum type) { unsigned int shaderID = glCreateShader(type); const char* c_str = source.c_str(); int* null = 0; glShaderSource(shaderID, 1, &c_str, null); // @suppress("Function cannot be resolved") glCompileShader(shaderID); GLint compilesuccessful; glGetShaderiv(shaderID, GL_COMPILE_STATUS, &compilesuccessful); if (compilesuccessful == false) { std::cout << "Could not compile shader !\n"; GLsizei size; glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &size); char error[size]; glGetShaderInfoLog(shaderID, size, &size, error); std::cout << error << std::endl; #ifdef __ANDROID__ __android_log_print(ANDROID_LOG_ERROR, "TRACKERS", "Could not compile shader !\n %s", error); #endif } return shaderID; } int ShaderProgram::loadShaderFromFile(const std::string& file, GLenum type) { std::string shaderSource = ""; std::ifstream fileStream(file); if (fileStream.is_open()) { std::string line; while (getline(fileStream, line)) { shaderSource += line + "\n"; } fileStream.close(); } unsigned int shaderID = glCreateShader(type); const char* c_str = shaderSource.c_str(); int* null = 0; glShaderSource(shaderID, 1, &c_str, null); // @suppress("Function cannot be resolved") glCompileShader(shaderID); GLint compilesuccessful; glGetShaderiv(shaderID, GL_COMPILE_STATUS, &compilesuccessful); if (compilesuccessful == false) { std::cout << "Could not compile shader !\n"; GLsizei size; glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &size); char error[size]; glGetShaderInfoLog(shaderID, size, &size, error); std::cout << error << std::endl; } return shaderID; } void ShaderProgram::loadMatrix(const int& location, const glm::mat4& matrix) { glUniformMatrix4fv(location, 1, false, glm::value_ptr(matrix)); }