-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprogram.c
116 lines (94 loc) · 2.92 KB
/
program.c
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
106
107
108
109
110
111
112
113
114
115
116
#include "program.h"
#include <stdbool.h>
bool compile_shader(GLint * shader_id, const char *path)
{
FILE *file = fopen(path, "r");
fseek(file, 0L, SEEK_END);
size_t length = ftell(file) + 1;
char *source = calloc(sizeof(char), length);
rewind(file);
INFO("Read %zu bytes from shader.",
fread(source, sizeof(char), length, file));
fclose(file);
glShaderSource(*shader_id, 1, (const char **) &source, NULL);
GLint compiled = GL_FALSE;
glCompileShader(*shader_id);
glGetShaderiv(*shader_id, GL_COMPILE_STATUS, &compiled);
if (compiled == GL_FALSE) {
char error_txt[1024];
int max_length = 1024;
glGetShaderInfoLog(*shader_id, 1024, &max_length, error_txt);
FATAL("Couldn't compile shader '%s'.\n%s", path, error_txt);
return false;
}
free(source);
return true;
}
program_t program_new(const char *vs_path, const char *fs_path)
{
program_t program;
GLint vs_id, fs_id;
vs_id = glCreateShader(GL_VERTEX_SHADER);
compile_shader(&vs_id, vs_path);
fs_id = glCreateShader(GL_FRAGMENT_SHADER);
compile_shader(&fs_id, fs_path);
/* And now, create the program. */
program.id = glCreateProgram();
glAttachShader(program.id, vs_id);
glAttachShader(program.id, fs_id);
// Binding attribute locations to the program.
glBindAttribLocation(program.id, 0, "position");
glBindAttribLocation(program.id, 1, "normal");
glBindAttribLocation(program.id, 2, "uv");
glLinkProgram(program.id);
GLint linked = GL_FALSE;
glGetProgramiv(program.id, GL_LINK_STATUS, &linked);
if (!linked) {
char error_txt[1024];
int max_length = 1024;
glGetShaderInfoLog(fs_id, 1024, &max_length, error_txt);
FATAL("Couldn't link program.\n%s", error_txt);
}
INFO("Done loading program %d", program.id);
DEBUG_GL();
return program;
}
void program_use(program_t * program)
{
glUseProgram(program->id);
}
void program_terminate(program_t * program)
{
glDeleteProgram(program->id);
}
void program_debug(program_t * program)
{
GLint current_program;
glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program);
if (current_program != program->id) {
INFO("Current program (%d) is not debugged program (%d)",
current_program, program->id);
} else {
INFO("Current program(%d) is active.", current_program);
}
GLint uniforms_no, attributes_no;
GLint size;
GLenum type;
const GLsizei bufSize = 16;
GLchar name[bufSize];
GLsizei length;
glGetProgramiv(program->id, GL_ACTIVE_UNIFORMS, &uniforms_no);
glGetProgramiv(program->id, GL_ACTIVE_ATTRIBUTES, &attributes_no);
INFO("Uniforms in program: %d", uniforms_no);
INFO("Attributes in program: %d", attributes_no);
for (GLint i = 0; i < uniforms_no; i++) {
glGetActiveUniform(uniforms_no, i, bufSize, &length, &size, &type,
name);
INFO("Uniform #%d Type: %u Name: %s\n", i, type, name);
}
for (GLint i = 0; i < attributes_no; i++) {
glGetActiveAttrib(program->id, (GLuint) i, bufSize, &length, &size,
&type, name);
INFO("Attribute #%d Type: %u Name: %s\n", i, type, name);
}
}