aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2018-03-27 18:51:07 +0100
committerTomasz Kramkowski <tk@the-tk.com>2018-03-27 19:21:34 +0100
commit4329c4e47c43dd34a106b5c8158f06728780629a (patch)
tree8ede3a5a46773730f9ad88ae201badb3636e4214
parent126c248cf55d10c1584f9bb340144b42ae57e847 (diff)
downloadfaqe-4329c4e47c43dd34a106b5c8158f06728780629a.tar.gz
faqe-4329c4e47c43dd34a106b5c8158f06728780629a.tar.xz
faqe-4329c4e47c43dd34a106b5c8158f06728780629a.zip
glprog: Wrap OpenGL program object loading
glprog provides a simple interface to loadign OpenGL program objects and getting their uniform locations.
-rw-r--r--Makefile4
-rw-r--r--gldefs.h1
-rw-r--r--glprog.c72
-rw-r--r--glprog.h23
-rw-r--r--gltest.c51
-rw-r--r--loadgl.m42
6 files changed, 107 insertions, 46 deletions
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 <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;
+}
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 <tk@the-tk.com>
+ * 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)