From 4329c4e47c43dd34a106b5c8158f06728780629a Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Tue, 27 Mar 2018 18:51:07 +0100 Subject: glprog: Wrap OpenGL program object loading glprog provides a simple interface to loadign OpenGL program objects and getting their uniform locations. --- Makefile | 4 ++-- gldefs.h | 1 + glprog.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ glprog.h | 23 ++++++++++++++++++++ gltest.c | 51 +++++++------------------------------------- loadgl.m4 | 2 ++ 6 files changed, 107 insertions(+), 46 deletions(-) create mode 100644 glprog.c create mode 100644 glprog.h diff --git a/Makefile b/Makefile index aa71c5c..5abbc46 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ CFLAGS += $(shell $(PKG_CONFIG) --cflags $(LIBS)) -std=c11 -MMD -MP LDFLAGS += -Wl,--as-needed LDLIBS += $(shell $(PKG_CONFIG) --libs $(LIBS)) -OBJ := gltest.o loadgl.o eprintf.o vert.o frag.o +OBJ := gltest.o loadgl.o eprintf.o vert.o frag.o glprog.o DEP := $(OBJ:.o=.d) %.o: %.glsl @@ -25,7 +25,7 @@ $(PROG): $(OBJ) clean: $(RM) $(OBJ) $(DEP) $(PROG) $(CLEAN) -loadgl.o gltest.o: loadgl.h +loadgl.o gltest.o glprog.o: loadgl.h loadgl.c loadgl.h: loadgl.%: loadgl.m4 loadgl.%.in m4 $^ >$@ CLEAN += loadgl.c loadgl.h diff --git a/gldefs.h b/gldefs.h index cb2a87d..f1bf79f 100644 --- a/gldefs.h +++ b/gldefs.h @@ -57,6 +57,7 @@ enum { GL_FRAGMENT_SHADER = 0x8b30, GL_VERTEX_SHADER = 0x8b31, GL_COMPILE_STATUS = 0x8b81, + GL_LINK_STATUS = 0x8b82, }; #endif // GLDEFS_H diff --git a/glprog.c b/glprog.c new file mode 100644 index 0000000..84f2bab --- /dev/null +++ b/glprog.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2018 Tomasz Kramkowski + * SPDX-License-Identifier: MIT + */ +#include + +#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; +} diff --git a/glprog.h b/glprog.h new file mode 100644 index 0000000..1f540a9 --- /dev/null +++ b/glprog.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2018 Tomasz Kramkowski + * SPDX-License-Identifier: MIT + */ +#ifndef GLPROG_H +#define GLPROG_H + +#include "gldefs.h" + +struct unidat { + const char *name; + GLint *loc; +}; + +struct shdrdat { + GLuint type; + const char *src; + GLint len; +}; + +GLuint glprog_load(int nshdrs, const struct shdrdat *shdrs, int nunis, const struct unidat *unis); + +#endif // SHADER_H diff --git a/gltest.c b/gltest.c index e40ee0f..cb43383 100644 --- a/gltest.c +++ b/gltest.c @@ -7,6 +7,7 @@ #include "eprintf.h" #include "gldefs.h" +#include "glprog.h" #include "linmath.h" #include "loadgl.h" #include "shaders.h" @@ -14,7 +15,6 @@ enum { WIDTH = 800, HEIGHT = 600, - LOGSIZE = 1024, }; void fb_size_cb(GLFWwindow *win, int width, int height) @@ -29,53 +29,12 @@ void take_input(GLFWwindow *win) glfwSetWindowShouldClose(win, true); } -GLuint load_shader(GLenum type, const char *data, GLint size) -{ - GLuint shdr; - GLint success; - char log[LOGSIZE]; - - shdr = gl_shdr_create(type); - gl_shdr_source(shdr, 1, &data, &size); - gl_shdr_compile(shdr); - gl_shdr_param(shdr, GL_COMPILE_STATUS, &success); - - if (!success) { - gl_shdr_infolog(shdr, sizeof log, NULL, log); - eprintf("Failed to compile shader:\n%s", log); - } - - return shdr; -} - -GLuint load_prog(void) -{ - GLuint vert, frag, prog; - GLuint success; - char log[LOGSIZE]; - - vert = load_shader(GL_VERTEX_SHADER, shader_vert_data, shader_vert_size); - frag = load_shader(GL_FRAGMENT_SHADER, shader_frag_data, shader_frag_size); - prog = gl_prog_create(); - gl_prog_attachshdr(prog, vert); - gl_prog_attachshdr(prog, frag); - gl_prog_link(prog); - gl_prog_param(prog, GL_COMPILE_STATUS, &success); - if (!success) { - gl_prog_infolog(prog, sizeof log, NULL, log); - eprintf("Failed to link program:\n%s", log); - } - gl_shdr_del(vert); - gl_shdr_del(frag); - - return prog; -} - int main(int argc, char **argv) { GLFWwindow *win; int ret; GLuint ebo, vbo, vao, prog; + GLint ucolor; vec3 verts[] = { { 0.5f, 0.5f, 0.0f }, { 0.5f, -0.5f, 0.0f }, @@ -121,7 +80,11 @@ int main(int argc, char **argv) gl_va_define(0, 3, GL_FLOAT, GL_FALSE, sizeof *verts, 0); gl_va_enable(0); - prog = load_prog(); + prog = glprog_load(2, (struct shdrdat []){ + { GL_VERTEX_SHADER, shader_vert_data, shader_vert_size }, + { GL_FRAGMENT_SHADER, shader_frag_data, shader_frag_size }, + }, + 1, &(struct unidat){ "ucolor", &ucolor }); gl_poly_mode(GL_FRONT_AND_BACK, GL_LINE); diff --git a/loadgl.m4 b/loadgl.m4 index 8dd0316..fb9b5e4 100644 --- a/loadgl.m4 +++ b/loadgl.m4 @@ -37,6 +37,8 @@ LOAD(glGetShaderInfoLog, void, gl_shdr_infolog, GLuint shader, GLsizei size, GLs LOAD(glCreateProgram, GLuint, gl_prog_create, void) LOAD(glDeleteProgram, void, gl_prog_del, GLuint program) LOAD(glAttachShader, void, gl_prog_attachshdr, GLuint program, GLuint shader) +LOAD(glDetachShader, void, gl_prog_detachshdr, GLuint program, GLuint shader) +LOAD(glGetAttachedShaders, void, gl_prog_getshdrs, GLuint program, GLsizei max, GLsizei *count, GLuint *shaders) LOAD(glLinkProgram, void, gl_prog_link, GLuint program) LOAD(glUseProgram, void, gl_prog_use, GLuint program) LOAD(glGetProgramiv, void, gl_prog_param, GLuint prog, GLenum pname, GLint *params) -- cgit v1.2.3-54-g00ecf