226 lines
6.8 KiB
C++
226 lines
6.8 KiB
C++
/***********************************************************************************************************************
|
|
*
|
|
* 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 <fstream>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
|
|
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);
|
|
}
|
|
} |