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
117
118
119
120
121
122
123
124
125
126
127
|
#include "lib/glcorearb.h"
// macro trickery to avoid having to write everything twice
#define gl_for_each_proc(do)\
do(CREATESHADER, CreateShader)\
do(DELETESHADER, DeleteShader)\
do(CREATEPROGRAM, CreateProgram)\
do(SHADERSOURCE, ShaderSource)\
do(GETSHADERIV, GetShaderiv)\
do(GETSHADERINFOLOG, GetShaderInfoLog)\
do(COMPILESHADER, CompileShader)\
do(CREATEPROGRAM, CreateProgram)\
do(DELETEPROGRAM, DeleteProgram)\
do(ATTACHSHADER, AttachShader)\
do(LINKPROGRAM, LinkProgram)\
do(GETPROGRAMIV, GetProgramiv)\
do(GETPROGRAMINFOLOG, GetProgramInfoLog)\
do(USEPROGRAM, UseProgram)\
do(GETATTRIBLOCATION, GetAttribLocation)\
do(GETUNIFORMLOCATION, GetUniformLocation)\
do(GENBUFFERS, GenBuffers)\
do(DELETEBUFFERS, DeleteBuffers)\
do(BINDBUFFER, BindBuffer)\
do(BUFFERDATA, BufferData)\
do(VERTEXATTRIBPOINTER, VertexAttribPointer)\
do(ENABLEVERTEXATTRIBARRAY, EnableVertexAttribArray)\
do(DISABLEVERTEXATTRIBARRAY, DisableVertexAttribArray)\
do(GENVERTEXARRAYS, GenVertexArrays)\
do(BINDVERTEXARRAY, BindVertexArray)\
do(UNIFORM1F, Uniform1f)\
do(UNIFORM2F, Uniform2f)\
do(UNIFORM3F, Uniform3f)\
do(UNIFORM4F, Uniform4f)\
do(UNIFORM1I, Uniform1i)\
do(UNIFORM2I, Uniform2i)\
do(UNIFORM3I, Uniform3i)\
do(UNIFORM4I, Uniform4i)\
do(UNIFORMMATRIX4FV, UniformMatrix4fv)\
do(DEBUGMESSAGECALLBACK, DebugMessageCallback)\
do(DEBUGMESSAGECONTROL, DebugMessageControl)\
#define gl_declare_proc(upper, lower) static PFNGL##upper##PROC gl##lower;
gl_for_each_proc(gl_declare_proc)
#undef gl_declare_proc
// set by main()
static int gl_version_major;
static int gl_version_minor;
static void gl_get_procs(void) {
#define gl_get_proc(upper, lower) gl##lower = (PFNGL##upper##PROC)SDL_GL_GetProcAddress("gl" #lower);
gl_for_each_proc(gl_get_proc)
#undef gl_get_proc
}
// compile a GLSL shader
static GLuint gl_compile_shader(char const *code, GLenum shader_type) {
GLuint shader = glCreateShader(shader_type);
glShaderSource(shader, 1, &code, NULL);
glCompileShader(shader);
GLint status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
char log[1024] = {0};
glGetShaderInfoLog(shader, sizeof log - 1, NULL, log);
debug_println("Error compiling shader: %s", log);
return 0;
}
return shader;
}
// link together GL shaders
static GLuint gl_link_program(GLuint *shaders, size_t count) {
GLuint program = glCreateProgram();
if (program) {
for (size_t i = 0; i < count; ++i) {
if (!shaders[i]) {
glDeleteProgram(program);
return 0;
}
glAttachShader(program, shaders[i]);
}
glLinkProgram(program);
GLint status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
char log[1024] = {0};
glGetProgramInfoLog(program, sizeof log - 1, NULL, log);
debug_println("Error linking shaders: %s", log);
glDeleteProgram(program);
return 0;
}
}
return program;
}
static GLuint gl_compile_and_link_shaders(char const *vshader_code, char const *fshader_code) {
GLuint shaders[2];
shaders[0] = gl_compile_shader(vshader_code, GL_VERTEX_SHADER);
shaders[1] = gl_compile_shader(fshader_code, GL_FRAGMENT_SHADER);
GLuint program = gl_link_program(shaders, 2);
if (shaders[0]) glDeleteShader(shaders[0]);
if (shaders[1]) glDeleteShader(shaders[1]);
if (program) {
debug_print("Successfully linked program %u.\n", program);
}
return program;
}
static GLuint gl_attrib_loc(GLuint program, char const *attrib) {
GLint loc = glGetAttribLocation(program, attrib);
if (loc == -1) {
debug_print("Couldn't find vertex attribute %s.\n", attrib);
return 0;
}
return (GLuint)loc;
}
static GLint gl_uniform_loc(GLuint program, char const *uniform) {
GLint loc = glGetUniformLocation(program, uniform);
if (loc == -1) {
debug_print("Couldn't find uniform: %s.\n", uniform);
return -1;
}
return loc;
}
|