#include "Shader.h" #include "../core.h" #include "../os.h" #include "../vendor/glad/glad.h" #include "../vendor/raymath.h" typedef enum { ShaderType_fragment=GL_FRAGMENT_SHADER, ShaderType_vertex=GL_VERTEX_SHADER, } ShaderType; uint32 createGlShader(string file_path, ShaderType shader_type) { GLuint shader; WithScratch(scratch) { string shader_code = os_readEntireFile(scratch.arena, file_path); shader = glCreateShader(shader_type); const char *shader_code_cstr = cstring(scratch.arena, shader_code); glShaderSource(shader, 1, &shader_code_cstr, NULL); glCompileShader(shader); int success; glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { GLint info_log_length; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length); string info_log = PushString(scratch.arena, (size_t)info_log_length + 1); glGetShaderInfoLog(shader, info_log_length, NULL, info_log.str); string shader_type_name = shader_type == ShaderType_fragment ? s("FRAGMENT") : s("VERTEX"); print("%S shader compilation error (%S):\n%S", shader_type_name, file_path, info_log); } } return shader; } Shader createShader(string vertex_path, string fragment_path) { Shader result = {0}; WithScratch(temp) { uint32 vertex_shader = createGlShader(vertex_path, ShaderType_vertex); uint32 fragment_shader = createGlShader(fragment_path, ShaderType_fragment); result.progId = glCreateProgram(); glAttachShader(result.progId, vertex_shader); glAttachShader(result.progId, fragment_shader); glLinkProgram(result.progId); int success; glGetProgramiv(result.progId, GL_LINK_STATUS, &success); if (!success) { GLint info_log_length; glGetShaderiv(result.progId, GL_INFO_LOG_LENGTH, &info_log_length); string info_log_prog = PushString(temp.arena, (size_t)info_log_length + 1); glGetProgramInfoLog(result.progId, info_log_length, NULL, info_log_prog.str); print("Shader program link error:\n%S", info_log_prog); } glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); } return result; } void setUniformMat4fv(Shader *s, const char *uniformName, Matrix *matrix) { glUniformMatrix4fv( glGetUniformLocation(s->progId, uniformName), 1, GL_FALSE, MatrixToFloat(*matrix)); } void setUniformMat4fvByLoc(int uniformLocation, Matrix *matrix) { glUniformMatrix4fv(uniformLocation, 1, GL_FALSE, MatrixToFloat(*matrix)); } void setUniform4fv(Shader *s, const char *uniformName, Vec4 *vector) { glUniform4fv(glGetUniformLocation(s->progId, uniformName), 1, (const GLfloat *)vector); } void setUniform4fvByLoc(int uniformLocation, Vec4 *vector) { glUniform4fv(uniformLocation, 1, (const GLfloat *)vector); } void setUniform3fv(Shader *s, const char *uniformName, Vec3 *vector) { glUniform3fv(glGetUniformLocation(s->progId, uniformName), 1, Vector3ToFloat(*vector)); } void setUniform3fvByLoc(int uniformLocation, Vec3 *vector) { glUniform3fv(uniformLocation, 1, Vector3ToFloat(*vector)); } void setUniform1i(Shader *s, const char *uniformName, int32 i) { glUniform1i(glGetUniformLocation(s->progId, uniformName), (GLint)i); } void setUniform1iByLoc(int uniformLocation, int32 i) { glUniform1i(uniformLocation, (GLint)i); } void setUniform2fv(Shader *s, const char *uniformName, Vec2 *vector) { glUniform2fv(glGetUniformLocation(s->progId, uniformName), 1, (const GLfloat *)vector); } void setUniform2fvByLoc(int uniformLocation, Vec2 *vector) { glUniform2fv(uniformLocation, 1, (const GLfloat *)vector); } int getUniformLocation(Shader *s, const char *uniformName) { return glGetUniformLocation(s->progId, uniformName); }