commit dc809dd3b27dd35c37e5edde3ac3d43d09bd8ab8
parent 0ab43ad67334d1984eb5178b6887197e68a4ee26
Author: William Casarin <jb55@jb55.com>
Date:   Fri, 26 Oct 2018 23:57:02 -0700
progress on UI/FBOS/geometry refactor
Diffstat:
18 files changed, 298 insertions(+), 43 deletions(-)
diff --git a/Makefile b/Makefile
@@ -8,7 +8,7 @@ CFLAGS = $(DEFS) -ggdb -Ofast -I src -Wall -Werror -Wextra -std=c99 \
 						-Wno-unused-variable \
 						-Wno-cast-align \
 						-Wno-padded
-LDFLAGS = -lSDL2 -lGL
+LDFLAGS = -lSDL2 -lGL -lm
 SRC=src
 
 OBJS  = $(SRC)/window.o
@@ -17,6 +17,7 @@ OBJS += $(SRC)/camera.o
 OBJS += $(SRC)/debug.o
 OBJS += $(SRC)/delaunay.o
 OBJS += $(SRC)/event.o
+OBJS += $(SRC)/fbo.o
 OBJS += $(SRC)/file.o
 OBJS += $(SRC)/game.o
 OBJS += $(SRC)/geometry.o
@@ -24,8 +25,10 @@ OBJS += $(SRC)/input.o
 OBJS += $(SRC)/main.o
 OBJS += $(SRC)/mat4.o
 OBJS += $(SRC)/mat_util.o
+OBJS += $(SRC)/model.o
 OBJS += $(SRC)/node.o
 OBJS += $(SRC)/perlin.o
+OBJS += $(SRC)/ply.o
 OBJS += $(SRC)/poisson.o
 OBJS += $(SRC)/quat.o
 OBJS += $(SRC)/render.o
@@ -35,8 +38,7 @@ OBJS += $(SRC)/uniform.o
 OBJS += $(SRC)/update.o
 OBJS += $(SRC)/util.o
 OBJS += $(SRC)/vec3.o
-OBJS += $(SRC)/ply.o
-OBJS += $(SRC)/model.o
+OBJS += $(SRC)/ui.o
 
 SRCS=$(OBJS:.o=.c)
 
diff --git a/etc/shaders/terrain.glsl b/etc/shaders/terrain.glsl
@@ -19,15 +19,6 @@ out vec3 v_ray;
 
 const int nlands = 6;
 
-const vec4 land[nlands] = vec4[](
-	vec4(0.0, 0.5, 0.79, 0.0),          // 0 - water
-	vec4(0.9176, 0.8156, 0.6588, 1.0),  // 1 - sand
-	vec4(0.6274, 0.749, 0.156, 2.0),    // 2 - grass
-	vec4(0.4627, 0.3333, 0.1686, 20.0), // 3 - dirt
-	vec4(0.5, 0.5, 0.5, 80.0),         // 4 - stone
-	vec4(1.0, 1.0, 1.0, 380.0)          // 5 - snow
-);
-
 vec3 standard_light(vec3 color) {
 	vec4 v4_normal = vec4(normal , 1);
 	vec4 trans_normal = normal_matrix * v4_normal;
@@ -54,11 +45,19 @@ vec3 gamma_correct(vec3 color) {
     return pow(color, vec3(1.0/2.2));
 }
 
+const vec4 land[nlands] = vec4[](
+  vec4(0.0, 0.5, 0.79, 0.0),          // 0 - water
+  vec4(0.9176, 0.8156, 0.6588, 1.0),  // 1 - sand
+  vec4(0.6274, 0.749, 0.156, 2.0),    // 2 - grass
+  vec4(0.4627, 0.3333, 0.1686, 20.0), // 3 - dirt
+  vec4(0.5, 0.5, 0.5, 80.0),         // 4 - stone
+  vec4(1.0, 1.0, 1.0, 380.0)          // 5 - snow
+);
+
 void main()
 {
 	vec4 v4_pos = vec4(position, 1.0);
 	gl_Position = mvp * v4_pos;
-	// float light = dot(trans_normal.xyz, normalize(light_dir)) ;
 
     vec3 color = land[0].xyz;
 
@@ -70,7 +69,6 @@ void main()
 	}
 
 	// v_color = vec3(0.2 + position.z*0.05, position.z*0.0095, position.z*0.0001) * 0.5;
-
 	 // v_color = vec3(position.z, position.z, position.z) * 0.005;
 
     v_color = hemispherical(color);
diff --git a/etc/shaders/vertex-color.glsl b/etc/shaders/vertex-color.glsl
@@ -20,6 +20,8 @@ flat out vec3 v_color;
 flat out vec3 v_normal;
 out vec3 v_ray;
 
+// TODO: includes
+// #include "lighting.glsl"
 
 vec3 standard_light(vec3 color) {
     vec4 v4_normal = vec4(normal, 1);
diff --git a/src/buffer.c b/src/buffer.c
@@ -20,7 +20,6 @@ make_buffer(GLenum target, const void *buffer_data, GLsizei buffer_size) {
   return buffer;
 }
 
-
 struct vbo*
 make_index_buffer(GLenum target, const void *data, GLsizei buffer_size,
                   struct vbo *vbo) {
diff --git a/src/buffer.h b/src/buffer.h
@@ -6,6 +6,12 @@
 
 typedef GLuint gpu_addr;
 
+struct attributes {
+    gpu_addr position;
+    gpu_addr normal;
+    gpu_addr color;
+};
+
 struct vbo {
   u32 type;
   int components;
diff --git a/src/fbo.c b/src/fbo.c
@@ -0,0 +1,65 @@
+
+#include <assert.h>
+#include "fbo.h"
+
+void create_fbo(struct fbo *fbo, int width, int height) {
+    glGenFramebuffers(1, &fbo->handle);
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
+
+    fbo->width = width;
+    fbo->height = height;
+}
+
+int fbo_attach_renderbuffer(struct fbo *fbo,
+                            GLenum internalformat, GLenum attachment) {
+    assert(fbo->n_attachments < MAX_FBO_ATTACHMENTS);
+    GLuint *rbo = &fbo->attachments[fbo->n_attachments++];
+
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
+    glGenRenderbuffers(1, rbo);
+    glBindRenderbuffer(GL_RENDERBUFFER, *rbo);
+    glRenderbufferStorage(GL_RENDERBUFFER, internalformat, fbo->width, fbo->height);
+    glBindRenderbuffer(GL_RENDERBUFFER, 0);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, *rbo);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+    return *rbo;
+}
+
+int fbo_attach_texture(struct fbo *fbo, GLenum attachment) {
+    assert(fbo->n_attachments < MAX_FBO_ATTACHMENTS);
+    GLuint *texture = &fbo->attachments[fbo->n_attachments++];
+
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
+    glGenTextures(1, texture);
+    glBindTexture(GL_TEXTURE_2D, *texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fbo->width, fbo->height, 0, GL_RGB,
+                  GL_UNSIGNED_BYTE, NULL);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+    glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, *texture,
+                           0);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+    return *texture;
+}
+
+void fbo_check(struct fbo *fbo) {
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
+    assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void delete_fbo(struct fbo *fbo) {
+    glDeleteFramebuffers(1, &fbo->handle);
+}
+
+
+void bind_fbo(struct fbo *fbo) {
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
+}
+
+void unbind_fbo(struct fbo *fbo) {
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
diff --git a/src/fbo.h b/src/fbo.h
@@ -0,0 +1,26 @@
+#ifndef POLYADVENT_FBO_H
+#define POLYADVENT_FBO_H
+
+#include "common.h"
+#include "gl.h"
+
+#define MAX_FBO_ATTACHMENTS 3
+
+struct fbo {
+    GLuint handle;
+    GLuint attachments[MAX_FBO_ATTACHMENTS];
+    int n_attachments;
+    int width, height;
+};
+
+void bind_fbo(struct fbo *fbo);
+void create_fbo(struct fbo *fbo, int width, int height);
+int fbo_attach_texture(struct fbo *, GLenum attachment);
+void fbo_check(struct fbo *fbo);
+int fbo_attach_renderbuffer(struct fbo *fbo, GLenum internalformat, GLenum attachment);
+void delete_fbo(struct fbo *);
+void unbind_fbo(struct fbo *fbo);
+
+
+
+#endif /* POLYADVENT_FBO_H */
diff --git a/src/game.c b/src/game.c
@@ -33,7 +33,6 @@ void game_init(struct game *game) {
     int ok = 0;
 
     const double size = 10000;
-    const double pdist = 1.7;
 
     terrain->settings = (struct perlin_settings){
         .depth = 1,
@@ -48,7 +47,7 @@ void game_init(struct game *game) {
     };
 
     terrain_init(terrain);
-    terrain->entity.model.program = res->terrain_program.handle;
+    terrain->entity.model.shading = SHADING_TERRAIN;
     terrain->size = size;
 
     mat4_id(mvp);
@@ -72,7 +71,7 @@ void game_init(struct game *game) {
     // player init
     ok = load_model(&player->model, "pirate-officer");
     assert(ok);
-    player->model.program = res->program.handle;
+    player->model.shading = SHADING_VERT_COLOR;
     player->node.label = "player";
 
     root->label = "root";
diff --git a/src/game.h b/src/game.h
@@ -22,6 +22,7 @@ struct resources {
 	struct gpu_program program;
 	struct gpu_program smooth_program;
 	struct gpu_program terrain_program;
+	struct gpu_program ui_program;
 
 	struct uniforms {
 		GLint camera_position;
@@ -36,11 +37,7 @@ struct resources {
 		GLint world;
 	} uniforms;
 
-	struct attributes {
-		gpu_addr position;
-		gpu_addr normal;
-		gpu_addr color;
-	} attributes;
+	struct attributes attributes;
 
 	struct node root;
 	struct entity player;
@@ -55,10 +52,11 @@ struct resources {
 };
 
 struct game {
-  int counter;
-  struct resources test_resources;
-  struct input input;
-  struct terrain terrain;
+    int counter;
+    int seed;
+    struct resources test_resources;
+    struct input input;
+    struct terrain terrain;
 };
 
 void game_init(struct game *game);
diff --git a/src/geometry.c b/src/geometry.c
@@ -6,10 +6,10 @@
 void
 destroy_buffer_geometry(struct geometry *geom) {
     gpu_addr buffers[] = {
-        geom->buffer.vertex_buffer.handle,
-        geom->buffer.normal_buffer.handle,
-        geom->buffer.color_buffer.handle,
-        geom->buffer.index_buffer.handle
+        geom->vbos.vertex.handle,
+        geom->vbos.normal.handle,
+        geom->vbos.color.handle,
+        geom->vbos.index.handle
     };
     /* void glDeleteVertexArrays(GLsizei n, const GLuint *arrays); */
     /* glDisableVertexAttribArray(geom->buffer.vertex_buffer.handle); */
@@ -23,6 +23,21 @@ destroy_buffer_geometry(struct geometry *geom) {
     check_gl();
 }
 
+void render_geometry(struct geometry *geom, struct attributes *attrs)
+{
+    bind_vbo(&geom->vbos.vertex, attrs->position);
+    bind_vbo(&geom->vbos.normal, attrs->normal);
+    if (geom->vbos.color.handle)
+        bind_vbo(&geom->vbos.color, attrs->color);
+    bind_ibo(&geom->vbos.index);
+
+    glDrawElements(GL_TRIANGLES,
+                   geom->num_indices, /* count */
+                   GL_UNSIGNED_INT,    /* type */
+                   (void*)0            /* element array buffer offset */
+                   );
+}
+
 
 void init_geometry(struct geometry *geom) {
     geom->colors = NULL;
@@ -42,7 +57,7 @@ make_buffer_geometry(struct geometry *geom) {
                         GL_ARRAY_BUFFER,
                         geom->vertices,
                         geom->num_verts * 3 * (int)sizeof(*geom->vertices),
-                        &geom->buffer.vertex_buffer
+                        &geom->vbos.vertex
                         );
 
     /* printf("making normal buffer\n"); */
@@ -51,7 +66,7 @@ make_buffer_geometry(struct geometry *geom) {
                         GL_ARRAY_BUFFER,
                         geom->normals,
                         geom->num_verts * 3 * (int)sizeof(*geom->normals),
-                        &geom->buffer.normal_buffer
+                        &geom->vbos.normal
                         );
 
     // vertex colors
@@ -60,7 +75,7 @@ make_buffer_geometry(struct geometry *geom) {
                         GL_ARRAY_BUFFER,
                         geom->colors,
                         geom->num_verts * 3 * (int)sizeof(*geom->colors),
-                        &geom->buffer.color_buffer
+                        &geom->vbos.color
                         );
 
     /* printf("making index buffer\n"); */
@@ -69,6 +84,6 @@ make_buffer_geometry(struct geometry *geom) {
                     GL_ELEMENT_ARRAY_BUFFER,
                     geom->indices,
                     geom->num_indices * (int)sizeof(*geom->indices),
-                    &geom->buffer.index_buffer
+                    &geom->vbos.index
                     );
 }
diff --git a/src/geometry.h b/src/geometry.h
@@ -6,14 +6,14 @@
 #include "buffer.h"
 
 struct buffer_geometry {
-    struct vbo vertex_buffer;
-    struct vbo index_buffer;
-    struct vbo normal_buffer;
-    struct vbo color_buffer;
+    struct vbo vertex;
+    struct vbo index;
+    struct vbo normal;
+    struct vbo color;
 };
 
 struct geometry {
-    struct buffer_geometry buffer;
+    struct buffer_geometry vbos;
     int num_indices;
     int num_verts;
     float *vertices;
@@ -22,6 +22,7 @@ struct geometry {
     float *colors;
 };
 
+void render_geometry(struct geometry *geom, struct attributes *);
 void init_geometry(struct geometry *geom);
 void make_buffer_geometry(struct geometry *geom);
 void destroy_buffer_geometry(struct geometry *geom);
diff --git a/src/gl.h b/src/gl.h
@@ -43,9 +43,48 @@ void glUniform1f(GLint location, GLfloat v0);
 void glGetProgramiv(GLuint program, GLenum pname, GLint *params);
 void glDeleteProgram(	GLuint program);
 
+void glGenFramebuffers(GLsizei handle, GLuint *ids);
+void glBindFramebuffer(	GLenum target, GLuint framebuffer);
+GLenum glCheckFramebufferStatus(GLenum target);
+void glDeleteFramebuffers(GLsizei n, const GLuint * framebuffers);
+
 void glDisableVertexAttribArray(GLuint index);
 void glDeleteVertexArrays(GLsizei n, const GLuint *arrays);
 
 GLboolean glIsBuffer(	GLuint buffer);
 
+
+void glTexImage2D(	GLenum target,
+                    GLint level,
+                    GLint internalformat,
+                    GLsizei width,
+                    GLsizei height,
+                    GLint border,
+                    GLenum format,
+                    GLenum type,
+                    const GLvoid * data);
+
+void glFramebufferTexture2D(	GLenum target,
+                                GLenum attachment,
+                                GLenum textarget,
+                                GLuint texture,
+                                GLint level);
+
+void glGenRenderbuffers(	GLsizei n,
+                            GLuint * renderbuffers);
+
+void glBindRenderbuffer(	GLenum target,
+                            GLuint renderbuffer);
+
+void glRenderbufferStorage(	GLenum target,
+                            GLenum internalformat,
+                            GLsizei width,
+                            GLsizei height);
+
+void glFramebufferRenderbuffer(	GLenum target,
+                                GLenum attachment,
+                                GLenum renderbuffertarget,
+                                GLuint renderbuffer);
+ 
+
 #endif /* POLYADVENT_GL_H */
diff --git a/src/main.c b/src/main.c
@@ -27,6 +27,7 @@ int main(void)
     srand(seed);
 
     struct game game;
+    game.seed = seed;
 
     /* SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); */
     int width = 640;
diff --git a/src/model.h b/src/model.h
@@ -8,9 +8,15 @@
 #include "geometry.h"
 #include "common.h"
 
+enum shading {
+    SHADING_TERRAIN,
+    SHADING_VERT_COLOR,
+    SHADING_UI,
+};
+
 struct model {
     struct geometry geom;
-    u32 program;
+    enum shading shading;
 };
 
 
diff --git a/src/render.c b/src/render.c
@@ -211,7 +211,7 @@ void render (struct game *game) {
 
         recalc_normals(res->uniforms.normal_matrix, model_view, normal_matrix);
 
-        render_geom(res, &entity->model.geom, GL_TRIANGLES);
+        render_geometry(&entity->model.geom, &res->attributes);
 
         check_gl();
     }
diff --git a/src/ui.c b/src/ui.c
@@ -0,0 +1,79 @@
+
+#include "ui.h"
+#include "mat4.h"
+#include "buffer.h"
+#include "geometry.h"
+#include "util.h"
+
+
+//  v1------v0
+//  |       |
+//  |       |
+//  |       |
+//  v2------v3
+
+static const GLfloat quad_vertices[] = {
+  0.5, 0.5, 0.5,  -0.5, 0.5, 0.5,  -0.5,-0.5, 0.5,   0.5,-0.5, 0.5,    // v0-v1-v2-v3 front
+};
+
+
+static const GLfloat quad_normals[] = {
+  0, 0, 1,   0, 0, 1,   0, 0, 1,   0, 0, 1, // front
+};
+
+static const GLushort quad_indices[] = {0, 1, 2,  0, 2, 3};
+
+static void
+render_quad(struct geometry *geom, struct attributes *attrs) {
+    bind_vbo(&geom->vbos.vertex, attrs->position);
+    bind_vbo(&geom->vbos.normal, attrs->normal);
+
+    bind_ibo(&geom->vbos.index);
+
+    glDrawElements(
+                   GL_TRIANGLES,
+                   ARRAY_SIZE(quad_indices), /* count */
+                   GL_UNSIGNED_SHORT,  /* type */
+                   (void*)0            /* element array buffer offset */
+                   );
+
+    //glDisableVertexAttribArray(resources->attributes.position);
+}
+
+
+static void create_quad(struct geometry *geom)
+{
+
+}
+
+void render_ui(struct ui *ui) {
+    glUseProgram(ui->shader.handle);
+
+    // render quad
+
+    // setup camera for shader
+}
+
+
+void resize_ui(struct ui *ui, int width, int height) {
+    float left = 0;
+    float right = width;
+    float top = 0;
+    float bottom = height;
+    float near = 0;
+    float far = 2;
+
+    mat4_ortho(left, right, bottom, top, near, far, ui->camera);
+}
+
+
+void create_ui(struct ui *ui, int width, int height) {
+    struct shader vertex;
+    struct shader fragment;
+
+    make_shader(GL_VERTEX_SHADER, "ui.v.glsl", &vertex);
+    make_shader(GL_FRAGMENT_SHADER, "ui.f.glsl", &vertex);
+    make_program(&vertex, &fragment, &ui->shader);
+
+    resize_ui(ui, width, height);
+}
diff --git a/src/ui.h b/src/ui.h
@@ -0,0 +1,19 @@
+
+#ifndef POLYADVENT_UI_H
+#define POLYADVENT_UI_H
+
+#include "common.h"
+#include "shader.h"
+#include "geometry.h"
+
+struct ui {
+    struct gpu_program shader;
+    struct geometry quad;
+    float camera[MAT4_ELEMS];
+};
+
+void create_ui(struct ui *ui, int width, int height);
+void resize_ui(struct ui *ui, int width, int height);
+void render_ui(struct ui *);
+
+#endif /* POLYADVENT_UI_H */
diff --git a/src/window.c b/src/window.c
@@ -7,7 +7,7 @@
 
 void
 handle_resize(float *camera, int width, int height) {
-  printf("resizing %d %d\n", width, height);
+  /* printf("resizing %d %d\n", width, height); */
   glViewport( 0, 0, width, height );
   mat4_perspective(75 /* fov */, (float)width / height, 1, 20000, camera);