1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
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);
}
|