polyadvent

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

commit ebcbe5490f652107b9b8cbb15b3b6079e247ab8d
parent 9576914fa6933bb5e8adcf4613a56bdf7daf19ab
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 29 Apr 2018 18:57:46 -0700

the progress is real

Diffstat:
MMakefile | 23++++++++++++-----------
Metc/shaders/test.v.glsl | 5++---
Msrc/camera.c | 20++++++++++++++++----
Msrc/camera.h | 14++++++++++----
Msrc/common.h | 3---
Msrc/game.c | 34++++++++++++++++++++--------------
Msrc/game.h | 2++
Msrc/mat4.c | 8++++++--
Msrc/mat4.h | 6+++++-
Msrc/render.c | 39++++++++++++++++++++++++---------------
Msrc/terrain.c | 2+-
Msrc/update.c | 59+++++++++++++++++++++++++++++++----------------------------
Msrc/util.c | 46+++++++++++++++++++++++++++++++++++++++++-----
Msrc/util.h | 5++++-
Msrc/vec3.c | 16++++++++--------
Msrc/vec3.h | 8++++++--
Msrc/window.c | 4++--
17 files changed, 190 insertions(+), 104 deletions(-)

diff --git a/Makefile b/Makefile @@ -13,16 +13,17 @@ SRC=src OBJS = $(SRC)/window.o OBJS += $(SRC)/buffer.o -#OBJS += $(SRC)/camera.o +OBJS += $(SRC)/camera.o OBJS += $(SRC)/debug.o OBJS += $(SRC)/event.o OBJS += $(SRC)/file.o OBJS += $(SRC)/perlin.o +OBJS += $(SRC)/main.o OBJS += $(SRC)/poisson.o OBJS += $(SRC)/uniform.o OBJS += $(SRC)/game.o -OBJS += $(SRC)/mat4/mat4.o -OBJS += $(SRC)/vec3/vec3.o +OBJS += $(SRC)/mat4.o +OBJS += $(SRC)/vec3.o OBJS += $(SRC)/render.o OBJS += $(SRC)/shader.o OBJS += $(SRC)/update.o @@ -36,18 +37,18 @@ OBJS += $(SRC)/util.o SRCS=$(OBJS:.o=.c) -include $(OBJS:.o=.d) all: $(BIN) -src/%.d: src/%.c - @rm -f $@; \ - $(CC) -MM $(CFLAGS) $< > $@ +include $(OBJS:.o=.d) -%.o: %.c %.h - $(CC) $(CFLAGS) -fPIC $(DEFS) -c $< -o $@ +%.d: %.c + @rm -f $@; \ + $(CC) -MM $(CFLAGS) $< > $@.$$$$; \ + sed 's,\(.*\)\.o[ :]*,src/\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ -$(BIN): $(SRC)/main.o $(OBJS) +$(BIN): $(OBJS) $(CC) $(CFLAGS) $(DEFS) $^ $(LDFLAGS) -o $@ install: $(BIN) @@ -61,6 +62,6 @@ TAGS: etags $(SRCS) clean: - rm -f src/main.o $(OBJS) $(SHLIB) $(BIN) *.d + rm -f src/main.o $(OBJS) $(SHLIB) $(BIN) $(SRC)/*.d* .PHONY: TAGS diff --git a/etc/shaders/test.v.glsl b/etc/shaders/test.v.glsl @@ -5,7 +5,6 @@ in vec3 normal; uniform mat4 local; uniform mat4 mvp; -uniform mat4 normal_matrix; flat out float v_dot; flat out vec3 v_norm; @@ -15,8 +14,8 @@ uniform vec3 light_dir; void main() { - vec4 trans_normal = normal_matrix * vec4(normal, 1); - gl_Position = mvp * local * vec4(position.xyz, 1.0); + vec4 trans_normal = vec4(normal, 1); + gl_Position = mvp * vec4(position.xyz, 1.0); v_dot = dot(trans_normal, vec4(light_dir, 0)); if (position.z <= 0.1) diff --git a/src/camera.c b/src/camera.c @@ -1,14 +1,26 @@ -#include "mat4/mat4.h" #include "camera.h" +#include "util.h" +#include "mat4.h" +#include "vec3.h" // should probably be a scene node struct camera *camera_init(struct camera *cam) { - return NULL; + return 0; } void -camera_follow(mat4 *cam, mat4 *target_prev, mat4 *target) { - cam +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", + 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); */ + /* 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 @@ -1,5 +1,11 @@ -struct camera { - float frustum[16]; - float world[16]; -}; +#ifndef POLYADVENT_CAMERA_H +#define POLYADVENT_CAMERA_H + +#include "mat4.h" +#include "vec3.h" + +void +camera_follow(vec3 *cam_pos, vec3 *target_prev, vec3 *target, mat4 *cam); + +#endif /* POLYADVENT_CAMERA_H */ diff --git a/src/common.h b/src/common.h @@ -5,9 +5,6 @@ #include <stdbool.h> #define MAT3_ELEMS 9 -#define M_X 12 -#define M_Y 13 -#define M_Z 14 #define MAT4_ELEMS 16 #define SLAB(f) "etc/slab/" f diff --git a/src/game.c b/src/game.c @@ -1,6 +1,6 @@ -#include "mat4/mat4.h" -#include "vec3/vec3.h" +#include "mat4.h" +#include "vec3.h" #include "game.h" mat4 *cam_init = (float[16]){ @@ -11,33 +11,39 @@ mat4 *cam_init = (float[16]){ }; void game_init(struct game *game) { - float *mvp = game->test_resources.test_mvp; - float *normal = game->test_resources.normal_matrix; - float *camera = game->test_resources.camera; - float *terrain = game->test_resources.terrain_node; - float *player = game->test_resources.player; - float *player_cam = game->test_resources.player_cam; - float *light_dir = game->test_resources.light_dir; + 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; + mat4 *terrain = game->test_resources.terrain_node; + mat4 *player = game->test_resources.player; + mat4 *player_cam = game->test_resources.player_cam; + mat4 *light_dir = game->test_resources.light_dir; mat4_id(mvp); mat4_id(normal); mat4_id(camera); mat4_id(player_cam); - light_dir[0] = 0.5; + light_dir[0] = 1; light_dir[1] = 1; - light_dir[2] = 0; + light_dir[2] = 0.8; + + vec3_set(V3(50,0,20), camera_pos); + vec3_set(V3(10,10,0), player_pos); // move the camera a bit /* mat4_translate(camera, 1.0f, 1.0f, 20.0f, camera); */ - mat4_copy(cam_init, camera); + /* mat4_copy(cam_init, camera); */ mat4_id(player); + /* mat4_id(camera_pos); */ mat4_id(terrain); - terrain[14] = 20.0; + terrain[M_Z] = 20.0; - mat4_scale(player, V3(0.36,0.36,PLAYER_HEIGHT), player); + /* mat4_scale(player, V3(0.36,0.36,PLAYER_HEIGHT), player); */ input_init(&game->input); } diff --git a/src/game.h b/src/game.h @@ -33,7 +33,9 @@ struct resources { 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]; diff --git a/src/mat4.c b/src/mat4.c @@ -3,7 +3,7 @@ #include <math.h> #include <stdio.h> #include <string.h> -#include "../vec3/vec3.h" +#include "vec3.h" #define PI 3.14159265f @@ -113,7 +113,11 @@ mat4 *mat4_frustum (float left, float right, float bottom, * Returns: * dest if specified, mat otherwise */ -mat4 *mat4_translate (mat4 *mat, float x, float y, float z, mat4 *dest) { +mat4 *mat4_translate (mat4 *mat, float *v3, mat4 *dest) { + const float x = v3[0]; + const float y = v3[1]; + const float z = v3[2]; + if(!dest || mat == dest) { mat[12] = mat[0]*x + mat[4]*y + mat[8]*z + mat[12]; mat[13] = mat[1]*x + mat[5]*y + mat[9]*z + mat[13]; diff --git a/src/mat4.h b/src/mat4.h @@ -1,6 +1,10 @@ typedef float mat4; +#define M_X 12 +#define M_Y 13 +#define M_Z 14 + mat4 *mat4_scale(mat4 *a, float v[3], mat4 *out); mat4 *mat4_frustum (float left, float right, float bottom, float top, float near, float far, mat4 *dest); @@ -8,7 +12,7 @@ mat4 *mat4_frustum (float left, float right, float bottom, mat4 *mat4_perspective(float fov, float aspect, float near, float far, mat4 *dest); -mat4 *mat4_translate (mat4 *mat, float x, float y, float z, mat4 *dest); +mat4 *mat4_translate (mat4 *mat, float *vec3, mat4 *dest); mat4 *mat4_transpose(mat4 *src, mat4 *dest); mat4 *mat4_inverse(mat4 *src, mat4 *dest); mat4 *mat4_copy(const mat4 *src, mat4 *dst); diff --git a/src/render.c b/src/render.c @@ -5,8 +5,8 @@ #include "gl.h" #include "game.h" -#include "mat4/mat4.h" -#include "vec3/vec3.h" +#include "mat4.h" +#include "vec3.h" #include "buffer.h" #include "buffer_geometry.h" #include "shader.h" @@ -205,12 +205,14 @@ void render (struct game *game, struct geometry *geom) { mat4_id(id); struct resources *res = &game->test_resources; - float *mvp = res->test_mvp; - float *normal = res->normal_matrix; - float *camera = res->camera; - float *persp = res->camera_persp; - float *light = res->light_dir; - float *player = res->player; + 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; float fade_factor = res->fade_factor; @@ -219,20 +221,27 @@ void render (struct game *game, struct geometry *geom) { /* static float v3[] = { 1, 1, 0 }; */ /* v3[1] = fade_factor * 1.4f; */ /* mat4_rotate(mvp, 0.004f, v3, mvp); */ - mat4_multiply(persp, camera, tmp_matrix); - mat4_multiply(tmp_matrix, mvp, tmp_matrix); - - recalc_normals(res->uniforms.normal_matrix, tmp_matrix, normal); + /* 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); + /* mat4_multiply(mvp, tmp_matrix, tmp_matrix); */ glUniform3f(res->uniforms.light_dir, light[0], light[1], light[2]); glUniform1f(res->uniforms.fade_factor, fade_factor); glUniform1f(res->uniforms.tscale, res->uniforms.tscale); - glUniformMatrix4fv(res->uniforms.mvp, 1, 0, tmp_matrix); - glUniformMatrix4fv(res->uniforms.local, 1, 0, player); + //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); + glUniformMatrix4fv(res->uniforms.mvp, 1, 0, tmp_matrix); + /* mat4_multiply(persp, tmp_matrix, mvp); */ render_cube(res); - glUniformMatrix4fv(res->uniforms.local, 1, 0, id); + // terrain + glUniformMatrix4fv(res->uniforms.mvp, 1, 0, mvp); render_geom(res, geom, GL_TRIANGLES); /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */ /* render_geom(res, geom, GL_TRIANGLES); */ diff --git a/src/terrain.c b/src/terrain.c @@ -2,7 +2,7 @@ #include "terrain.h" #include "util.h" #include "delaunay.h" -#include "vec3/vec3.h" +#include "vec3.h" #include "perlin.h" #include "poisson.h" diff --git a/src/update.c b/src/update.c @@ -3,62 +3,65 @@ #include "update.h" #include "terrain.h" #include "util.h" -#include "mat4/mat4.h" -#include "vec3/vec3.h" +#include "mat4.h" +#include "vec3.h" +#include "camera.h" #include "poisson.h" #include "uniform.h" -void movement(struct game *game, float *obj) { +void movement(struct game *game, vec3 *obj) { float amt = 0.25; if (game->input.modifiers & KMOD_SHIFT) amt *= 6; if (game->input.keystates[SDL_SCANCODE_A]) - mat4_translate(obj, -amt, 0, 0, obj); + obj[0] -= amt; if (game->input.keystates[SDL_SCANCODE_E]) - mat4_translate(obj, 0, 0, amt, obj); + obj[2] += amt; if (game->input.keystates[SDL_SCANCODE_Q]) - mat4_translate(obj, 0, 0, -amt, obj); + obj[2] -= amt; if (game->input.keystates[SDL_SCANCODE_D]) - mat4_translate(obj, amt, 0, 0, obj); + obj[0] += amt; if (game->input.keystates[SDL_SCANCODE_W]) - mat4_translate(obj, 0, amt, 0, obj); + obj[1] += amt; if (game->input.keystates[SDL_SCANCODE_S]) - mat4_translate(obj, 0, -amt, 0, obj); + obj[1] -= amt; - if (obj == game->test_resources.camera) { - if (game->input.keystates[SDL_SCANCODE_UP]) - mat4_rotate(obj, amt*0.1, (float[]){1,0,0}, obj); + /* if (obj == game->test_resources.camera) { */ + /* if (game->input.keystates[SDL_SCANCODE_UP]) */ + /* mat4_rotate(obj, amt*0.1, (float[]){1,0,0}, obj); */ - if (game->input.keystates[SDL_SCANCODE_RIGHT]) - mat4_rotate(obj, amt*0.1, (float[]){0,1,0}, obj); + /* if (game->input.keystates[SDL_SCANCODE_RIGHT]) */ + /* mat4_rotate(obj, amt*0.1, (float[]){0,1,0}, obj); */ - if (game->input.keystates[SDL_SCANCODE_LEFT]) - mat4_rotate(obj, -(amt*0.1), (float[]){0,1,0}, obj); + /* if (game->input.keystates[SDL_SCANCODE_LEFT]) */ + /* mat4_rotate(obj, -(amt*0.1), (float[]){0,1,0}, obj); */ - if (game->input.keystates[SDL_SCANCODE_DOWN]) - mat4_rotate(obj, -(amt*0.1), (float[]){1,0,0}, obj); - } + /* if (game->input.keystates[SDL_SCANCODE_DOWN]) */ + /* mat4_rotate(obj, -(amt*0.1), (float[]){1,0,0}, obj); */ + /* } */ - if (game->input.keystates[SDL_SCANCODE_P]) - mat4_print(obj); + /* if (game->input.keystates[SDL_SCANCODE_P]) */ + /* mat4_print(obj); */ } void update (struct game *game, u32 dt) { static int passed = 0; 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]; float *tnode = game->test_resources.terrain_node; float *light = res->light_dir; @@ -69,19 +72,20 @@ void update (struct game *game, u32 dt) { } if (game->input.modifiers & KMOD_LALT) { - movement(game, res->camera); + movement(game, res->camera_pos); /* mat4_multiply(res->player, res->ca era, res->player); */ } if (game->input.modifiers & KMOD_LCTRL) { - movement(game, res->terrain_node); + /* movement(game, res->terrain_node); */ /* mat4_multiply(res->player, res->ca era, res->player); */ } else { - movement(game, res->player); - res->player[14] = - game->terrain->fn(game->terrain, res->player[M_X], res->player[M_Y]) + + 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]) + PLAYER_HEIGHT; - camera_follow(camera, player); + camera_follow(res->camera_pos, res->player_pos, res->player_pos, res->camera); /* movement(game, res->camera); */ } @@ -167,7 +171,6 @@ void update (struct game *game, u32 dt) { n += 0.01f; } - /* res->light_dir[0] = cos(n) * 0.8; */ } } diff --git a/src/util.c b/src/util.c @@ -1,6 +1,7 @@ #include "util.h" -#include "vec3/vec3.h" +#include "vec3.h" +#include "mat4.h" #include <stdlib.h> int clampi(int a, int mina, int maxa) { @@ -44,10 +45,45 @@ double rand_0to1() { return (double) rand() / RAND_MAX; } -mat4 *look_at(vec3 *eye, vec3 *target, vec3 *up) { - float[3] z; +void look_at(vec3 *eye, vec3 *target, vec3 *up, mat4 *dest) { + float z[3], x[3], y[3]; + vec3_subtract(eye, target, z); - if (vec3_lengthsq(z) == 0) - z[V_Z] = 0; + + /* if (vec3_lengthsq(z) == 0) */ + /* z[2] = 0; */ + + vec3_normalize(z, z); + vec3_cross(up, z, x); + + if (vec3_lengthsq(x) == 0) { + // up and z are parallel + + if (fabs(up[2]) == 1.0) + z[0] += 0.0001; + else + z[2] += 0.0001; + + vec3_normalize(z, z); + vec3_cross(up, z, x); + } + + vec3_normalize(x, x); + vec3_cross(z, x, y); + + dest[0] = x[0]; + dest[1] = x[1]; + dest[2] = x[2]; + /* dest[3] = -vec3_dot(x, eye); */ + + dest[4] = y[0]; + dest[5] = y[1]; + dest[6] = y[2]; + /* dest[7] = -vec3_dot(y, eye); */ + + dest[8] = z[0]; + dest[9] = z[1]; + dest[10] = z[2]; + /* dest[11] = -vec3_dot(z, eye); */ } diff --git a/src/util.h b/src/util.h @@ -3,6 +3,8 @@ #define PA_UTIL_H #include "gl.h" +#include "vec3.h" +#include "mat4.h" #include <assert.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -12,7 +14,8 @@ int clampi(int a, int mina, int maxa); double clamp(double a, double mina, double maxa); double max(double a, double b); double min(double a, double b); -mat4 *look_at(vec3 *eye, vec3 *target, vec3 *up); + +void look_at(vec3 *eye, vec3 *target, vec3 *up, mat4 *dest); double rand_0to1(); diff --git a/src/vec3.c b/src/vec3.c @@ -2,7 +2,7 @@ #include <stdlib.h> #include <math.h> -#include "mat4/mat4.h" +#include "mat4.h" #include "vec3.h" vec3 *vec3_create(vec3 *vec) { @@ -130,9 +130,13 @@ vec3 *vec3_cross (vec3 *vec, vec3 *vec2, vec3 *dest) { return dest; } +float vec3_lengthsq(vec3 *vec) { + float x = vec[0], y = vec[1], z = vec[2]; + return x * x + y * y + z * z; +} + float vec3_length(vec3 *vec) { - float x = vec[0], y = vec[1], z = vec[2]; - return sqrt(x * x + y * y + z * z); + return sqrt(vec3_lengthsq(vec)); } float vec3_dot(vec3 *vec, vec3 *vec2) { @@ -171,7 +175,7 @@ vec3 *vec3_lerp(vec3 *vec, vec3 *vec2, float lerp, vec3 *dest) { return dest; } -float vec3_lengthsq(vec3 *vec, vec3 *vec) { +float vec3_distsq(vec3 *vec, vec3 *vec2) { float x = vec2[0] - vec[0], y = vec2[1] - vec[1], z = vec2[2] - vec[2]; @@ -180,10 +184,6 @@ float vec3_lengthsq(vec3 *vec, vec3 *vec) { } -float vec3_length(vec3 *vec, vec3 *vec2) { - return sqrt(vec3_lengthsq(vec, vec2)); -} - /* vec3 *vec3_unproject(vec3 *vec, mat4 view, mat4 proj, vec4_t viewport, vec3 *dest) { */ /* if (!dest) { dest = vec; } */ diff --git a/src/vec3.h b/src/vec3.h @@ -11,6 +11,10 @@ vec3 *vec3_cross (vec3 *vec, vec3 *vec2, vec3 *dest); vec3 *vec3_multiply(vec3 *vec, vec3 *vec2, vec3 *dest); vec3 *vec3_scale(vec3 *vec, float val, vec3 *dest); vec3 *vec3_normalize(vec3 *vec, vec3 *dest); -vec3 *vec3_length(vec3 *vec, vec3 *dest); -vec3 *vec3_lengthsq(vec3 *vec, vec3 *dest); +float vec3_dist(vec3 *vec, vec3 *vec2); +float vec3_distsq(vec3 *vec, vec3 *vec2); +float *vec3_set(vec3 *vec, vec3 *dest); +float vec3_length(vec3 *vec); +float vec3_lengthsq(vec3 *vec); +float vec3_dot(vec3 *vec, vec3 *vec2); diff --git a/src/window.c b/src/window.c @@ -1,7 +1,7 @@ #include "gl.h" -#include "mat4/mat4.h" +#include "mat4.h" #include "window.h" @@ -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(100 /* fov */, (float)width / height, 1, 1000, camera); + mat4_perspective(90 /* fov */, (float)width / height, 1, 1000, camera); /* glMatrixMode( GL_PROJECTION ); //Switch to setting the camera perspective */ /* Set the camera perspective */