summaryrefslogtreecommitdiff
path: root/gl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl.c')
-rw-r--r--gl.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/gl.c b/gl.c
new file mode 100644
index 0000000..6e61742
--- /dev/null
+++ b/gl.c
@@ -0,0 +1,128 @@
+#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;
+}
+
+