U32 compile_glsl_shader(U32 type, const char *fname) { Arena *tmpa; FLS src; const char *csrc; U32 id; S32 status; tmpa = alloc_arena(0); src = sys_read_entire_file_fls(tmpa, fname); if (!src.p) { sys_printf("[ERROR] : Failed to read \"%s\"\n", fname); return 0; } csrc = (const char *)src.p; 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); sys_printf("[ERROR] : Failed to compile : \"%s\"\n%s", fname, log); } else { sys_printf("[INFO] : \"%s\" compiled successfully.\n", fname); } release_arena(tmpa); return id; } Shader load_shader(const char *vfname, const char *gfname, const char *ffname) { Shader shader; U32 vert, geom, frag; S32 success; shader.id = glCreateProgram(); if (vfname) { vert = compile_glsl_shader(GL_VERTEX_SHADER, vfname); glAttachShader(shader.id, vert); } if (gfname) { geom = compile_glsl_shader(GL_GEOMETRY_SHADER, gfname); glAttachShader(shader.id, geom); } if (ffname) { frag = compile_glsl_shader(GL_FRAGMENT_SHADER, ffname); glAttachShader(shader.id, frag); } glLinkProgram(shader.id); glGetProgramiv(shader.id, GL_LINK_STATUS, &success); if (success == GL_FALSE) { char log[512]; glGetProgramInfoLog(shader.id, 512, 0, log); sys_printf("[ERROR] : Failed to link shader program:\n%s", log); } else { sys_printf("[INFO] : Shader linked successfuly.\n\n"); } if (vfname) glDeleteShader(vert); if (gfname) glDeleteShader(geom); if (ffname) glDeleteShader(frag); return shader; } void set3fv(U32 id, const char *name, V3 v) { S32 loc = glGetUniformLocation(id, name); glUniform3fv(loc, 1, (F32 *)&v); } void set4fv(U32 id, const char *name, V4 v) { S32 loc = glGetUniformLocation(id, name); glUniform4fv(loc, 1, (F32 *)&v); } void setmat4fv(U32 id, const char *name, MAT4 m) { S32 loc = glGetUniformLocation(id, name); glUniformMatrix4fv(loc, 1, 0, (F32 *)&m); }