polyadvent

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

commit 47be43a13b1bfbb5bfb25fe77ea34b9f77ad210a
parent fcb7afe358b12a506655246e9f244eb98bde088e
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 22 Apr 2018 13:34:46 -0700

VERY NICE

Diffstat:
M.gitignore | 1+
MMakefile | 8++++++++
Metc/shaders/test.v.glsl | 4++--
Msrc/common.h | 2++
Msrc/event.c | 10++++++++--
Msrc/game.c | 20++++++++++++++++----
Msrc/game.h | 7+++++--
Msrc/geometry.c | 3++-
Msrc/geometry.h | 2+-
Asrc/input.c | 12++++++++++++
Asrc/input.h | 24++++++++++++++++++++++++
Msrc/main.c | 6+++---
Msrc/mat4/mat4.c | 12++++++++++++
Msrc/mat4/mat4.h | 1+
Msrc/render.c | 22++++++++++++----------
Msrc/terrain.c | 30++++++++++++++++--------------
Msrc/update.c | 56+++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/update.h | 2+-
Msrc/util.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Msrc/util.h | 2++
Msrc/window.c | 8+++++---
21 files changed, 227 insertions(+), 50 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,3 +1,4 @@ *.o *.so polyadvent +/TAGS diff --git a/Makefile b/Makefile @@ -26,8 +26,11 @@ OBJS += $(SRC)/terrain.o OBJS += $(SRC)/slab.o OBJS += $(SRC)/slab_geom.o OBJS += $(SRC)/geometry.o +OBJS += $(SRC)/input.o OBJS += $(SRC)/util.o +SRCS=$(OBJS:.o=.c) + all: $(BIN) %.o: %.c %.h @@ -43,5 +46,10 @@ install: $(BIN) nixbuild: nix-shell shell.nix --command 'make -j4' +TAGS: + etags $(SRCS) + clean: rm -f src/main.o $(OBJS) $(SHLIB) $(BIN) + +.PHONY: TAGS diff --git a/etc/shaders/test.v.glsl b/etc/shaders/test.v.glsl @@ -12,6 +12,6 @@ uniform vec3 light_dir; void main() { vec4 trans_normal = normal_matrix * vec4(normal, 1); - gl_Position = mvp * vec4(position.xyz / 10., 1.0); - v_dot = max(dot(trans_normal.xyz, light_dir), 0.4); + gl_Position = mvp * vec4(position.xyz, 1.0); + v_dot = max(dot(trans_normal.xyz, light_dir), 0.8); } diff --git a/src/common.h b/src/common.h @@ -2,6 +2,8 @@ #ifndef POLYADVENT_COMMON_H #define POLYADVENT_COMMON_H +#include <stdbool.h> + #define MAT3_ELEMS 9 #define MAT4_ELEMS 16 diff --git a/src/event.c b/src/event.c @@ -1,14 +1,20 @@ #include "event.h" #include "window.h" +#include "input.h" +#include "game.h" void process_events() { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { - case SDL_WINDOWEVENT_RESIZED: - handle_resize(event.window.data1, event.window.data2); + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_RESIZED: + handle_resize(event.window.data1, event.window.data2); + break; + } break; case SDL_QUIT: SDL_Quit(); diff --git a/src/game.c b/src/game.c @@ -2,12 +2,24 @@ #include "mat4/mat4.h" #include "game.h" -void init_game(struct game_state *game) { - float *mvp = &game->test_resources.test_mvp[0]; - float *normal = &game->test_resources.normal_matrix[0]; +mat4 *cam_init = (float[16]){ + 1.000000, 0.000000, 0.000000, 0.000000, + 0.000000, 0.674875, -0.737931, 0.000000, + 0.000000, 0.737931, 0.674875, 0.000000, + -0.100000,-0.131862, -6.496247, 1.000000 +}; + +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; mat4_id(mvp); mat4_id(normal); + mat4_id(camera); // move the camera a bit - mat4_translate(mvp, -1.0f, -1.0f, -10.0f, mvp); + /* mat4_translate(camera, -1.0f, -1.0f, -7.0f, camera); */ + mat4_copy(cam_init, camera); + + input_init(&game->input); } diff --git a/src/game.h b/src/game.h @@ -3,6 +3,7 @@ #define PA_GAME_H #include "buffer.h" +#include "input.h" /* * Global data used by our render callback: @@ -27,15 +28,17 @@ struct resources { float normal_matrix[MAT4_ELEMS]; float test_mvp[MAT4_ELEMS]; float camera[MAT4_ELEMS]; + float camera_persp[MAT4_ELEMS]; GLfloat fade_factor; }; -struct game_state { +struct game { int counter; struct resources test_resources; + struct input input; }; -void init_game(struct game_state *game); +void game_init(struct game *game); #endif /* PA_GAME_H */ diff --git a/src/geometry.c b/src/geometry.c @@ -9,6 +9,7 @@ make_buffer_geometry(struct geometry *geom) { assert(geom->vertices); assert(geom->normals); assert(geom->indices); + assert(geom->num_indices >= 1); printf("making vertex buffer\n"); make_vertex_buffer( @@ -32,7 +33,7 @@ make_buffer_geometry(struct geometry *geom) { make_index_buffer( GL_ELEMENT_ARRAY_BUFFER, geom->indices, - geom->num_elements * (int)sizeof(u32), + geom->num_indices * (int)sizeof(u32), &geom->buffer.index_buffer ); } diff --git a/src/geometry.h b/src/geometry.h @@ -13,7 +13,7 @@ struct buffer_geometry { struct geometry { struct buffer_geometry buffer; - int num_elements; + int num_indices; int num_verts; float *vertices; float *normals; diff --git a/src/input.c b/src/input.c @@ -0,0 +1,12 @@ + +#include "input.h" +#include "util.h" +#include "common.h" + +void input_init(struct input *input) { + /* memset(input->keys, 0, sizeof(input->keys[0]) * ARRAY_SIZE(input->keys)); */ + input->keystates = SDL_GetKeyboardState(NULL); +} + +/* void handle_key(struct input *input, SDL_KeyboardEvent *key) { */ +/* } */ diff --git a/src/input.h b/src/input.h @@ -0,0 +1,24 @@ + + +#ifndef POLYADVENT_INPUT_H +#define POLYADVENT_INPUT_H + +#include <SDL2/SDL.h> +#include "common.h" + +/* enum key_state { */ +/* KEY_NONE, */ +/* KEY_DOWN, */ +/* KEY_UP */ +/* }; */ + +struct input { + /* enum key_state keys[0x7F-0x1F]; */ + u8 const *keystates; +}; + +void input_init(struct input *input); + +/* void handle_key(struct input *input, SDL_KeyboardEvent *ke); */ + +#endif /* POLYADVENT_INPUT_H */ diff --git a/src/main.c b/src/main.c @@ -16,7 +16,7 @@ int main(void) { - struct game_state game; + struct game game; struct slab slab; struct geometry slab_geom; struct terrain terrain; @@ -31,7 +31,7 @@ int main(void) SDL_GL_CreateContext(window); init_gl(&game.test_resources); - init_game(&game); + game_init(&game); terrain_init(&terrain); terrain_create(&terrain); @@ -53,7 +53,7 @@ int main(void) while (1) { process_events(); update(&game); - render(&game.test_resources, &slab_geom); + render(&game.test_resources, &terrain.geom); /* Swap front and back buffers */ SDL_GL_SwapWindow(window); diff --git a/src/mat4/mat4.c b/src/mat4/mat4.c @@ -1,6 +1,7 @@ #include "mat4.h" #include <math.h> +#include <stdio.h> #include <string.h> #define PI 3.14159265f @@ -234,6 +235,7 @@ int float_eq(float a, float b) { return fabsf(a - b) < 0.0001; } + mat4 *mat4_rotate(const mat4 *mat, const float angle, const float *axis, mat4 *dest) { float x = axis[0], y = axis[1], z = axis[2]; @@ -288,3 +290,13 @@ mat4 *mat4_rotate(const mat4 *mat, const float angle, return dest; } + + +mat4_print(const mat4 *m) { + for (int i = 0; i < 16; ++i) { + if (i % 4 == 0) + printf("\n"); + printf("%f ", m[i]); + } + printf("\n"); +} diff --git a/src/mat4/mat4.h b/src/mat4/mat4.h @@ -13,6 +13,7 @@ mat4 *mat4_inverse(mat4 *src, mat4 *dest); mat4 *mat4_copy(const mat4 *src, mat4 *dst); mat4 *mat4_id(mat4 *dest); mat4 *mat4_multiply(const mat4 *a, const mat4 *b, mat4 *dest); +void mat4_print(const mat4 *a); mat4 *mat4_rotate(const mat4 *mat, const float angle, const float *v3_axis, mat4 *dest); diff --git a/src/render.c b/src/render.c @@ -55,6 +55,7 @@ static const GLushort cube_indices[] = { void init_gl(struct resources *resources) { + float tmp_matrix[16]; glEnable(GL_DEPTH_TEST); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); @@ -97,7 +98,7 @@ init_gl(struct resources *resources) { assert(resources->fragment_shader != 0); // camera - mat4_perspective(90 /* fov */, 1080 / 720, 1, 1000, resources->camera); + mat4_perspective(50 /* fov */, 1080 / 720, 1, 1000, resources->camera_persp); // Shader program resources->program = make_program(resources->vertex_shader, @@ -180,15 +181,14 @@ static void render_geom (struct resources *res, glDrawElements( GL_TRIANGLES, - geom->num_elements, /* count */ + geom->num_indices, /* count */ GL_UNSIGNED_INT, /* type */ (void*)0 /* element array buffer offset */ ); } -void -render (struct resources * resources, struct geometry *geom) { +void render (struct resources * resources, struct geometry *geom) { glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); //clear background screen to black glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); @@ -198,19 +198,21 @@ render (struct resources * resources, struct geometry *geom) { float *mvp = resources->test_mvp; float *normal = resources->normal_matrix; float *camera = resources->camera; + float *persp = resources->camera_persp; float fade_factor = resources->fade_factor; - static float v3[] = { 1, 1, 0 }; - v3[1] = fade_factor * 1.4f; - mat4_rotate(mvp, 0.004f, v3, mvp); - mat4_multiply(camera, mvp, tmp_matrix); + /* 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(resources->uniforms.normal_matrix, tmp_matrix, normal); glUseProgram(resources->program); glUniform3f(resources->uniforms.light_dir, -1, 1, -0.099f); - //glUniform1f(resources->uniforms.fade_factor, fade_factor); + glUniform1f(resources->uniforms.fade_factor, fade_factor); glUniformMatrix4fv(resources->uniforms.mvp, 1, 0, tmp_matrix); - //render_cube(resources); + /* render_cube(resources); */ render_geom(resources, geom); } diff --git a/src/terrain.c b/src/terrain.c @@ -1,16 +1,19 @@ #include "terrain.h" - #include "util.h" -// v6----- v5 -// /| /| -// v1------v0| -// | | | | -// | |v7---|-|v4 -// |/ |/ -// v2------v3 +static const float plane_verts[] = { + -1,-1,0, -1,1,0, 1,1,0, 1,-1,0 +}; + +static const float plane_normals[] = { + 0,0,1, 0,0,1, 0,0,1, 0,0,1 +}; + +static const u32 plane_indices[] = { + 2,1,0, 2,0,3 +}; void terrain_init(struct terrain *terrain) { @@ -21,15 +24,14 @@ terrain_init(struct terrain *terrain) { void terrain_create(struct terrain *terrain) { const int num_verts = 4; - float *vs; - float *ns; terrain->geom.num_verts = num_verts; - vs = terrain->geom.vertices = calloc(num_verts * 3, sizeof(*terrain->geom.vertices)); - ns = terrain->geom.normals = calloc(num_verts * 3, sizeof(*terrain->geom.normals)); + terrain->geom.vertices = (float*)plane_verts; + terrain->geom.normals = (float*)plane_normals; + terrain->geom.indices = (u32*)plane_indices; + terrain->geom.num_indices = ARRAY_SIZE(plane_indices); - for (int i = 0; i < num_verts; ++i) { - } + make_buffer_geometry(&terrain->geom); } void diff --git a/src/update.c b/src/update.c @@ -1,16 +1,58 @@ #include "gl.h" #include "update.h" +#include "mat4/mat4.h" -void update (struct game_state * game) { - unsigned int ms = SDL_GetTicks(); - /* struct resources *res; */ +void camera_movement(struct game *game) { + float *camera = game->test_resources.camera; + float amt = 0.1; + + if (game->input.keystates[SDL_SCANCODE_A]) { + mat4_translate(camera, -amt, 0, 0, camera); + } + + if (game->input.keystates[SDL_SCANCODE_D]) { + mat4_translate(camera, amt, 0, 0, camera); + } + + if (game->input.keystates[SDL_SCANCODE_W]) { + mat4_translate(camera, 0, amt, 0, camera); + } + + if (game->input.keystates[SDL_SCANCODE_S]) { + mat4_translate(camera, 0, -amt, 0, camera); + } - /* res = &game->test_resources; */ + if (game->input.keystates[SDL_SCANCODE_UP]) { + /* mat4_translate(camera, 0, 0, 0.1, camera); */ + /* mat4_translate(camera, 0, -amt, 0, camera); */ + mat4_rotate(camera, amt*0.1, (float[]){1,0,0}, camera); + } - // Update fade effect in shader - //res->fade_factor = sinf((float)ms * 0.001f) * 0.5f + 0.5f; + if (game->input.keystates[SDL_SCANCODE_RIGHT]) { + /* mat4_translate(camera, amt, 0, 0, camera); */ + /* mat4_translate(camera, amt, 0, 0, camera); */ + mat4_rotate(camera, amt*0.1, (float[]){0,1,0}, camera); + } - /* game->test_resources */ + if (game->input.keystates[SDL_SCANCODE_LEFT]) { + /* mat4_translate(camera, -amt, 0, 0, camera); */ + /* mat4_translate(camera, -amt, 0, 0, camera); */ + mat4_rotate(camera, -(amt*0.1), (float[]){0,1,0}, camera); + } + if (game->input.keystates[SDL_SCANCODE_DOWN]) { + /* mat4_translate(camera, -0.1, 0, 0, camera); */ + /* mat4_translate(camera, 0, amt, 0, camera); */ + mat4_rotate(camera, -(amt*0.1), (float[]){1,0,0}, camera); + } + + if (game->input.keystates[SDL_SCANCODE_P]) { + mat4_print(camera); + } +} + +void update (struct game *game) { + unsigned int ms = SDL_GetTicks(); + camera_movement(game); } diff --git a/src/update.h b/src/update.h @@ -4,6 +4,6 @@ #include "game.h" -void update(struct game_state * game); +void update(struct game * game); #endif /* PA_UPDATE_H */ diff --git a/src/util.c b/src/util.c @@ -8,3 +8,48 @@ void check_gl() { assert(0); } } + + + +/* void glhLookAtf2( float *matrix, float *eyePosition3D, */ +/* float *center3D, float *upVector3D ) */ +/* { */ +/* float forward[3], side[3], up[3]; */ +/* float matrix2[16], resultMatrix[16]; */ +/* // -------------------- */ +/* forward[0] = center3D[0] - eyePosition3D[0]; */ +/* forward[1] = center3D[1] - eyePosition3D[1]; */ +/* forward[2] = center3D[2] - eyePosition3D[2]; */ +/* NormalizeVector(forward); */ +/* // -------------------- */ +/* // Side = forward x up */ +/* ComputeNormalOfPlane(side, forward, upVector3D); */ +/* NormalizeVector(side); */ +/* -------------------- */ +/* // Recompute up as: up = side x forward */ +/* ComputeNormalOfPlane(up, side, forward); */ +/* // -------------------- */ +/* matrix2[0] = side[0]; */ +/* matrix2[4] = side[1]; */ +/* matrix2[8] = side[2]; */ +/* matrix2[12] = 0.0; */ +/* // -------------------- */ +/* matrix2[1] = up[0]; */ +/* matrix2[5] = up[1]; */ +/* matrix2[9] = up[2]; */ +/* matrix2[13] = 0.0; */ +/* // -------------------- */ +/* matrix2[2] = -forward[0]; */ +/* matrix2[6] = -forward[1]; */ +/* matrix2[10] = -forward[2]; */ +/* matrix2[14] = 0.0; */ +/* // -------------------- */ +/* matrix2[3] = matrix2[7] = matrix2[11] = 0.0; */ +/* matrix2[15] = 1.0; */ +/* // -------------------- */ +/* MultiplyMatrices4by4OpenGL_FLOAT(resultMatrix, matrix, matrix2); */ +/* glhTranslatef2(resultMatrix, */ +/* -eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]); */ +/* // -------------------- */ +/* memcpy(matrix, resultMatrix, 16*sizeof(float)); */ +/* } */ diff --git a/src/util.h b/src/util.h @@ -9,4 +9,6 @@ void check_gl(void); + + #endif /* PA_UTIL_H */ diff --git a/src/window.c b/src/window.c @@ -3,11 +3,13 @@ #include "gl.h" #include "window.h" + void handle_resize(int width, int height) { + printf("resizing %d %d\n", width, height); glViewport( 0, 0, width, height ); - //glMatrixMode( GL_PROJECTION ); //Switch to setting the camera perspective - //Set the camera perspective - //glLoadIdentity(); //reset the camera + /* glMatrixMode( GL_PROJECTION ); //Switch to setting the camera perspective */ + /* Set the camera perspective */ + /* glLoadIdentity(); //reset the camera */ }