polyadvent

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

commit 2ff19ed7e53ecaf2407053de493508d0872674e7
parent 0daf3a4f126da9e86e77561323265981ea9efc1a
Author: William Casarin <jb55@jb55.com>
Date:   Fri, 27 Apr 2018 23:29:35 -0700

progress

Diffstat:
Adata/samples-200x200.bin | 0
Msrc/geometry.c | 6+++---
Msrc/main.c | 22+++++++++++++---------
Msrc/poisson.c | 34++++++++++++++++++++++++++++++++--
Msrc/poisson.h | 5+++++
Msrc/terrain.c | 26++++++--------------------
Msrc/terrain.h | 6+++++-
Msrc/update.c | 26+++++++++++++-------------
8 files changed, 77 insertions(+), 48 deletions(-)

diff --git a/data/samples-200x200.bin b/data/samples-200x200.bin Binary files differ. diff --git a/src/geometry.c b/src/geometry.c @@ -31,7 +31,7 @@ make_buffer_geometry(struct geometry *geom) { assert(geom->indices); assert(geom->num_indices >= 1); - printf("making vertex buffer\n"); + /* printf("making vertex buffer\n"); */ make_vertex_buffer( GL_ARRAY_BUFFER, geom->vertices, @@ -39,7 +39,7 @@ make_buffer_geometry(struct geometry *geom) { &geom->buffer.vertex_buffer ); - printf("making normal buffer\n"); + /* printf("making normal buffer\n"); */ // cube normals make_vertex_buffer( GL_ARRAY_BUFFER, @@ -48,7 +48,7 @@ make_buffer_geometry(struct geometry *geom) { &geom->buffer.normal_buffer ); - printf("making index buffer\n"); + /* printf("making index buffer\n"); */ // cube indices make_index_buffer( GL_ELEMENT_ARRAY_BUFFER, diff --git a/src/main.c b/src/main.c @@ -19,15 +19,9 @@ int main(void) { int nsamples; - struct point *samples; - const double size = 500; - const double point_dist = 20; - srand(time(NULL)); - - samples = poisson_disk_samples(point_dist, size, 30, &nsamples); - draw_samples(samples, point_dist, nsamples, size); - exit(0); + int seed = time(NULL); + srand(seed); struct game game; struct slab slab; @@ -49,6 +43,14 @@ int main(void) game_init(&game); game.terrain = &terrain; + const double size = 200; + const double pdist = (sqrt(2)*size)/(size-1.0); + /* printf("samples seed %d\n", seed); */ + /* struct point *samples = poisson_disk_samples(pdist, size, 30, &terrain.n_samples); */ + struct point *samples = load_samples(NULL, &terrain.n_samples); + draw_samples(samples, pdist, terrain.n_samples, size); + save_samples(samples, seed, terrain.n_samples); + struct perlin_settings terrain_settings = { .depth = 1, .freq = 0.02, @@ -57,10 +59,12 @@ int main(void) .amplitude = 1.0, .ox = 0, .oy = 0, - .exp = 7.3 + .exp = 7.3, }; terrain_init(&terrain); + terrain.size = size; + terrain.samples = samples; terrain_create(&terrain, &terrain_settings); /* slab_buffer = file_contents(SLAB("test.slab"), &length); */ diff --git a/src/poisson.c b/src/poisson.c @@ -72,6 +72,34 @@ grid_lookup(struct grid_info *info, int x, int y) { return ix; } +void +save_samples(struct point *samples, int seed, int n_samples) { + FILE *fp = fopen("samples.bin", "wb"); /* b - binary mode */ + fwrite(&seed, sizeof(seed), 1, fp); + fwrite(&n_samples, sizeof(n_samples), 1, fp); + fwrite(samples, sizeof(*samples), n_samples, fp); + fclose(fp); +} + +struct point * +load_samples(int *seed, int *n_samples) { + FILE *fp = fopen("data/samples-200x200.bin", "rb"); + int res; + int localseed; + seed = seed ? seed : &localseed; + res = fread(seed, sizeof(*seed), 1, fp); + printf("loaded seed %d\n", *seed); + assert(res); + res = fread(n_samples, sizeof(*n_samples), 1, fp); + printf ("loaded n_samples %d\n", *n_samples); + assert(res); + struct point *samples = malloc(*n_samples * sizeof(*samples)); + res = fread(samples, sizeof(*samples), *n_samples, fp); + assert(res); + fclose(fp); + return samples; +} + static int add_sample(struct grid_info *info, struct point *candidate) { int grid_x = floor(candidate->x / info->cell_size); @@ -158,7 +186,7 @@ poisson_disk_samples(const double point_dist, double size, int all_rejected = 1; - for (int i = 0; i < reject_limit; ++i) { + for (int i = 0, tries = 0; i < reject_limit + tries; ++i) { int sx = rand() % 2 ? 1 : -1; int sy = rand() % 2 ? 1 : -1; @@ -173,8 +201,10 @@ poisson_disk_samples(const double point_dist, double size, int cx = floor(candidate.x / info.cell_size); int cy = floor(candidate.y / info.cell_size); - if (candidate.x > size || candidate.x < 0 || candidate.y > size || candidate.y < 0) + if (candidate.x > size || candidate.x < 0 || candidate.y > size || candidate.y < 0) { + tries++; continue; + } int nearby[] = { grid_lookup(&info, cx - 1, cy - 1), diff --git a/src/poisson.h b/src/poisson.h @@ -13,5 +13,10 @@ struct point * poisson_disk_samples(const double point_dist, double size, const int reject_limit, int *n_samples); +struct point * +load_samples(int *seed, int *num_samples); + +void +save_samples(struct point *samples, int seed, int n_samples); #endif /* POLYADVENT_POISSON_H */ diff --git a/src/terrain.c b/src/terrain.c @@ -4,6 +4,7 @@ #include "delaunay.h" #include "vec3/vec3.h" #include "perlin.h" +#include "poisson.h" static const float plane_verts[] = { -1,-1,0, -1,1,0, 1,1,0, 1,-1,0 @@ -38,19 +39,14 @@ void deriv(double (*noisefn)(void*, double, double), void* data, double x, void terrain_init(struct terrain *terrain) { - terrain->width = 1; - terrain->height = 1; } void terrain_create(struct terrain *terrain, struct perlin_settings *perlin) { u32 i; - const double size = 200; + const double size = terrain->size; const double hsize = size; int num_verts = hsize*hsize; - static int first = 1; - static float samples_x[40000]; - static float samples_y[40000]; float tmp1[3], tmp2[3]; del_point2d_t *points = calloc(num_verts, sizeof(*points)); float *verts = calloc(num_verts * 3, sizeof(*verts)); @@ -59,20 +55,12 @@ terrain_create(struct terrain *terrain, struct perlin_settings *perlin) { double oy = perlin->oy; // 100 random samples from our noise function - for (i = 0; i < (u32)num_verts; i++) { + for (i = 0; i < (u32)terrain->n_samples; i++) { int n = i*3; double dx, dy, x, y; - if (first) { - x = rand_0to1() * size; - y = rand_0to1() * size; - samples_x[i] = x; - samples_y[i] = y; - } - else { - x = samples_x[i]; - y = samples_y[i]; - } + x = terrain->samples[i].x; + y = terrain->samples[i].y; double z = old_noisy_boi((void*)perlin, ox+x, oy+y); @@ -84,9 +72,7 @@ terrain_create(struct terrain *terrain, struct perlin_settings *perlin) { verts[n+2] = (float)z; } - first = 0; - - delaunay2d_t *del = delaunay2d_from(points, num_verts); + delaunay2d_t *del = delaunay2d_from(points, terrain->n_samples); tri_delaunay2d_t *tri = tri_delaunay2d_from(del); num_verts = tri->num_triangles * 3; diff --git a/src/terrain.h b/src/terrain.h @@ -5,6 +5,8 @@ #include "geometry.h" +struct point; + struct perlin_settings { double freq; int depth; @@ -18,7 +20,9 @@ struct perlin_settings { struct terrain { struct geometry geom; struct perlin_settings settings; - float width, height; + struct point *samples; + int n_samples; + double size; }; void terrain_init(struct terrain *terrain); diff --git a/src/update.c b/src/update.c @@ -93,19 +93,19 @@ void update (struct game *game, u32 dt) { /* terrain_settings.exp = fabs(cos(n)*2.0*cos(n)) + 5.0; */ /* terrain_settings.amplitude = cos(1/n)*2.0*cos(n) + 0.5; */ - terrain_destroy(game->terrain); - terrain_init(game->terrain); - - int t1 = SDL_GetTicks(); - terrain_create(game->terrain, &terrain_settings); - int t2 = SDL_GetTicks(); - last_gen_time = t2 - t1; - - printf("terrain amp %f exp %f freq %f (%d ms)\n", - terrain_settings.amplitude, - terrain_settings.exp, - terrain_settings.freq, - last_gen_time); + /* terrain_destroy(game->terrain); */ + /* terrain_init(game->terrain); */ + + /* int t1 = SDL_GetTicks(); */ + /* terrain_create(game->terrain, &terrain_settings); */ + /* int t2 = SDL_GetTicks(); */ + /* last_gen_time = t2 - t1; */ + + /* printf("terrain amp %f exp %f freq %f (%d ms)\n", */ + /* terrain_settings.amplitude, */ + /* terrain_settings.exp, */ + /* terrain_settings.freq, */ + /* last_gen_time); */ /* res->light_dir[0] = cos(n) * 0.8; */ n += 0.01f;