polyadvent

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

commit 2802876294861f24db52913828c43f2d515bedc1
parent ebcbe5490f652107b9b8cbb15b3b6079e247ab8d
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 29 Apr 2018 20:32:38 -0700

intial scene nodes

Diffstat:
MMakefile | 1+
Msrc/camera.c | 4++--
Msrc/camera.h | 6++++++
Msrc/game.c | 26+++++++++++++-------------
Msrc/game.h | 9++++-----
Asrc/node.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/node.h | 20++++++++++++++++++++
Msrc/render.c | 18+++++++-----------
Msrc/update.c | 30+++++++++++++++++-------------
Msrc/vec3.c | 16++++++++++++++++
Msrc/vec3.h | 4+++-
11 files changed, 148 insertions(+), 45 deletions(-)

diff --git a/Makefile b/Makefile @@ -34,6 +34,7 @@ OBJS += $(SRC)/delaunay.o OBJS += $(SRC)/geometry.o OBJS += $(SRC)/input.o OBJS += $(SRC)/util.o +OBJS += $(SRC)/node.o SRCS=$(OBJS:.o=.c) diff --git a/src/camera.c b/src/camera.c @@ -15,11 +15,11 @@ camera_follow(vec3 *cam_pos, vec3 *target_prev, vec3 *target, mat4 *cam) { cam_pos[0] = target[0]; cam_pos[1] = target[1] - 20; cam_pos[2] = target[2] + 20; - printf("%f %f %f looking at %f %f %f\n", + printf("cam %f %f %f looking at player %f %f %f\n", cam_pos[0], cam_pos[1], cam_pos[2], target[0], target[1], target[2]); - /* look_at(cam_pos, target, V3(0,1,0), cam); */ + look_at(cam_pos, target, V3(0,1,0), cam); /* cam_pos[0] = -target[0]; */ /* cam_pos[1] = -target[1]; */ /* cam_pos[2] = target[2]; */ diff --git a/src/camera.h b/src/camera.h @@ -4,6 +4,12 @@ #include "mat4.h" #include "vec3.h" +#include "node.h" + +struct camera { + float frustum[16]; + struct node node; +}; void camera_follow(vec3 *cam_pos, vec3 *target_prev, vec3 *target, mat4 *cam); diff --git a/src/game.c b/src/game.c @@ -12,33 +12,33 @@ mat4 *cam_init = (float[16]){ void game_init(struct game *game) { mat4 *mvp = game->test_resources.test_mvp; - mat4 *normal = game->test_resources.normal_matrix; - vec3 *camera_pos = game->test_resources.camera_pos; - vec3 *player_pos = game->test_resources.player_pos; - mat4 *camera = game->test_resources.camera; + struct node *camera = &game->test_resources.camera; mat4 *terrain = game->test_resources.terrain_node; - mat4 *player = game->test_resources.player; - mat4 *player_cam = game->test_resources.player_cam; + struct node *player = &game->test_resources.player; mat4 *light_dir = game->test_resources.light_dir; mat4_id(mvp); - mat4_id(normal); - mat4_id(camera); - mat4_id(player_cam); light_dir[0] = 1; light_dir[1] = 1; light_dir[2] = 0.8; - vec3_set(V3(50,0,20), camera_pos); - vec3_set(V3(10,10,0), player_pos); + node_init(player); + node_init(camera); + + /* vec3_all(camera->scale, -1); */ + camera->mirrored = 1; + + node_translate(player, V3(10,10,0)); + node_translate(camera, V3(50,0,20)); + + camera->rot[0] = -45; // move the camera a bit /* mat4_translate(camera, 1.0f, 1.0f, 20.0f, camera); */ /* mat4_copy(cam_init, camera); */ - - mat4_id(player); /* mat4_id(camera_pos); */ + mat4_id(terrain); terrain[M_Z] = 20.0; diff --git a/src/game.h b/src/game.h @@ -4,6 +4,7 @@ #include "buffer.h" #include "input.h" +#include "node.h" #define PLAYER_HEIGHT 1.7 @@ -29,15 +30,13 @@ struct resources { gpu_addr normal; } attributes; + struct node player; + struct node camera; + float terrain_node[MAT4_ELEMS]; float normal_matrix[MAT4_ELEMS]; float test_mvp[MAT4_ELEMS]; float light_dir[3]; - float player_pos[3]; - float camera[MAT4_ELEMS]; - float camera_pos[3]; - float player[MAT4_ELEMS]; - float player_cam[MAT4_ELEMS]; float camera_persp[MAT4_ELEMS]; GLfloat fade_factor; }; diff --git a/src/node.c b/src/node.c @@ -0,0 +1,59 @@ + + +#include "node.h" +#include "mat4.h" +#include "vec3.h" +#include <stdio.h> + +struct node *node_init(struct node *node) { + mat4_id(node->mat); + vec3_all(node->pos, 0); + vec3_all(node->rot, 0); + vec3_all(node->scale, 1.0); + node->children = 0; + node->mirrored = 0; + node->needs_recalc = 0; + return node; +} + +void node_translate(struct node *node, vec3 *p) { + if (vec3_isall(p, 0)) + return; + + printf("translating %f %f %f\n", p[0], p[1], p[2]); + vec3_add(node->pos, p, node->pos); + node->needs_recalc = 1; +} + +int node_recalc(struct node *node) { + float rotate_axis[3]; + + if (!node->needs_recalc) + return 0; + + mat4_id(node->mat); + + node->needs_recalc = 0; + + if (node->scale[0] != 1 || node->scale[1] != 1 || node->scale[2] != 1) + mat4_scale(node->mat, node->scale, node->mat); + + // FIXME: this seems bad? + for (int i = 0; i < 3; ++i) { + if (node->rot[i] != 0) { + rotate_axis[0] = 0; + rotate_axis[1] = 0; + rotate_axis[2] = 0; + rotate_axis[i] = 1; + mat4_rotate(node->mat, node->rot[i], rotate_axis, node->mat); + } + } + + float m = node->mirrored ? -1 : 1; + if (node->pos[0] || node->pos[1] || node->pos[2]) + mat4_translate(node->mat, V3(node->pos[0]*m,node->pos[1]*m,node->pos[2]*m), + node->mat); + + return 1; +} + diff --git a/src/node.h b/src/node.h @@ -0,0 +1,20 @@ + +#ifndef POLYADVENT_NODE_H +#define POLYADVENT_NODE_H + +struct node { + float pos[3]; + float rot[3]; + float scale[3]; + float mat[16]; + int needs_recalc; + int mirrored; // TODO: make camera type + struct node* children; + // TODO quaternion rotation +}; + +int node_recalc(struct node *node); +struct node *node_init(struct node *node); +void node_translate(struct node *node, float *p); + +#endif /* POLYADVENT_NODE_H */ diff --git a/src/render.c b/src/render.c @@ -207,12 +207,10 @@ void render (struct game *game, struct geometry *geom) { mat4 *mvp = res->test_mvp; mat4 *normal = res->normal_matrix; - mat4 *camera = res->camera; mat4 *persp = res->camera_persp; mat4 *light = res->light_dir; - mat4 *player = res->player; - vec3 *camera_pos = res->camera_pos; - vec3 *player_pos = res->player_pos; + struct node *player = &res->player; + struct node *camera = &res->camera; float fade_factor = res->fade_factor; @@ -222,9 +220,9 @@ void render (struct game *game, struct geometry *geom) { /* v3[1] = fade_factor * 1.4f; */ /* mat4_rotate(mvp, 0.004f, v3, mvp); */ /* printf("camera_pos %f %f %f", camera_pos[0], camera_pos[1], camera_pos[2]); */ - mat4_rotate(camera, -45, V3(1,0,0), tmp_matrix); - mat4_translate(tmp_matrix, V3(-camera_pos[0], -camera_pos[1], -camera_pos[2]), tmp_matrix); - mat4_multiply(persp, tmp_matrix, mvp); + node_recalc(camera); + /* mat4_print(camera->mat); */ + mat4_multiply(persp, camera->mat, mvp); /* mat4_multiply(mvp, tmp_matrix, tmp_matrix); */ glUniform3f(res->uniforms.light_dir, light[0], light[1], light[2]); @@ -232,10 +230,8 @@ void render (struct game *game, struct geometry *geom) { glUniform1f(res->uniforms.tscale, res->uniforms.tscale); //player - /* mat4_rotate(camera, -45, V3(1,0,0), tmp_matrix); */ - /* mat4_translate(tmp_matrix, V3(-camera_pos[0], -camera_pos[1], -camera_pos[2]), tmp_matrix); */ - mat4_translate(player, player_pos, tmp_matrix); - mat4_multiply(mvp, tmp_matrix, tmp_matrix); + node_recalc(player); + mat4_multiply(mvp, player->mat, tmp_matrix); glUniformMatrix4fv(res->uniforms.mvp, 1, 0, tmp_matrix); /* mat4_multiply(persp, tmp_matrix, mvp); */ render_cube(res); diff --git a/src/update.c b/src/update.c @@ -9,29 +9,29 @@ #include "poisson.h" #include "uniform.h" -void movement(struct game *game, vec3 *obj) { +void movement(struct game *game, struct node *node) { float amt = 0.25; if (game->input.modifiers & KMOD_SHIFT) amt *= 6; if (game->input.keystates[SDL_SCANCODE_A]) - obj[0] -= amt; + node_translate(node, V3(-amt,0,0)); if (game->input.keystates[SDL_SCANCODE_E]) - obj[2] += amt; + node_translate(node, V3(0,0,amt)); if (game->input.keystates[SDL_SCANCODE_Q]) - obj[2] -= amt; + node_translate(node, V3(0,0,-amt)); if (game->input.keystates[SDL_SCANCODE_D]) - obj[0] += amt; + node_translate(node, V3(amt,0,0)); if (game->input.keystates[SDL_SCANCODE_W]) - obj[1] += amt; + node_translate(node, V3(0,amt,0)); if (game->input.keystates[SDL_SCANCODE_S]) - obj[1] -= amt; + node_translate(node, V3(0,-amt,0)); /* if (obj == game->test_resources.camera) { */ /* if (game->input.keystates[SDL_SCANCODE_UP]) */ @@ -72,7 +72,7 @@ void update (struct game *game, u32 dt) { } if (game->input.modifiers & KMOD_LALT) { - movement(game, res->camera_pos); + movement(game, &res->camera); /* mat4_multiply(res->player, res->ca era, res->player); */ } if (game->input.modifiers & KMOD_LCTRL) { @@ -80,12 +80,16 @@ void update (struct game *game, u32 dt) { /* mat4_multiply(res->player, res->ca era, res->player); */ } else { - movement(game, res->player_pos); - mat4_copy(res->player, player_prev); - res->player_pos[2] = - game->terrain->fn(game->terrain, res->player_pos[0], res->player_pos[1]) + + movement(game, &res->player); + /* mat4_copy(res->player, player_prev); */ + + res->player.pos[2] = + game->terrain->fn(game->terrain, res->player.pos[0], res->player.pos[1]) + PLAYER_HEIGHT; - camera_follow(res->camera_pos, res->player_pos, res->player_pos, res->camera); + res->player.needs_recalc = 1; + + camera_follow(res->camera.pos, res->player.pos, res->player.pos, res->camera.mat); + res->camera.needs_recalc = 1; /* movement(game, res->camera); */ } diff --git a/src/vec3.c b/src/vec3.c @@ -184,6 +184,13 @@ float vec3_distsq(vec3 *vec, vec3 *vec2) { } +vec3 *vec3_all(vec3 *vec, float n) { + vec[0] = n; + vec[1] = n; + vec[2] = n; + return vec; +} + /* vec3 *vec3_unproject(vec3 *vec, mat4 view, mat4 proj, vec4_t viewport, vec3 *dest) { */ /* if (!dest) { dest = vec; } */ @@ -207,3 +214,12 @@ float vec3_distsq(vec3 *vec, vec3 *vec2) { /* return dest; */ /* } */ + +int vec3_isall(vec3 *vec, float n) { + for (int i = 0; i < 3; ++i) { + if (vec[i] != n) + return 0; + } + + return 1; +} diff --git a/src/vec3.h b/src/vec3.h @@ -17,4 +17,6 @@ float *vec3_set(vec3 *vec, vec3 *dest); float vec3_length(vec3 *vec); float vec3_lengthsq(vec3 *vec); float vec3_dot(vec3 *vec, vec3 *vec2); - +int vec3_isall(vec3 *vec, float n); +vec3 *vec3_all(vec3 *vec, float n); +vec3 *vec3_add(vec3 *vec, vec3 *vec2, vec3 *dest);