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