26 return current_shader;
31 was_compilation_successful(GLuint
object)
34 glGetShaderiv(
object, GL_COMPILE_STATUS, &r);
40 was_linking_successful(GLuint
object)
43 glGetProgramiv(
object, GL_LINK_STATUS, &r);
49 get_shader_log(GLuint shader)
52 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
57 const int max_length = length + 1;
58 std::vector<char> str(max_length, 0);
59 glGetShaderInfoLog(shader, max_length, &length, str.data());
65 get_program_log(GLuint shader)
68 glGetProgramiv(shader, GL_INFO_LOG_LENGTH, &length);
73 const int max_length = length + 1;
74 std::vector<char> str(max_length, 0);
75 glGetProgramInfoLog(shader, max_length, &length, str.data());
88 : id(glCreateProgram())
109 return this == get_current_shader();
116 if(shader !=
nullptr)
118 glUseProgram(shader->
get_id());
124 get_current_shader() = shader;
131 return get_current_shader();
140 "ERROR::SHADER: Compile-time error: Type: {0} \n"
142 "---------------------------------------------------------",
152 const std::string& log = get_program_log(program);
160 const std::string& log = get_shader_log(shader);
168 GLuint shader = glCreateShader(type);
169 glShaderSource(shader, 1, &source,
nullptr);
170 glCompileShader(shader);
171 if(was_compilation_successful(shader))
186 const std::string attribute_name = std::string(attribute.
name);
187 glBindAttribLocation(
get_id(), attribute.
id, attribute_name.c_str());
188 bound_attributes.push_back(attribute);
195 const GLchar* vertex_source,
196 const GLchar* fragment_source,
197 const GLchar* geometry_source
202 GLuint vertex_shader_id =
compile_shader(GL_VERTEX_SHADER, vertex_source,
"VERTEX");
203 GLuint fragment_shader_id =
compile_shader(GL_FRAGMENT_SHADER, fragment_source,
"FRAGMENT");
205 GLuint geometry_shader_id = 0;
206 if(geometry_source !=
nullptr)
208 geometry_shader_id =
compile_shader(GL_GEOMETRY_SHADER, geometry_source,
"GEOMETRY");
211 glAttachShader(
get_id(), vertex_shader_id);
212 glAttachShader(
get_id(), fragment_shader_id);
213 if(geometry_source !=
nullptr)
215 glAttachShader(
get_id(), geometry_shader_id);
218 const bool link_ok = was_linking_successful(
get_id());
225 glDeleteShader(vertex_shader_id);
226 glDeleteShader(fragment_shader_id);
227 if(geometry_source !=
nullptr)
229 glDeleteShader(geometry_shader_id);
232 for(
const auto& attribute: bound_attributes)
234 const std::string attribute_name = std::string(attribute.name);
235 const int actual_attribute_id = glGetAttribLocation(
get_id(), attribute_name.c_str());
237 if(actual_attribute_id == attribute.id)
242 if(actual_attribute_id == -1)
249 "{0} was bound to {1} but was requested at {2}",
264 int uniform_id = glGetUniformLocation(
get_id(), name.c_str());
266 bound_uniforms.push_back(uniform);
272 "Failed to load uniform {0} from shader {1}",
286 ASSERT(has_bound_uniform(attribute));
287 glUniform1f(attribute.
id, val);
295 ASSERT(has_bound_uniform(attribute));
296 glUniform1i(attribute.
id, val);
304 ASSERT(has_bound_uniform(attribute));
305 if(attribute.
id == -1)
309 glUniform3f(attribute.
id, val.
r, val.
g, val.
b);
317 ASSERT(has_bound_uniform(attribute));
318 if(attribute.
id == -1)
322 glUniform4f(attribute.
id, val.
r, val.
g, val.
b, val.
a);
330 ASSERT(has_bound_uniform(attribute));
331 if(attribute.
id == -1)
335 glUniform3f(attribute.
id, val.
x, val.
y, val.
z);
343 ASSERT(has_bound_uniform(attribute));
344 if(attribute.
id == -1)
348 glUniform4f(attribute.
id, val.
x, val.
y, val.
z, val.
w);
356 ASSERT(has_bound_uniform(attribute));
357 if(attribute.
id == -1)
361 glUniformMatrix3fv(attribute.
id, 1, GL_FALSE, val.
get_data_ptr());
369 ASSERT(has_bound_uniform(attribute));
370 if(attribute.
id == -1)
374 glUniformMatrix4fv(attribute.
id, 1, GL_FALSE, val.
get_data_ptr());
382 ASSERT(has_bound_uniform(attribute));
383 if(attribute.
id == -1)
392 : shader_name(
"~/not_loaded_shader")
400 shader_name = file_path;
418 bool loaded_files =
true;
422 LOG_ERROR(
"Failed to load vert shader {0}", file_path);
423 loaded_files =
false;
428 LOG_ERROR(
"Failed to load frag shader {0}", file_path);
429 loaded_files =
false;
437 const bool shader_compiled =
compile
441 geom.empty() ?
nullptr : geom.c_str()
445 LOG_ERROR(
"Failed to compile shader {0}", file_path);
447 return shader_compiled;
451 const std::vector<ShaderAttribute>&
454 return bound_attributes;
466 ShaderProgram::has_bound_attribute(
const ShaderAttribute& attribute)
const
470 bound_attributes.begin(),
471 bound_attributes.end(),
474 return found != bound_attributes.end();
479 ShaderProgram::has_bound_uniform(
const ShaderUniform& uniform)
const
481 const auto found =
std::find(bound_uniforms.begin(), bound_uniforms.end(), uniform);
482 return found != bound_uniforms.end();
496 GLenum gl_id = GL_TEXTURE0 + index;
497 glActiveTexture(gl_id);
std::string trim(const std::string &string_to_trim, std::string_view trim_characters)
Remove characters from both the start and the end.
bool find(const std::string &target, const std::string &search)
void use(const ShaderProgram *shader)
void report_error_program(GLuint program)
GLuint compile_shader(GLuint type, const GLchar *source, const std::string &name)
void bind_texture_to_shader(Texture2 *texture, ShaderProgram *shader, const ShaderUniform &attribute, gl::Int index)
void report_shader_error(const std::string &log, const std::string &type)
void report_error_shader(GLuint shader, const std::string &type)
String utility functions.
FilePath set_extension_copy(const std::string &ext) const
std::optional< std::string > read_file_to_string(const FilePath &path)
Represents a shader attribute like vertex, normal or uv coord.
gl::Int id
the id of the attribute
std::string_view name
the name of the shader attribute
bool is_currently_bound() const
void set_uniform(const ShaderUniform &attribute, gl::Int val)
bool load(io::FileSystem *fs, const io::FilePath &file_path)
bool compile(const gl::Char *vertex_source, const gl::Char *fragment_source, const gl::Char *geometry_source=nullptr)
const io::FilePath & get_name() const
ShaderUniform get_uniform(const std::string &name)
void add_attribute(const ShaderAttribute &attribute)
static const ShaderProgram * get_current_bound_for_debug()
const std::vector< ShaderAttribute > & get_attributes() const