commit 16811635a54c0eb4f849442ce311c8d0d298ca4d
parent 1d79a744f594bc569b9bd769b35e24e8baeeb283
Author: William Casarin <jb55@jb55.com>
Date: Mon, 19 Nov 2018 23:22:32 -0800
dynamic wip
Diffstat:
25 files changed, 489 insertions(+), 256 deletions(-)
diff --git a/Makefile b/Makefile
@@ -12,7 +12,7 @@ LDFLAGS = -lSDL2 -lGL -lm
SRC=src
OBJS = $(SRC)/window.o
-OBJS += $(SRC)/buffer.o
+OBJS += $(SRC)/vbo.o
OBJS += $(SRC)/camera.o
OBJS += $(SRC)/debug.o
OBJS += $(SRC)/delaunay.o
diff --git a/src/buffer.c b/src/buffer.c
@@ -1,71 +0,0 @@
-
-#include "buffer.h"
-#include "util.h"
-#include <assert.h>
-#include "gl.h"
-
-gpu_addr
-make_buffer(GLenum target, const void *buffer_data, GLsizei buffer_size) {
- gpu_addr buffer;
- check_gl();
- glGenBuffers(1, &buffer);
- check_gl();
-
- glBindBuffer(target, buffer);
- check_gl();
-
- glBufferData(target, buffer_size, buffer_data, GL_STATIC_DRAW);
- check_gl();
-
- return buffer;
-}
-
-struct vbo*
-make_index_buffer(GLenum target, const void *data, GLsizei buffer_size,
- struct vbo *vbo) {
- vbo->components = 3;
- vbo->handle = make_buffer(target, data, buffer_size);
- vbo->type = GL_ELEMENT_ARRAY_BUFFER;
- return vbo;
-}
-
-
-struct vbo*
-make_vertex_buffer(GLenum target, const void *data,
- GLsizei buffer_size, struct vbo *vbo) {
- vbo->components = 3;
- vbo->handle = make_buffer(target, data, buffer_size);
- vbo->type = GL_ARRAY_BUFFER;
- return vbo;
-}
-
-struct vbo*
-make_uv_buffer(GLenum target, const void *data,
- GLsizei buffer_size, struct vbo *vbo, int components) {
- vbo->components = components;
- vbo->handle = make_buffer(target, data, buffer_size);
- vbo->type = GL_ARRAY_BUFFER;
- return vbo;
-}
-
-void bind_ibo(struct vbo *vbo) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo->handle);
-}
-
-static void bind_vbo_internal(struct vbo *vbo, gpu_addr slot) {
- glEnableVertexAttribArray(slot);
- check_gl();
- glBindBuffer(vbo->type, vbo->handle);
- check_gl();
- glVertexAttribPointer(slot, // attribute
- vbo->components, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized?
- 0, // stride
- (void*)0 // array buffer offset
- );
-}
-
-void bind_vbo(struct vbo *vbo, gpu_addr slot) {
- bind_vbo_internal(vbo, slot);
-}
diff --git a/src/buffer.h b/src/buffer.h
@@ -1,43 +0,0 @@
-#ifndef POLYADVENT_BUFFER_H
-#define POLYADVENT_BUFFER_H
-
-#include "gl.h"
-#include "common.h"
-
-typedef GLuint gpu_addr;
-
-struct attributes {
- gpu_addr position;
- gpu_addr normal;
- gpu_addr color;
- gpu_addr tex_coord;
-};
-
-struct vbo {
- u32 type;
- int components;
- gpu_addr handle;
-};
-
-#define NUM_VBO_SLOTS 1
-
-gpu_addr make_buffer(GLenum target, const void *buffer_data,
- GLsizei buffer_size);
-
-struct vbo *
-make_vertex_buffer(GLenum target, const void *buffer_data,
- GLsizei buffer_size, struct vbo *vbo);
-
-struct vbo *
-make_index_buffer(GLenum target, const void *buffer_data,
- GLsizei buffer_size, struct vbo *vbo);
-
-struct vbo *
-make_uv_buffer(GLenum target, const void *data,
- GLsizei buffer_size, struct vbo *vbo, int components);
-
-void bind_uv_vbo(struct vbo *vbo, gpu_addr slot);
-void bind_vbo(struct vbo *vbo, gpu_addr slot);
-void bind_ibo(struct vbo *vbo);
-
-#endif /* POLYADVENT_BUFFER_H */
diff --git a/src/entity.c b/src/entity.c
@@ -27,7 +27,6 @@ struct entity *get_all_entities(u32 *count, struct entity_id **ids) {
struct entity *init_entity(struct entity *ent) {
node_init(&ent->node);
- init_model(&ent->model);
ent->casts_shadows = 1;
return ent;
}
@@ -39,16 +38,18 @@ struct entity *get_entity_pure(struct entity_id id) {
return get_entity(&pure_id);
}
-struct entity *get_entity(struct entity_id *id) {
+struct entity *get_entity(struct entity_id *ent_id) {
struct entity_id *new_id;
+ struct id *id = &ent_id->id;
+
// rollover is ok
/* assert(->generation <= esys.generation); */
if (id->generation != esys.generation) {
// try to find uuid in new memory layout
for (u32 i = 0; i < esys.entity_count; i++) {
new_id = &esys.ids[i];
- if (new_id->uuid == id->uuid) {
- id->index = new_id->index;
+ if (new_id->id.uuid == id->uuid) {
+ id->index = new_id->id.index;
id->generation = esys.generation;
return &esys.entities[id->index];
}
@@ -62,9 +63,11 @@ struct entity *get_entity(struct entity_id *id) {
static inline struct entity_id new_id() {
return (struct entity_id){
- .index = esys.entity_count,
- .uuid = entity_uuids++,
- .generation = esys.generation,
+ .id = (struct id) {
+ .index = esys.entity_count,
+ .uuid = entity_uuids++,
+ .generation = esys.generation,
+ }
};
}
@@ -88,8 +91,15 @@ struct entity *add_entity(struct entity *e, struct entity_id *id) {
return new;
}
-void destroy_entity(struct entity *ent) {
+void destroy_entities() {
+ for (u32 i = RESERVED_ENTITIES; i < esys.entity_count; i++) {
+ destroy_entity(&esys.entities[i]);
+ }
+ esys.entity_count = RESERVED_ENTITIES;
+};
+void destroy_entity(struct entity *ent) {
+ node_detach_from_parent(&ent->node);
}
void destroy_entity_system() {
diff --git a/src/entity.h b/src/entity.h
@@ -4,6 +4,9 @@
#include "node.h"
#include "model.h"
+#include "id.h"
+
+#define RESERVED_ENTITIES 2
enum entity_flags {
ENT_IS_PLAYER = 1 << 0,
@@ -12,7 +15,7 @@ enum entity_flags {
struct entity {
struct node node;
- struct model model;
+ struct model *model;
u32 flags;
float velocity[3];
float accel[3];
@@ -20,13 +23,11 @@ struct entity {
};
struct entity_id {
- u64 uuid;
- u32 index;
- u32 generation;
+ struct id id;
};
struct entity *init_entity(struct entity *);
-void delete_entities();
+void destroy_entities();
void destroy_entity(struct entity *);
void init_entity_system();
struct entity *get_entity(struct entity_id *);
diff --git a/src/game.h b/src/game.h
@@ -2,7 +2,7 @@
#ifndef PA_GAME_H
#define PA_GAME_H
-#include "buffer.h"
+#include "vbo.h"
#include "entity.h"
#include "fbo.h"
#include "input.h"
diff --git a/src/geometry.c b/src/geometry.c
@@ -3,14 +3,18 @@
#include "util.h"
#include <assert.h>
+static struct geometry_manager geom_manager;
+
void
-destroy_buffer_geometry(struct geometry *geom) {
+destroy_buffer_geometry(struct geometry_id geom_id) {
+ struct geometry *geom = get_geometry(geom_id);
+
gpu_addr buffers[] = {
- geom->vbos.vertex.handle,
- geom->vbos.normal.handle,
- geom->vbos.color.handle,
- geom->vbos.index.handle,
- geom->vbos.tex_coord.handle
+ geom->vertex.handle,
+ geom->normal.handle,
+ geom->color.handle,
+ geom->index.handle,
+ geom->tex_coord.handle
};
/* void glDeleteVertexArrays(GLsizei n, const GLuint *arrays); */
/* glDisableVertexAttribArray(geom->buffer.vertex_buffer.handle); */
@@ -23,25 +27,27 @@ destroy_buffer_geometry(struct geometry *geom) {
glDeleteBuffers(ARRAY_SIZE(buffers), buffers);
check_gl();
+
+
geom->has_vbos = 0;
}
void bind_geometry(struct geometry *geom, struct attributes *attrs) {
- bind_vbo(&geom->vbos.vertex, attrs->position);
+ bind_vbo(&geom->vertex, attrs->position);
check_gl();
- if (geom->vbos.normal.handle && attrs->normal != 0xFFFFFFFF) {
- bind_vbo(&geom->vbos.normal, attrs->normal);
+ if (geom->normal.handle && attrs->normal != 0xFFFFFFFF) {
+ bind_vbo(&geom->normal, attrs->normal);
check_gl();
}
- if (geom->vbos.color.handle && attrs->color != 0xFFFFFFFF) {
- bind_vbo(&geom->vbos.color, attrs->color);
+ if (geom->color.handle && attrs->color != 0xFFFFFFFF) {
+ bind_vbo(&geom->color, attrs->color);
check_gl();
}
- if (geom->vbos.tex_coord.handle && attrs->tex_coord != 0xFFFFFFFF) {
- bind_vbo(&geom->vbos.tex_coord, attrs->tex_coord);
+ if (geom->tex_coord.handle && attrs->tex_coord != 0xFFFFFFFF) {
+ bind_vbo(&geom->tex_coord, attrs->tex_coord);
check_gl();
}
- bind_ibo(&geom->vbos.index);
+ bind_ibo(&geom->index);
check_gl();
}
@@ -62,7 +68,7 @@ void render_geometry(struct geometry *geom, struct attributes *attrs,
int type = GL_TRIANGLES;
//check_for_patches(program, &type);
bind_geometry(geom, attrs);
- if (geom->indices) {
+ if (geom->num_indices) {
glDrawElements(type,
geom->num_indices, /* count */
GL_UNSIGNED_INT, /* type */
@@ -77,26 +83,36 @@ void render_geometry(struct geometry *geom, struct attributes *attrs,
}
}
+void init_make_geometry(struct make_geometry *mkgeom) {
+ mkgeom->colors = NULL;
+ mkgeom->normals = NULL;
+ mkgeom->indices = NULL;
+ mkgeom->vertices = NULL;
+ mkgeom->tex_coords = NULL;
+ mkgeom->num_uv_components = 2;
+ mkgeom->num_verts = 0;
+ mkgeom->num_indices = 0;
+}
void init_geometry(struct geometry *geom) {
- geom->colors = NULL;
- geom->normals = NULL;
- geom->indices = NULL;
- geom->vertices = NULL;
- geom->tex_coords = NULL;
- geom->num_uv_components = 2;
geom->has_vbos = 0;
-
- geom->vbos.color.handle = 0;
- geom->vbos.normal.handle = 0;
- geom->vbos.tex_coord.handle = 0;
+ init_vbo(&geom->vertex);
+ init_vbo(&geom->color);
+ init_vbo(&geom->normal);
+ init_vbo(&geom->tex_coord);
+ init_vbo(&geom->index);
}
void
-make_buffer_geometry(struct geometry *geom) {
+make_buffer_geometry_(struct make_geometry *mkgeom, struct geometry *geom) {
+
+
// VBOs
+ geom->num_uv_components = mkgeom->num_uv_components;
+ geom->num_verts = mkgeom->num_verts;
+ geom->num_indices = mkgeom->num_indices;
- assert(geom->vertices);
+ assert(mkgeom->vertices);
/* assert(geom->normals); */
/* assert(geom->indices); */
/* assert(geom->num_indices >= 1); */
@@ -104,61 +120,100 @@ make_buffer_geometry(struct geometry *geom) {
/* printf("making vertex buffer\n"); */
make_vertex_buffer(
GL_ARRAY_BUFFER,
- geom->vertices,
- geom->num_verts * 3 * (int)sizeof(*geom->vertices),
- &geom->vbos.vertex
+ mkgeom->vertices,
+ mkgeom->num_verts * 3 * (int)sizeof(*mkgeom->vertices),
+ &geom->vertex
);
/* printf("making normal buffer\n"); */
// cube normals
- if (geom->normals != NULL)
+ if (mkgeom->normals != NULL)
make_vertex_buffer(
GL_ARRAY_BUFFER,
- geom->normals,
- geom->num_verts * 3 * (int)sizeof(*geom->normals),
- &geom->vbos.normal
+ mkgeom->normals,
+ mkgeom->num_verts * 3 * (int)sizeof(*mkgeom->normals),
+ &geom->normal
);
// vertex colors
- if (geom->colors != NULL)
+ if (mkgeom->colors != NULL)
make_vertex_buffer(
GL_ARRAY_BUFFER,
- geom->colors,
- geom->num_verts * 3 * (int)sizeof(*geom->colors),
- &geom->vbos.color
+ mkgeom->colors,
+ mkgeom->num_verts * 3 * (int)sizeof(*mkgeom->colors),
+ &geom->color
);
- if (geom->tex_coords != NULL) {
+ if (mkgeom->tex_coords != NULL) {
assert(geom->num_uv_components);
printf("%f %f %f %f\n",
- geom->tex_coords[0],
- geom->tex_coords[1],
- geom->tex_coords[2],
- geom->tex_coords[3]
+ mkgeom->tex_coords[0],
+ mkgeom->tex_coords[1],
+ mkgeom->tex_coords[2],
+ mkgeom->tex_coords[3]
);
make_uv_buffer(GL_ARRAY_BUFFER,
- geom->tex_coords,
- geom->num_verts * geom->num_uv_components * (int)sizeof(*geom->tex_coords),
- &geom->vbos.tex_coord, geom->num_uv_components);
+ mkgeom->tex_coords,
+ mkgeom->num_verts * mkgeom->num_uv_components * (int)sizeof(*mkgeom->tex_coords),
+ &geom->tex_coord, geom->num_uv_components);
}
/* printf("making index buffer\n"); */
// cube indices
- if (geom->indices)
+ if (mkgeom->indices)
make_index_buffer(
GL_ELEMENT_ARRAY_BUFFER,
- geom->indices,
- geom->num_indices * (int)sizeof(*geom->indices),
- &geom->vbos.index
+ mkgeom->indices,
+ mkgeom->num_indices * (int)sizeof(*mkgeom->indices),
+ &geom->index
);
geom->has_vbos = 1;
}
+struct geometry_id
+make_buffer_geometry(struct make_geometry *mkgeom) {
+ struct geometry_id geom_id;
+ struct geometry *geom = new_geometry(&geom_id);
+
+ make_buffer_geometry_(mkgeom, geom);
+ return geom_id;
+}
+
void geometry_centroid(struct geometry *geom, float *dest) {
vec3_subtract(geom->max, geom->min, dest);
vec3_scale(dest, 0.5, dest);
};
+
+void init_geometry_manager() {
+ geom_manager.num_geometry = 0;
+}
+
+struct geometry *get_geometry(struct geometry_id geom_id) {
+ assert(geom_id.index != -1);
+ assert(geom_id.index < geom_manager.num_geometry);
+ return &geom_manager.geoms[geom_id.index];
+}
+
+
+struct geometry *new_geometry(struct geometry_id *geom_id) {
+ u32 index = geom_manager.num_geometry++;
+ struct geometry *g = &geom_manager.geoms[index];
+ init_geometry(g);
+ if (geom_id)
+ geom_id->index = index;
+
+ return g;
+}
+
+void init_geometry_id(struct geometry_id *id) {
+ id->index = -1;
+}
+
+struct geometry *get_all_geometry(u32 *count) {
+ *count = geom_manager.num_geometry;
+ return &geom_manager.geoms[0];
+}
diff --git a/src/geometry.h b/src/geometry.h
@@ -3,38 +3,63 @@
#define GEOMETRY_H
#include "common.h"
-#include "buffer.h"
+#include "vbo.h"
#include "shader.h"
+#include "id.h"
-struct buffer_geometry {
+#define MAX_GEOMETRY 64
+
+// -1 is uninitialized
+struct geometry_id {
+ struct id id;
+};
+
+struct geometry {
struct vbo vertex;
struct vbo index;
struct vbo normal;
struct vbo color;
struct vbo tex_coord;
-};
-struct geometry {
- struct buffer_geometry vbos;
- int has_vbos;
float min[3];
float max[3];
+
+ int has_vbos;
int num_uv_components;
int num_indices;
int num_verts;
+};
+
+struct make_geometry {
float *vertices;
float *normals;
- u32 *indices;
float *colors;
+ int num_verts;
+
+ u32 *indices;
+ int num_indices;
+
float *tex_coords;
+ int num_uv_components;
+};
+
+struct geometry_manager {
+ struct geometry geoms[MAX_GEOMETRY];
+ int num_geometry;
};
void render_geometry(struct geometry *geom, struct attributes *,
struct gpu_program *current_program);
void bind_geometry(struct geometry *geom, struct attributes *);
void init_geometry(struct geometry *geom);
-void make_buffer_geometry(struct geometry *geom);
+void init_make_geometry(struct make_geometry *mkgeom);
+struct geometry_id make_buffer_geometry(struct make_geometry *mkgeom);
void destroy_buffer_geometry(struct geometry *geom);
void geometry_centroid(struct geometry *geom, float *v3);
+void init_geometry_manager();
+void init_geometry_id(struct geometry_id *);
+struct geometry *new_geometry(struct geometry_id *);
+struct geometry *get_geometry(struct geometry_id);
+struct geometry *get_all_geometry(u32 *count);
#endif /* GEOMETRY_H */
diff --git a/src/id.h b/src/id.h
@@ -0,0 +1,13 @@
+
+#ifndef ID_H
+#define ID_H
+
+#include "common.h"
+
+struct id {
+ u64 uuid;
+ u32 index;
+ u32 generation;
+};
+
+#endif /* ID_H */
diff --git a/src/main.c b/src/main.c
@@ -58,7 +58,8 @@ int main(void)
SDL_GL_CreateContext(window);
game_init(&game, width, height);
- default_scene(&game);
+ /* reset_scene(&game); */
+ /* pbr_scene(&game); */
check_gl();
double last = hires_time_in_seconds();
diff --git a/src/model.c b/src/model.c
@@ -1,26 +1,51 @@
#include "model.h"
#include "ply.h"
+#include <assert.h>
+
+#define MODELDEF(name) { .id = model_##name, .loaded = 0, .file = #name }
+
+static struct model_def static_models[NUM_STATIC_MODELS] = {
+ MODELDEF(tower),
+ MODELDEF(icosphere),
+ MODELDEF(pirateofficer),
+};
+
+static int static_models_initialized = 0;
void init_model(struct model *model) {
model->shading = SHADING_VERT_COLOR;
model->texture = 0;
- init_geometry(&model->geom);
+ init_geometry_id(&model->geom_id);
}
-int load_model(struct model *model, const char *name) {
+static void initialize_static_models() {
+ for (int i = 0; i < NUM_STATIC_MODELS; i++) {
+ struct model_def *sm = &static_models[i];
+ assert(sm->id == i);
+ init_model(&sm->model);
+ }
+ static_models_initialized = 1;
+}
+
+struct model *get_model(enum static_model m) {
static char path[128] = {0};
- if (model->geom.has_vbos)
- return 2;
+ if (!static_models_initialized)
+ initialize_static_models();
+
+ struct model *model = &static_models[m].model;
+
+ if (model->geom_id.index >= 0)
+ return model;
int ok = 0;
// Load mesh
- snprintf(path, 128, "data/models/%s.ply", name);
- ok = parse_ply(path, &model->geom);
+ snprintf(path, 128, "data/models/%s.ply", static_models[m].file);
+ ok = parse_ply(path, &model->geom_id);
if (!ok)
return 0;
- return 1;
+ return model;
}
diff --git a/src/model.h b/src/model.h
@@ -8,7 +8,14 @@
#include "geometry.h"
#include "common.h"
-#define MAX_MODELS 128
+#define MAX_STATIC_MODELS 128
+
+enum static_model {
+ model_tower,
+ model_icosphere,
+ model_pirateofficer,
+ NUM_STATIC_MODELS
+};
enum shading {
SHADING_TERRAIN,
@@ -17,14 +24,21 @@ enum shading {
};
struct model {
- struct geometry geom;
+ struct geometry_id geom_id;
enum shading shading;
u32 texture;
};
+struct model_def {
+ u16 id;
+ int loaded;
+ char *file;
+ struct model model;
+};
+
void init_model(struct model *model);
-int load_model(struct model *model, const char *name);
+struct model *get_model(enum static_model);
#endif /* MODEL_H */
diff --git a/src/node.c b/src/node.c
@@ -115,7 +115,6 @@ int node_recalc(struct node *node) {
return 1;
}
-
int node_detach(struct node *node, struct node *from) {
for (int i = 0; i < from->n_children; i++) {
if (from->children[i] == node) {
@@ -128,6 +127,20 @@ int node_detach(struct node *node, struct node *from) {
return 0;
}
+void node_detach_from_parent(struct node *node) {
+ if (node->parent)
+ node_detach(node, node->parent);
+}
+
+// count the total number of nodes
+int node_count(struct node *node) {
+ int c = 1;
+ for (int i = 0; i < node->n_children; i++) {
+ c += node_count(node->children[i]);
+ }
+ return c;
+}
+
void node_attach(struct node *node, struct node *to) {
assert(to->n_children <= MAX_NODE_CHILDREN);
diff --git a/src/node.h b/src/node.h
@@ -27,6 +27,7 @@ struct node {
int node_recalc(struct node *root);
void node_attach(struct node *node, struct node *to);
int node_detach(struct node *node, struct node *from);
+void node_detach_from_parent(struct node *node);
void node_mark_for_recalc(struct node *node);
struct node *node_init(struct node *node);
void node_translate(struct node *node, float *p);
@@ -34,6 +35,7 @@ void node_forward(struct node *node, float *p);
void node_forward_dir(struct node *node, float *orientation, float *p);
void node_rotate(struct node *node, float *p);
void node_scale(struct node *node, float val);
+int node_count(struct node *node);
float *node_world(struct node *node);
#endif /* POLYADVENT_NODE_H */
diff --git a/src/ply.c b/src/ply.c
@@ -105,7 +105,7 @@ static int parse_magic(const char **cursor) {
}
-int parse_ply(const char *filename, struct geometry *geom) {
+int parse_ply(const char *filename, struct geometry_id *geom_id) {
size_t len;
int success = 0;
int nverts = 0;
@@ -118,8 +118,10 @@ int parse_ply(const char *filename, struct geometry *geom) {
enum ply_state state = PLY_MAGIC;
const char *data = file_contents(filename, &len);
const char *p = data;
+ struct make_geometry mkgeom;
+ init_make_geometry(&mkgeom);
- float vert[3], norm[3];
+ float vert[3], norm[3], min[3], max[3];
int inds[3];
u8 color[3];
@@ -144,10 +146,10 @@ int parse_ply(const char *filename, struct geometry *geom) {
break;
}
- geom->vertices = calloc(nverts * 3, sizeof(*geom->vertices));
- geom->normals = calloc(nverts * 3, sizeof(*geom->normals));
- geom->colors = calloc(nverts * 3, sizeof(*geom->colors));
- geom->indices = calloc(ninds * 3, sizeof(*geom->indices));
+ mkgeom.vertices = calloc(nverts * 3, sizeof(*mkgeom.vertices));
+ mkgeom.normals = calloc(nverts * 3, sizeof(*mkgeom.normals));
+ mkgeom.colors = calloc(nverts * 3, sizeof(*mkgeom.colors));
+ mkgeom.indices = calloc(ninds * 3, sizeof(*mkgeom.indices));
state = PLY_VERTICES;
}
@@ -162,25 +164,25 @@ int parse_ply(const char *filename, struct geometry *geom) {
// compute bounding box as we go
if (cvert == 0) {
- vec3_copy(vert, geom->min);
- vec3_copy(vert, geom->max);
+ vec3_copy(vert, min);
+ vec3_copy(vert, max);
}
else {
- vec3_min(vert, geom->min, geom->min);
- vec3_max(vert, geom->max, geom->max);
+ vec3_min(vert, min, min);
+ vec3_max(vert, max, max);
}
- geom->vertices[cvert * 3] = vert[0];
- geom->vertices[cvert * 3 + 1] = vert[1];
- geom->vertices[cvert * 3 + 2] = vert[2];
+ mkgeom.vertices[cvert * 3] = vert[0];
+ mkgeom.vertices[cvert * 3 + 1] = vert[1];
+ mkgeom.vertices[cvert * 3 + 2] = vert[2];
- geom->normals[cvert * 3] = norm[0];
- geom->normals[cvert * 3 + 1] = norm[1];
- geom->normals[cvert * 3 + 2] = norm[2];
+ mkgeom.normals[cvert * 3] = norm[0];
+ mkgeom.normals[cvert * 3 + 1] = norm[1];
+ mkgeom.normals[cvert * 3 + 2] = norm[2];
- geom->colors[cvert * 3] = color[0] / 255.0;
- geom->colors[cvert * 3 + 1] = color[1] / 255.0;
- geom->colors[cvert * 3 + 2] = color[2] / 255.0;
+ mkgeom.colors[cvert * 3] = color[0] / 255.0;
+ mkgeom.colors[cvert * 3 + 1] = color[1] / 255.0;
+ mkgeom.colors[cvert * 3 + 2] = color[2] / 255.0;
cvert++;
@@ -196,9 +198,9 @@ int parse_ply(const char *filename, struct geometry *geom) {
break;
}
- geom->indices[cind * 3] = inds[0];
- geom->indices[cind * 3 + 1] = inds[1];
- geom->indices[cind * 3 + 2] = inds[2];
+ mkgeom.indices[cind * 3] = inds[0];
+ mkgeom.indices[cind * 3 + 1] = inds[1];
+ mkgeom.indices[cind * 3 + 2] = inds[2];
cind++;
@@ -224,14 +226,19 @@ int parse_ply(const char *filename, struct geometry *geom) {
free((void*)data);
if (success) {
+ *geom_id = make_buffer_geometry(&mkgeom);
+ struct geometry *geom =
+ get_geometry(*geom_id);
+
+ vec3_copy(min, geom->min);
+ vec3_copy(max, geom->max);
geom->num_indices = ninds * 3;
geom->num_verts = nverts * 3;
- make_buffer_geometry(geom);
- free(geom->vertices);
- free(geom->normals);
- free(geom->colors);
- free(geom->indices);
+ free(mkgeom.vertices);
+ free(mkgeom.normals);
+ free(mkgeom.colors);
+ free(mkgeom.indices);
}
return success;
diff --git a/src/ply.h b/src/ply.h
@@ -5,6 +5,6 @@
#include "geometry.h"
-int parse_ply(const char *filename, struct geometry *geom);
+int parse_ply(const char *filename, struct geometry_id *geom_id);
#endif /* PLYPARSER_H */
diff --git a/src/scene.c b/src/scene.c
@@ -7,6 +7,8 @@ void reset_scene(struct game *game) {
struct entity *terrain_ent = get_terrain_entity(&game->terrain);
struct entity *player_ent = get_player(&game->test_resources);
+ destroy_entities();
+
// hide terrain and player by default
terrain_ent->flags |= ENT_INVISIBLE;
player_ent->flags |= ENT_INVISIBLE;
@@ -24,8 +26,7 @@ void default_scene(struct game *game) {
player->flags &= ~ENT_INVISIBLE;
struct entity *tower = new_entity(NULL);
- int ok = load_model(&tower->model, "tower");
- assert(ok);
+ tower->model = get_model(model_tower);
tower->node.label = "tower";
node_attach(&tower->node, &player->node);
node_translate(&tower->node, V3(0.0, 50.0, 0.0));
@@ -39,5 +40,5 @@ void default_scene(struct game *game) {
}
void pbr_scene(struct game *game) {
-
+ struct model *sphere = get_model(model_icosphere);
}
diff --git a/src/scene.h b/src/scene.h
@@ -0,0 +1,11 @@
+
+#ifndef SCENE_H
+#define SCENE_H
+
+#include "game.h"
+
+void default_scene(struct game *);
+void reset_scene(struct game *);
+void pbr_scene(struct game *);
+
+#endif /* SCENE_H */
diff --git a/src/skybox.c b/src/skybox.c
@@ -36,7 +36,6 @@ static u32 skybox_indices[] = {
void create_skybox(struct skybox *skybox, struct gpu_program *program) {
struct shader vertex, frag;
struct shader *shaders[] = {&vertex, &frag};
- struct geometry *geom = &skybox->model.geom;
int ok;
node_init(&skybox->node);
@@ -44,15 +43,19 @@ void create_skybox(struct skybox *skybox, struct gpu_program *program) {
skybox->program = program;
- geom->vertices = skybox_vertices;
- geom->indices = skybox_indices;
+ struct make_geometry mkgeom;
+ init_make_geometry(&mkgeom);
+
+ mkgeom.vertices = skybox_vertices;
+ mkgeom.indices = skybox_indices;
/* geom->tex_coords = skybox_uvs; */
/* geom->num_uv_components = 3; */
- geom->num_verts = ARRAY_SIZE(skybox_vertices);
- geom->num_indices = ARRAY_SIZE(skybox_indices);
+ mkgeom.num_verts = ARRAY_SIZE(skybox_vertices);
+ mkgeom.num_indices = ARRAY_SIZE(skybox_indices);
- make_buffer_geometry(&skybox->model.geom);
+ skybox->model.geom_id =
+ make_buffer_geometry(&mkgeom);
static const char *faces[6] = {
CUBEMAP("hw_sahara/sahara_rt_flip.tga"),
@@ -109,7 +112,7 @@ void render_skybox(struct skybox *skybox, mat4 *camera) {
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->model.texture);
check_gl();
- render_geometry(&skybox->model.geom, &skybox->attrs, skybox->program);
+ render_geometry(get_geometry(skybox->model.geom_id), &skybox->attrs, skybox->program);
check_gl();
glDepthMask(GL_TRUE);
diff --git a/src/terrain.c b/src/terrain.c
@@ -56,7 +56,8 @@ void init_terrain(struct terrain *terrain, float size) {
ent = new_entity(&terrain->entity_id);
assert(terrain->entity_id.uuid == 0);
- ent->model.shading = SHADING_TERRAIN;
+ terrain->model.shading = SHADING_TERRAIN;
+ ent->model = &terrain->model;
ent->node.label = "terrain_node";
ent->casts_shadows = 0;
@@ -205,13 +206,16 @@ void create_terrain(struct terrain *terrain, float scale) {
struct entity *ent = get_entity(&terrain->entity_id);
assert(ent);
- ent->model.geom.num_verts = num_verts;
- ent->model.geom.vertices = (float*)del_verts;
- ent->model.geom.normals = (float*)del_norms;
- ent->model.geom.indices = (u32*)del_indices;
- ent->model.geom.num_indices = num_verts;
+ struct make_geometry mkgeom;
+ init_make_geometry(&mkgeom);
+ mkgeom.num_verts = num_verts;
+ mkgeom.vertices = (float*)del_verts;
+ mkgeom.normals = (float*)del_norms;
+ mkgeom.indices = (u32*)del_indices;
+ mkgeom.num_indices = num_verts;
- make_buffer_geometry(&ent->model.geom);
+ terrain->model.geom_id =
+ make_buffer_geometry(&mkgeom);
delaunay2d_release(del);
tri_delaunay2d_release(tri);
@@ -227,5 +231,5 @@ void create_terrain(struct terrain *terrain, float scale) {
void destroy_terrain(struct terrain *terrain) {
struct entity *ent = get_entity(&terrain->entity_id);
assert(ent);
- destroy_buffer_geometry(&ent->model.geom);
+ destroy_buffer_geometry(get_geometry(terrain->model.geom_id));
}
diff --git a/src/terrain.h b/src/terrain.h
@@ -24,6 +24,7 @@ struct terrain {
struct entity_id entity_id;
struct perlin_settings settings;
struct point *samples;
+ struct model model;
double (*fn)(struct terrain *, double, double);
int n_samples;
double size;
diff --git a/src/tests.c b/src/tests.c
@@ -0,0 +1,35 @@
+
+#include "scene.h"
+#include "entity.h"
+
+
+/* #define t_assert(cond, msg) if (cond) { printf(msg); } */
+#define t_assert(cond, msg) assert(cond);
+
+int scene_tests(struct game *game) {
+ struct node *root = &game->test_resources.root;
+ u32 ent_count;
+ int initial_node_count = node_count(root);
+ reset_scene(game);
+ t_assert(node_count(root) == initial_node_count,
+ "scene: node count doesn't match initial after reset_scene");
+
+ get_all_entities(&ent_count, NULL);
+ t_assert(ent_count == RESERVED_ENTITIES,
+ "scene: entity count isn't reset after reset_scene");
+
+ default_scene(game);
+ get_all_entities(&ent_count, NULL);
+
+ t_assert(ent_count > RESERVED_ENTITIES,
+ "scene: entity count isn't larger after loading default scene");
+
+ reset_scene(game);
+ t_assert(ent_count == RESERVED_ENTITIES,
+ "scene: entity count isn't reset after reset_scene");
+
+ t_assert(node_count(root) == initial_node_count,
+ "scene: node count doesn't match initial after reset_scene");
+
+ return 1;
+}
diff --git a/src/ui.c b/src/ui.c
@@ -1,7 +1,7 @@
#include "ui.h"
#include "mat4.h"
-#include "buffer.h"
+#include "vbo.h"
#include "geometry.h"
#include "util.h"
#include "common.h"
@@ -34,18 +34,21 @@ static GLfloat quad_uvs[] =
};
-static void create_quad(struct geometry *geom)
+static struct geometry_id create_quad()
{
- init_geometry(geom);
- geom->indices = quad_indices;
- geom->vertices = quad_vertices;
- geom->colors = quad_normals;
- geom->tex_coords = quad_uvs;
- geom->num_indices = ARRAY_SIZE(quad_indices);
- geom->num_verts = ARRAY_SIZE(quad_vertices);
- geom->num_uv_components = 2;
- make_buffer_geometry(geom);
+ struct make_geometry mkgeom = {
+ .indices = quad_indices,
+ .vertices = quad_vertices,
+ .normals = quad_normals,
+ .tex_coords = quad_uvs,
+ .num_indices = ARRAY_SIZE(quad_indices),
+ .num_verts = ARRAY_SIZE(quad_vertices),
+ .num_uv_components = 2
+ };
+ struct geometry_id id = make_buffer_geometry(&mkgeom);
check_gl();
+
+ return id;
}
void render_ui(struct ui *ui, float *view) {
diff --git a/src/vbo.c b/src/vbo.c
@@ -0,0 +1,78 @@
+
+#include "vbo.h"
+#include "util.h"
+#include <assert.h>
+#include "gl.h"
+
+gpu_addr
+make_buffer(GLenum target, const void *buffer_data, GLsizei buffer_size) {
+ gpu_addr buffer;
+ check_gl();
+ glGenBuffers(1, &buffer);
+ check_gl();
+
+ glBindBuffer(target, buffer);
+ check_gl();
+
+ glBufferData(target, buffer_size, buffer_data, GL_STATIC_DRAW);
+ check_gl();
+
+ return buffer;
+}
+
+struct vbo*
+make_index_buffer(GLenum target, const void *data, GLsizei buffer_size,
+ struct vbo *vbo) {
+ vbo->components = 3;
+ vbo->handle = make_buffer(target, data, buffer_size);
+ vbo->type = GL_ELEMENT_ARRAY_BUFFER;
+ return vbo;
+}
+
+
+struct vbo*
+make_vertex_buffer(GLenum target, const void *data,
+ GLsizei buffer_size, struct vbo *vbo) {
+ vbo->components = 3;
+ vbo->handle = make_buffer(target, data, buffer_size);
+ vbo->type = GL_ARRAY_BUFFER;
+ return vbo;
+}
+
+struct vbo*
+make_uv_buffer(GLenum target, const void *data,
+ GLsizei buffer_size, struct vbo *vbo, int components) {
+ vbo->components = components;
+ vbo->handle = make_buffer(target, data, buffer_size);
+ vbo->type = GL_ARRAY_BUFFER;
+ return vbo;
+}
+
+void bind_ibo(struct vbo *vbo) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo->handle);
+}
+
+struct vbo* init_vbo(struct vbo *vbo) {
+ vbo->type = 0;
+ vbo->handle = 0;
+ vbo->components = 0;
+ return vbo;
+}
+
+static void bind_vbo_internal(struct vbo *vbo, gpu_addr slot) {
+ glEnableVertexAttribArray(slot);
+ check_gl();
+ glBindBuffer(vbo->type, vbo->handle);
+ check_gl();
+ glVertexAttribPointer(slot, // attribute
+ vbo->components, // size
+ GL_FLOAT, // type
+ GL_FALSE, // normalized?
+ 0, // stride
+ (void*)0 // array buffer offset
+ );
+}
+
+void bind_vbo(struct vbo *vbo, gpu_addr slot) {
+ bind_vbo_internal(vbo, slot);
+}
diff --git a/src/vbo.h b/src/vbo.h
@@ -0,0 +1,45 @@
+#ifndef POLYADVENT_BUFFER_H
+#define POLYADVENT_BUFFER_H
+
+#include "gl.h"
+#include "common.h"
+
+typedef GLuint gpu_addr;
+
+struct attributes {
+ gpu_addr position;
+ gpu_addr normal;
+ gpu_addr color;
+ gpu_addr tex_coord;
+};
+
+struct vbo {
+ u32 type;
+ int components;
+ gpu_addr handle;
+};
+
+#define NUM_VBO_SLOTS 1
+
+gpu_addr make_buffer(GLenum target, const void *buffer_data,
+ GLsizei buffer_size);
+
+struct vbo *init_vbo(struct vbo *);
+
+struct vbo *
+make_vertex_buffer(GLenum target, const void *buffer_data,
+ GLsizei buffer_size, struct vbo *vbo);
+
+struct vbo *
+make_index_buffer(GLenum target, const void *buffer_data,
+ GLsizei buffer_size, struct vbo *vbo);
+
+struct vbo *
+make_uv_buffer(GLenum target, const void *data,
+ GLsizei buffer_size, struct vbo *vbo, int components);
+
+void bind_uv_vbo(struct vbo *vbo, gpu_addr slot);
+void bind_vbo(struct vbo *vbo, gpu_addr slot);
+void bind_ibo(struct vbo *vbo);
+
+#endif /* POLYADVENT_BUFFER_H */