/*********************************************************************************************************************** * * Copyright (c) 2010 - 2025 by Tech Soft 3D, Inc. * The information contained herein is confidential and proprietary to Tech Soft 3D, Inc., and considered a trade secret * as defined under civil and criminal statutes. Tech Soft 3D shall pursue its civil and criminal remedies in the event * of unauthorized use or misappropriation of its trade secrets. Use of this information by anyone other than authorized * employees of Tech Soft 3D, Inc. is granted only under a written non-disclosure agreement, expressly prescribing the * scope and manner of such use. * ***********************************************************************************************************************/ #include "shader.h" #include #include #include #include std::string parse_file(const char* filename) { try { std::ifstream file; file.open(filename); std::stringstream filestream; filestream << file.rdbuf(); file.close(); return filestream.str(); } catch (std::ifstream::failure& e) { std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl; } return ""; } Shader::Shader(const char* vertex_filename, const char* fragment_filename) { std::string vertex_filepath = SHADERS_FOLDER; vertex_filepath.append("/"); vertex_filepath.append(vertex_filename); std::string vertexCode = parse_file(vertex_filepath.c_str()); const char* vShaderCode = vertexCode.c_str(); std::string fragment_filepath = SHADERS_FOLDER; fragment_filepath.append("/"); fragment_filepath.append(fragment_filename); std::string fragmentCode = parse_file(fragment_filepath.c_str()); const char* fShaderCode = fragmentCode.c_str(); unsigned int vertex, fragment; // vertex shader vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vShaderCode, nullptr); glCompileShader(vertex); compile_errors(vertex, "VERTEX"); // fragment Shader fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fShaderCode, nullptr); glCompileShader(fragment); compile_errors(fragment, "FRAGMENT"); // shader Program ID = glCreateProgram(); glAttachShader(ID, vertex); glAttachShader(ID, fragment); glLinkProgram(ID); compile_errors(ID, "PROGRAM"); glDeleteShader(vertex); glDeleteShader(fragment); } void Shader::use() { glUseProgram(ID); } void Shader::detach() { glDeleteProgram(ID); } void Shader::add_light_properties(const glm::vec3& light_position) { use(); set_vec4("lightColor", 1.f, 1.f, 1.f, 0.f); set_vec3("lightPos", light_position); } void Shader::compile_errors(unsigned int shader, const std::string & type) { GLint success; GLchar infoLog[1024]; if (type != "PROGRAM") { glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(shader, 1024, NULL, infoLog); std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; } } else { glGetProgramiv(shader, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shader, 1024, NULL, infoLog); std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; } } } void Shader::set_value(const std::string& name, float value) const { glUniform1fv(glGetUniformLocation(ID, name.c_str()), 1, &value); } void Shader::set_vec2(const std::string& name, const glm::vec2& value) const { glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); } void Shader::set_vec2(const std::string& name, float x, float y) const { glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y); } // ------------------------------------------------------------------------ void Shader::set_vec3(const std::string& name, const glm::vec3& value) const { glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); } void Shader::set_vec3(const std::string& name, float x, float y, float z) const { glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z); } // ------------------------------------------------------------------------ void Shader::set_vec4(const std::string& name, const glm::vec4& value) const { glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); } void Shader::set_vec4(const std::string& name, float x, float y, float z, float w) const { glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w); } // ------------------------------------------------------------------------ void Shader::set_mat4(const std::string& name, const glm::mat4& mat) const { glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); } void Shader::update_view_matrix(const glm::mat4& mat) const { set_mat4("view", mat); } void Shader::update_world_matrix(const glm::mat4& mat) const { set_mat4("world", mat); } void Shader::update_model_matrix(const glm::mat4& mat) const { set_mat4("model", mat); set_mat4("model_normal", glm::transpose(glm::inverse(mat))); } void Shader::update_projection_matrix(const glm::mat4& mat) const { set_mat4("projection", mat); } void Shader::update_mesh_color(const glm::vec4& rgba) const { set_vec4("material.ambiant", rgba); set_vec4("material.diffuse", rgba); set_vec4("material.specular", 0.5f, 0.5f, 0.5f, rgba[3]); set_vec4("material.emissive", 0.f, 0.f, 0.f, rgba[3]); set_value("material.shininess", 0.5f); } void Shader::update_mesh_material(const utils::properties::style::Material& material) const { set_vec4("material.ambiant", material.ambient); set_vec4("material.diffuse", material.diffuse); set_vec4("material.specular", material.specular); set_vec4("material.emissive", material.emissive); set_value("material.shininess", material.shininess); } void Shader::update_mesh_style(const utils::properties::style::Graphics& graphics, bool& is_first) { if (!is_first && current_graphics_id == graphics.id) return; is_first = false; current_graphics_id = graphics.id; if (graphics.id == -1) { update_mesh_material(utils::properties::style::default_material); } else if (graphics.type == utils::properties::style::Graphics::UNDEF) { update_mesh_material(utils::properties::style::default_material); } else if (graphics.type == utils::properties::style::Graphics::TEXTURE) { std::cout << "WARNING::TEXTURE::NOT_IMPLEMENTED_IN_THE_SAMPLE" << std::endl; update_mesh_material(utils::properties::style::default_material); } else if (graphics.type == utils::properties::style::Graphics::RGBA) { update_mesh_color(graphics.rgba); } else if (graphics.type == utils::properties::style::Graphics::MATERIAL) { update_mesh_material(graphics.material); } else { std::cout << "ERROR::STYLE::UNEXPECTED" << std::endl; update_mesh_material(utils::properties::style::default_material); } }