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
101
102
103
104
105
|
shader_t compile_gl_shader(u32 type, char **src)
{
shader_t shader = {0};
shader.id = glCreateShader(type);
glShaderSource(shader.id, 1, (const char **)src, 0);
glCompileShader(shader.id);
i32 status;
glGetShaderiv(shader.id, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
glGetShaderInfoLog(shader.id, MAX_SHADER_LOG, 0, shader.log);
else
snprintf(shader.log, MAX_SHADER_LOG, "compiled successfully");
return shader;
}
shader_t compile_gl_shader_file(u32 type, const char *filename)
{
char *src;
shader_t shader = {0};
arena_t tmp = alloc_arena(0);
if (!sys_read_file(&tmp, &src, filename)) {
printf("error: failed to read: \"%s\"\n", filename);
release_arena(&tmp);
return shader;
}
shader = compile_gl_shader(type, &src);
release_arena(&tmp);
if (!shader.id)
printf("error: \"%s\": ", filename);
else
printf("info: \"%s\": ", filename);
printf("%s", shader.log);
printf("\n");
return shader;
}
shader_t load_gl_shader(const char *dir, const char *vert_filename, const char *geom_filename, const char *frag_filename)
{
shader_t shader = {0};
shader.id = glCreateProgram();
char full_path[MAX_PATH];
shader_t vert;
if (vert_filename) {
snprintf(full_path, sizeof(full_path), "%s/%s", dir, vert_filename);
vert = compile_gl_shader_file(GL_VERTEX_SHADER, full_path);
glAttachShader(shader.id, vert.id);
}
shader_t geom;
if (geom_filename) {
snprintf(full_path, sizeof(full_path), "%s/%s", dir, geom_filename);
geom = compile_gl_shader_file(GL_GEOMETRY_SHADER, full_path);
glAttachShader(shader.id, geom.id);
}
shader_t frag;
if (frag_filename) {
snprintf(full_path, sizeof(full_path), "%s/%s", dir, frag_filename);
frag = compile_gl_shader_file(GL_FRAGMENT_SHADER, full_path);
glAttachShader(shader.id, frag.id);
}
i32 status;
glLinkProgram(shader.id);
glGetProgramiv(shader.id, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
glGetProgramInfoLog(shader.id, MAX_SHADER_LOG, 0, shader.log);
printf("error: failed to link shader program:\n%s", shader.log);
} else {
printf("info: shader linked successfuly\n\n");
}
if (vert_filename)
glDeleteShader(vert.id);
if (geom_filename)
glDeleteShader(geom.id);
if (frag_filename)
glDeleteShader(frag.id);
return shader;
}
void shader_set_v3(shader_t shader, const char *name, v3 vec)
{
i32 location = glGetUniformLocation(shader.id, name);
glUniform3fv(location, 1, (f32 *)&vec);
}
void shader_set_v4(shader_t shader, const char *name, v4 vec)
{
i32 location = glGetUniformLocation(shader.id, name);
glUniform4fv(location, 1, (f32 *)&vec);
}
void shader_set_mat4(shader_t shader, const char *name, mat4 mat)
{
i32 location = glGetUniformLocation(shader.id, name);
glUniformMatrix4fv(location, 1, 0, (f32 *)&mat);
}
|