polyadvent

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

commit 962a75b0fe4d6a27d16f12cf65457cb1524573e6
parent 7c8f16ec21fce0f3030ca4a9f1d624215c5a0dae
Author: William Casarin <jb55@jb55.com>
Date:   Tue,  1 May 2018 14:44:31 -0700

terrain cleanup

Diffstat:
Msrc/game.c | 22+++++++++++++++++++++-
Msrc/game.h | 4++--
Msrc/main.c | 52+---------------------------------------------------
Msrc/terrain.c | 2++
Msrc/update.c | 121+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/window.c | 2+-
6 files changed, 99 insertions(+), 104 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -1,6 +1,7 @@ #include "mat_util.h" #include "game.h" +#include "terrain.h" mat4 *cam_init = (float[16]){ 0.955761, 0.228018, -0.185425, 0.000000, @@ -23,8 +24,27 @@ void game_init(struct game *game) { struct node *camera = &game->test_resources.camera; struct node *player = &game->test_resources.player; struct node *terrain_node = &game->test_resources.terrain_node; + struct terrain *terrain = &game->terrain; mat4 *light_dir = game->test_resources.light_dir; + const double size = 1000; + const double pdist = 1.7; + + terrain->settings = (struct perlin_settings){ + .depth = 1, + .freq = 0.02, + .o1 = 2.0, .o1s = 0.5, + .o2 = 4.0, .o2s = 0.25, + .amplitude = 1.0, + .ox = 0, + .oy = 0, + .exp = 6.3 + }; + + terrain_init(terrain); + terrain->size = size; + + mat4_id(mvp); light_dir[0] = 1; @@ -52,7 +72,7 @@ void game_init(struct game *game) { /* vec3_all(camera->scale, -1); */ /* camera->mirrored = 1; */ - node_translate(player, V3(20,20,0)); + node_translate(player, V3(terrain->size/2.,terrain->size/2.,0)); node_translate(camera, V3(0,-30,20)); /* node_recalc(camera); */ diff --git a/src/game.h b/src/game.h @@ -5,6 +5,7 @@ #include "buffer.h" #include "input.h" #include "node.h" +#include "terrain.h" #define PLAYER_HEIGHT 1.7 @@ -41,12 +42,11 @@ struct resources { GLfloat fade_factor; }; - struct game { int counter; struct resources test_resources; struct input input; - struct terrain *terrain; + struct terrain terrain; }; void game_init(struct game *game); diff --git a/src/main.c b/src/main.c @@ -28,7 +28,6 @@ int main(void) struct game game; struct slab slab; struct geometry slab_geom; - struct terrain terrain; size_t length; @@ -43,55 +42,6 @@ int main(void) SDL_GL_CreateContext(window); init_gl(&game.test_resources, width, height); game_init(&game); - game.terrain = &terrain; - - const double size = 1000; - const double pdist = 1.7; - const double scale = 0.01; - /* printf("samples seed %d\n", seed); */ - const int n_samples = - (size * size) * scale*scale; - struct point *samples = uniform_samples(n_samples, size); - terrain.n_samples = n_samples; - - /* 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); */ - - terrain.settings = (struct perlin_settings){ - .depth = 1, - .freq = 0.02, - .o1 = 2.0, .o1s = 0.5, - .o2 = 4.0, .o2s = 0.25, - .amplitude = 1.0, - .ox = 0, - .oy = 0, - .exp = 6.3, - .scale = 1.0 - }; - - terrain_init(&terrain); - terrain.size = size; - terrain.samples = samples; - terrain_create(&terrain); - - /* slab_buffer = file_contents(SLAB("test.slab"), &length); */ - /* slab_parse(&slab, slab_buffer); */ - /* slab_show(&slab); */ - /* slab_alloc_arrays(&slab, &slab_geom, NULL); */ - /* slab_arrays(&slab, */ - /* slab_geom.vertices, */ - /* slab_geom.normals, */ - /* slab_geom.indices, */ - /* &slab_geom.num_elements); */ - - /* make_buffer_geometry(&slab_geom); */ - // mesh it -> load into vbo - - /* Loop until the user closes the window */ - - u32 last = SDL_GetTicks(); while (1) { @@ -100,7 +50,7 @@ int main(void) update(&game, ticks-last); last = ticks; - render(&game, &terrain.geom); + render(&game, &game.terrain.geom); /* Swap front and back buffers */ SDL_GL_SwapWindow(window); diff --git a/src/terrain.c b/src/terrain.c @@ -42,6 +42,8 @@ void deriv(double (*noisefn)(void*, double, double), void* data, double x, void terrain_init(struct terrain *terrain) { + terrain->samples = NULL; + terrain->n_samples = 0; } double offset_fn(struct terrain* terrain, double x, double y) { diff --git a/src/update.c b/src/update.c @@ -50,24 +50,85 @@ static void movement(struct game *game, struct node *node) { mat4_print(node->mat); } +void update_terrain(struct game *game) { + static int first = 1; + static float last_scale = -1.0; + + struct perlin_settings *ts = &game->terrain.settings; + struct node *tnode = &game->test_resources.terrain_node; + struct terrain *terrain = &game->terrain; + + double ox = tnode->pos[0]; + double oy = tnode->pos[1]; + + printf("updating terrain\n"); + + if (first) { + terrain_init(terrain); + /* ts->ox = rand_0to1() * 1000.0; */ + /* ts->oy = rand_0to1() * 1000.0; */ + first = 0; + } + + for (int i = 0; i < 2; ++i) + tnode->pos[i] = max(tnode->pos[i], 0); + + double scale = tnode->pos[2] * 0.01; + if (scale == 0) scale = 1.0; + + printf("terrain %f %f %f\n", tnode->pos[0], tnode->pos[1], tnode->pos[2]); + + ts->scale = scale; + + /* ts.o1s = fabs(sin(1/n) * 0.25); */ + /* ts.o1 = fabs(cos(n*0.2) * 0.5); */ + /* ts.o2s = fabs(cos(n+2) * 0.5); */ + /* ts.o2 = fabs(sin(n*0.02) * 2); */ + ts->freq = scale * 0.15; + ts->amplitude = 3/scale; + + terrain_destroy(&game->terrain); + + + /* const double pdist = min(5.0, max(1.1, 1.0/scale*1.4)); */ + + /* printf("pdist %f\n", pdist); */ + + if (last_scale == -1 || fabs(scale - last_scale) > 0.00001) { + printf("generating new samples\n"); + + if (terrain->samples) + free(terrain->samples); + + int n_samples = + (terrain->size * game->terrain.size) * scale*scale*scale; + + struct point *samples = + uniform_samples(n_samples, game->terrain.size); + + terrain->samples = samples; + terrain->n_samples = n_samples; + } + + last_scale = scale; + terrain_create(&game->terrain); +} + void update (struct game *game, u32 dt) { static int passed = 0; + static double last_ox, last_oy, last_oz; static int last_gen_time = 50; static float n = 1; - static float nn = 1; static int first = 1; - static double last_ox, last_oy, last_oz; struct resources *res = &game->test_resources; static int stopped = 0; - struct perlin_settings *ts = &game->terrain->settings; - float player_prev[MAT4_ELEMS]; + struct perlin_settings *ts = &game->terrain.settings; struct node *tnode = &game->test_resources.terrain_node; struct node *root = &game->test_resources.root; float *light = res->light_dir; if (first) { - ts->ox = rand_0to1() * 1000.0; - ts->oy = rand_0to1() * 1000.0; + update_terrain(game); first = 0; } @@ -86,10 +147,9 @@ void update (struct game *game, u32 dt) { movement(game, &res->player); if (!vec3_eq(res->player.pos, last_pos, 0.0001)) { - printf("else\n"); res->player.pos[2] = - game->terrain->fn(game->terrain, res->player.pos[0], res->player.pos[1]) + + game->terrain.fn(&game->terrain, res->player.pos[0], res->player.pos[1]) + PLAYER_HEIGHT; node_recalc(&res->camera); @@ -100,7 +160,7 @@ void update (struct game *game, u32 dt) { node_recalc(&res->camera); vec3 *camera_world = node_world(&res->camera); float cam_terrain_z = - game->terrain->fn(game->terrain, camera_world[0], camera_world[1]); + game->terrain.fn(&game->terrain, camera_world[0], camera_world[1]); if (camera_world[2] < cam_terrain_z) camera_world[2] = cam_terrain_z + 10.0; @@ -140,48 +200,11 @@ void update (struct game *game, u32 dt) { bool changed = last_ox != ox || last_oy != oy || last_oz != tnode->pos[2]; if (!stopped && changed) { - for (int i = 0; i < 2; ++i) - tnode->pos[i] = max(tnode->pos[i], 0); - - last_oz = tnode->pos[2] = max(tnode->pos[2], 5.0); - - double scale = tnode->pos[2] * 0.01; - if (scale == 0) scale = 1.0; - - printf("terrain %f %f %f\n", tnode->pos[0], tnode->pos[1], tnode->pos[2]); - + int t1 = SDL_GetTicks(); + update_terrain(game); last_ox = ts->ox = ox; last_oy = ts->oy = oy; - - ts->scale = scale; - /* ts.o1s = fabs(sin(1/n) * 0.25); */ - /* ts.o1 = fabs(cos(n*0.2) * 0.5); */ - /* ts.o2s = fabs(cos(n+2) * 0.5); */ - /* ts.o2 = fabs(sin(n*0.02) * 2); */ - ts->freq = scale * 0.15; - - ts->amplitude = 3/scale; - - terrain_destroy(game->terrain); - terrain_init(game->terrain); - - int t1 = SDL_GetTicks(); - free(game->terrain->samples); - - /* const double pdist = min(5.0, max(1.1, 1.0/scale*1.4)); */ - - /* printf("pdist %f\n", pdist); */ - - int n_samples = - (game->terrain->size * game->terrain->size) * scale*scale*scale; - - struct point *samples = - uniform_samples(n_samples, game->terrain->size); - - game->terrain->samples = samples; - game->terrain->n_samples = n_samples; - - terrain_create(game->terrain); + last_oz = tnode->pos[2] = max(tnode->pos[2], 5.0); int t2 = SDL_GetTicks(); last_gen_time = t2 - t1; diff --git a/src/window.c b/src/window.c @@ -9,7 +9,7 @@ void handle_resize(float *camera, int width, int height) { printf("resizing %d %d\n", width, height); glViewport( 0, 0, width, height ); - mat4_perspective(90 /* fov */, (float)width / height, 1, 2000, camera); + mat4_perspective(90 /* fov */, (float)width / height, 1, 4000, camera); /* glMatrixMode( GL_PROJECTION ); //Switch to setting the camera perspective */ /* Set the camera perspective */