polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

commit 1330cf8b09f481a3b36386b16a0f29e4fc24032f
parent 1f8ccbebbae181526906fac35a26ea66a60ed98e
Author: William Casarin <bill@casarin.me>
Date:   Fri, 26 Jun 2015 00:53:04 -0700

Initial slab stuff

  - slab parser
  - create geom_t from slabs

Diffstat:
MMakefile | 8+++++++-
Aetc/slab/test.slab | 0
Msrc/common.h | 6++++++
Msrc/file.c | 1-
Msrc/file.h | 5++---
Asrc/geometry.c | 2++
Asrc/geometry.h | 15+++++++++++++++
Msrc/main.c | 23+++++++++++++++++++++--
Msrc/render.c | 8++++++--
Msrc/render.h | 4+++-
Msrc/shader.c | 2++
Asrc/slab.c | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/slab.h | 28++++++++++++++++++++++++++++
Asrc/slab_geom.c | 34++++++++++++++++++++++++++++++++++
Asrc/slab_geom.h | 18++++++++++++++++++
15 files changed, 273 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile @@ -3,7 +3,10 @@ BIN ?= $(NAME) PREFIX ?= /usr/local CFLAGS = -ggdb -I src -Wall -Wextra -Weverything -Werror -std=c99 \ -Wno-unused-function \ - -Wno-unused-variable + -Wno-unused-parameter \ + -Wno-unused-variable \ + -Wno-cast-align \ + -Wno-padded LDFLAGS = -lSDL2 -lGL DEFS= -DGLFW_INCLUDE_NONE SRC=src @@ -21,6 +24,9 @@ OBJS += $(SRC)/mat4/mat4.o OBJS += $(SRC)/render.o OBJS += $(SRC)/shader.o OBJS += $(SRC)/update.o +OBJS += $(SRC)/slab.o +OBJS += $(SRC)/slab_geom.o +#OBJS += $(SRC)/geometry.o all: $(BIN) diff --git a/etc/slab/test.slab b/etc/slab/test.slab Binary files differ. diff --git a/src/common.h b/src/common.h @@ -5,8 +5,14 @@ #define MAT3_ELEMS 9 #define MAT4_ELEMS 16 +#define SLAB(f) "etc/slab/" f +#define RESOURCE(f) "etc/shaders/" f + #define PI 3.14159265f; +typedef unsigned char u8; +typedef signed char s8; + typedef unsigned short u16; typedef signed short s16; diff --git a/src/file.c b/src/file.c @@ -20,7 +20,6 @@ file_contents(const char *filename, size_t *length) { buffer = malloc(*length+1); *length = fread(buffer, 1, *length, f); fclose(f); - ((char*)buffer)[*length] = '\0'; return buffer; } diff --git a/src/file.h b/src/file.h @@ -1,8 +1,7 @@ #ifndef POLYADVEMT_FILE_H #define POLYADVEMT_FILE_H -#include "gl.h" - -void *file_contents(const char *filename, size_t *length); +void * +file_contents(const char *filename, size_t *length); #endif /* POLYADVEMT_FILE_H */ diff --git a/src/geometry.c b/src/geometry.c @@ -0,0 +1,2 @@ + + diff --git a/src/geometry.h b/src/geometry.h @@ -0,0 +1,15 @@ + +#include "common.h" + +#ifndef GEOMETRY_H +#define GEOMETRY_H + + +struct geom_t { + int num_elements; + float *vertices; + float *normals; + u16 *indices; +}; + +#endif /* GEOMETRY_H */ diff --git a/src/main.c b/src/main.c @@ -1,34 +1,53 @@ #include "gl.h" #include "game.h" +#include "slab.h" +#include "file.h" #include "update.h" #include "window.h" +#include "slab_geom.h" +#include "geometry.h" #include "event.h" #include "render.h" int main(void) { struct game_state game; + struct slab_t slab; + struct geom_t slab_geom; + size_t length; + void *slab_buffer; SDL_Window *window = SDL_CreateWindow( "SDL2/OpenGL Demo", 0, 0, 640, 480, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); - /* SDL_GLContext _SDL_GLContext _gl =gl = */ SDL_GL_CreateContext(window); + SDL_GL_CreateContext(window); init_gl(&game.test_resources); init_game(&game); + // load slab file + slab_buffer = file_contents(SLAB("test.slab"), &length); + // parse to a slab_t + slab_parse(&slab, slab_buffer); + slab_show(&slab); + // mesh it -> load into vbo + alloc_slab_geom(&slab, &slab_geom, NULL); + /* Loop until the user closes the window */ while (1) { process_events(); update(&game); - render(&game.test_resources); + render(&game.test_resources, &slab_geom); /* Swap front and back buffers */ SDL_GL_SwapWindow(window); } + //free(slab_buffer); + //free_slab_geom(&geom, NULL) + //SDL_GL_DeleteContext(gl); //return 0; } diff --git a/src/render.c b/src/render.c @@ -8,6 +8,7 @@ #include "mat4/mat4.h" #include "buffer.h" #include "shader.h" +#include "geometry.h" #include "debug.h" #include "render.h" #include "util.h" @@ -143,8 +144,8 @@ recalc_normals(GLint norm_uniform, mat4 *mvp, mat4 *normal) { static float tmp_matrix[MAT4_ELEMS] = { 0 }; - -void render (struct test_resources * resources) { +void +render (struct test_resources * resources, struct geom_t *geom) { static float id[MAT4_ELEMS] = { 0 }; mat4_id(id); @@ -171,6 +172,9 @@ void render (struct test_resources * resources) { bind_vbo(&resources->vertex_buffer, resources->attributes.position); + bind_vbo(&resources->vertex_buffer, + resources->attributes.position); + bind_vbo(&resources->normal_buffer, resources->attributes.normal); diff --git a/src/render.h b/src/render.h @@ -1,8 +1,10 @@ #ifndef POLYADVENT_RENDER_H #define POLYADVENT_RENDER_H +#include "geometry.h" + void init_gl(struct test_resources * resources); -void render(struct test_resources * resources); +void render (struct test_resources * resources, struct geom_t *geom); void wireframe_mode_on(); void wireframe_mode_off(); diff --git a/src/shader.c b/src/shader.c @@ -17,6 +17,8 @@ make_shader(GLenum type, const char *filename) { if (!source) return 0; + source[length] = '\0'; + shader = glCreateShader(type); glShaderSource(shader, 1, (const GLchar*const*)&source, (GLint*)&length); free(source); diff --git a/src/slab.c b/src/slab.c @@ -0,0 +1,129 @@ + + +#include "slab.h" +#include "util.h" +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + + +#define defconsume(T) \ + static inline T \ + consume_##T(void **p) { \ + T *i = (T*)*p; \ + T v = *i++; \ + *p = (void*)i; \ + return v; \ + } + +defconsume(int) +//defconsume(char) + +/* slab_vbo(const void *data) { */ +/* struct slab_t *slab = (struct slab_t*)data; */ +/* assert(slab->x == 3); */ +/* assert(slab->y == 3); */ +/* assert(slab->z == 3); */ +/* } */ + +struct slab_t *slab_parse(struct slab_t *slab, void *data) { + void *p = data; + slab->x = consume_int(&p); + slab->y = consume_int(&p); + slab->z = consume_int(&p); + slab->voxels = (void*)p; + return slab; +} + +int slab_size(const struct slab_t *slab) { + return slab->x * + slab->y * + slab->z; +} + +void slab_show(const struct slab_t *slab) { + printf("slab %d %d %d\n", slab->x, slab->y, slab->z); +} + + + +// v6----- v5 +// /| /| +// v1------v0| +// | | | | +// | |v7---|-|v4 +// |/ |/ +// v2------v3 + +#define BLOCK_AIR 0xFF + +static const float cube_verts[] = { + 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0-v1-v2-v3 front + 1, 1,-1, 1, 1, 1, 1,-1, 1, 1,-1,-1, // v5-v0-v3-v4 right + -1, 1, 1, 1, 1, 1, 1, 1,-1, -1, 1,-1, // v1-v0-v5-v6 top + -1, 1, 1, -1, 1,-1, -1,-1,-1, -1,-1, 1, // v1-v6-v7-v2 left + 1,-1, 1, -1,-1, 1, -1,-1,-1, 1,-1,-1, // v3-v2-v7-v4 bottom + -1, 1,-1, 1, 1,-1, 1,-1,-1, -1,-1,-1 // v4-v7-v6-v5 back +}; + +static const float cube_normals[] = { + 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // front + 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // right + 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // top + -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // left + 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, // bottom + 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 // back +}; + + +static const u16 cube_indices[] = { + 0, 1, 2, 0, 2, 3, // front + 4, 5, 6, 4, 6, 7, // right + 8, 9,10, 8,10,11, // top + 12,13,14, 12,14,15, // left + 16,17,18, 16,18,19, // bottom + 20,21,22, 20,22,23 +}; + +void +slab_arrays(const struct slab_t *slab, + float *verts, + u16 *indices, + float *normals) { + int x, y, z, i, j; + u16 start_index = 0; + int verts_ind, normals_ind, index_ind; + verts_ind = 0; normals_ind = 0; index_ind = 0; + float xs = slab->x; + float ys = slab->y; + float zs = slab->z; + int cube_verts_size = ARRAY_SIZE(cube_verts); + int cube_indices_size = ARRAY_SIZE(cube_indices); + float n = 0.5f; + u8 color = 0; + + for (y = 0; y < ys; ++y) + for (x = 0; x < xs; ++x) + for (z = 0; z < zs; ++z) { + for (i = 0; i < cube_verts_size; i += 12) + for (j = 0; j < 12; j += 3) { + int k = i + j; + verts[verts_ind++] = cube_verts[k] * n + x; + verts[verts_ind++] = cube_verts[k+1] * n + y; + verts[verts_ind++] = cube_verts[k+2] * n + z; + + normals[normals_ind++] = cube_normals[k]; + normals[normals_ind++] = cube_normals[k+1]; + normals[normals_ind++] = cube_normals[k+2]; + } + + // if we have something other than air + if (color != BLOCK_AIR) { + for (i = 0; i < cube_indices_size; ++i) { + indices[index_ind++] = cube_indices[i] + start_index; + } + } + + start_index += 24; + } +} diff --git a/src/slab.h b/src/slab.h @@ -0,0 +1,28 @@ + +#ifndef SLAB_H +#define SLAB_H + +#include "common.h" + +struct slab_t { + int x; + int y; + int z; + char *voxels; +}; + +struct slab_t * +slab_parse(struct slab_t *slab, void *data); + +void +slab_show(const struct slab_t *slab); + +int slab_size(const struct slab_t *slab); + +void +slab_arrays(const struct slab_t *slab, + float *verts, + u16 *indices, + float *normals); + +#endif /* SLAB_H */ diff --git a/src/slab_geom.c b/src/slab_geom.c @@ -0,0 +1,34 @@ + +#include "slab_geom.h" +#include <stdlib.h> + +struct geom_t* +alloc_slab_geom(const struct slab_t *slab, + struct geom_t *geom, + void* (*_realloc)(void*, size_t)) { + _realloc = _realloc ? _realloc : realloc; + float *verts, *normals; + u16 *indices; + const int num_cubes = slab_size(slab); + const int num_sides = 6; + const int vert_per_side = 4; + const int num_verts = num_cubes * num_sides * vert_per_side; + verts = _realloc(NULL, (size_t)num_verts * 3 * sizeof(float)); + normals = _realloc(NULL, (size_t)num_verts * 3 * sizeof(float)); + indices = _realloc(NULL, (size_t)num_verts * sizeof(u16)); + geom->vertices = verts; + geom->indices = indices; + geom->normals = normals; + geom->num_elements = num_verts; + return geom; +} + + +void +free_slab_geom(struct geom_t *geom, + void (*_free)(void*)) { + _free = _free ? _free : free; + _free(geom->vertices); + _free(geom->indices); + _free(geom->normals); +} diff --git a/src/slab_geom.h b/src/slab_geom.h @@ -0,0 +1,18 @@ + +#ifndef SLAB_GEOM +#define SLAB_GEOM + +#include "geometry.h" +#include "slab.h" +#include <stddef.h> + +struct geom_t* +alloc_slab_geom(const struct slab_t *slab, + struct geom_t *geom, + void* (*_realloc)(void*, size_t)); + +void +free_slab_geom(struct geom_t *geom, + void (*_free)(void*)); + +#endif // SLAB_GEOM