summaryrefslogtreecommitdiff
path: root/prge_shader.c
blob: 3aee9b5d719a15a0989332b0de336162cce38181 (plain)
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
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);
}