aboutsummaryrefslogtreecommitdiffstats
path: root/glprog.c
blob: 84f2bab76a1270cdf5f6474eb9efdbda8292cbd8 (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
/*
 * Copyright (C) 2018 Tomasz Kramkowski <tk@the-tk.com>
 * SPDX-License-Identifier: MIT
 */
#include <assert.h>

#include "eprintf.h"
#include "glprog.h"
#include "loadgl.h"

enum {
	LOGSIZE = 1024,
};

static GLuint load_shader(const struct shdrdat *shdr)
{
	GLuint id;
	GLint success;
	char log[LOGSIZE];

	id = gl_shdr_create(shdr->type);
	gl_shdr_source(id, 1, &shdr->src, &shdr->len);
	gl_shdr_compile(id);
	gl_shdr_param(id, GL_COMPILE_STATUS, &success);

	if (!success) {
		gl_shdr_infolog(id, sizeof log, NULL, log);
		eprintf("Failed to compile shader:\n%s", log);
	}

	return id;
}

void detach_shaders(GLuint prog)
{
	GLsizei count;
	GLuint shdr;

	while (gl_prog_getshdrs(prog, 1, &count, &shdr), count)
		gl_prog_detachshdr(prog, shdr);
}

GLuint glprog_load(int nshdrs, const struct shdrdat *shdrs, int nunis, const struct unidat *unis)
{
	GLuint prog;
	GLint success;
	char log[LOGSIZE];

	assert(nshdrs > 0);
	assert(shdrs != NULL);
	assert(nunis <= 0 || unis != NULL);

	prog = gl_prog_create();
	for (int i = 0; i < nshdrs; i++) {
		GLuint shdr = load_shader(&shdrs[i]);
		gl_prog_attachshdr(prog, shdr);
		gl_shdr_del(shdr);
	}
	gl_prog_link(prog);
	gl_prog_param(prog, GL_LINK_STATUS, &success);
	if (!success) {
		gl_prog_infolog(prog, sizeof log, NULL, log);
		eprintf("Failed to link program:\n%s", log);
	}

	detach_shaders(prog);

	for (int i = 0; i < nunis; i++)
		*unis[i].loc = gl_uni_loc(prog, unis[i].name);

	return prog;
}