U32 compile_shader(GLenum type, Str8 filename) { Arena *tmp = arena_alloc(0); Str8 src = str8_read_entire_file(tmp, filename); if (!src.ptr || !src.length) { str8print(str8_pushf(tmp, "[ERROR] : Failed to read \"%.*s\"\n", str8expand(filename))); arena_release(tmp); return 0; } const char *csrc = str8_to_cstr(tmp, src); U32 id = glCreateShader(type); glShaderSource(id, 1, &csrc, 0); glCompileShader(id); S32 status; glGetShaderiv(id, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { char log[512]; glGetShaderInfoLog(id, 512, 0, log); str8print(str8_pushf(tmp, "[ERROR] : Failed to compile : \"%.*s\"\n%s", str8expand(filename), log)); } else { str8print(str8_pushf(tmp, "[INFO] : \"%.*s\" compiled successfully.\n", str8expand(filename))); } arena_release(tmp); return id; } U32 create_shader_program(Str8 vert_filename, Str8 frag_filename) { U32 vert = compile_shader(GL_VERTEX_SHADER, vert_filename); U32 frag = compile_shader(GL_FRAGMENT_SHADER, frag_filename); Arena *tmp = arena_alloc(0); U32 id = glCreateProgram(); glAttachShader(id, vert); glAttachShader(id, frag); glLinkProgram(id); S32 success; glGetProgramiv(id, GL_LINK_STATUS, &success); if (success == GL_FALSE) { char log[512]; glGetProgramInfoLog(id, 512, 0, log); str8print(str8_pushf(tmp, "[ERROR]: Failed to link shader program:\n%s", log)); } else { str8print(str8_pushf(tmp, "[INFO]: Shader program linked successfuly.\n\n")); } glDeleteShader(vert); glDeleteShader(frag); arena_release(tmp); return id; } void shader_set_mat4fv(U32 id, char *name, Mat4 m) { S32 loc = glGetUniformLocation(id, name); glUniformMatrix4fv(loc, 1, 0, (F32 *)&m); }