polyadvent

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

commit 7f1108e7efcd1971a5f8e421e33f7547489a7aa6
parent 7e8508fa101ead3ed90493e594b67c375c01dfe4
Author: William Casarin <jb55@jb55.com>
Date:   Mon,  4 Oct 2021 17:03:04 -0700

resource_id newtypes, tcc, init rogue

Diffstat:
M.envrc | 1+
MMakefile | 37+++++++++++++++----------------------
Mdefault.nix | 2+-
Mmain.c | 19+++++++++++--------
Arogue/rogue.c | 226+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arogue/rogue.h | 23+++++++++++++++++++++++
Msrc/animation.h | 2+-
Msrc/camera.h | 2+-
Msrc/chess.c | 10+++++-----
Msrc/chess.h | 2+-
Msrc/dae.c | 4++--
Msrc/entity.c | 14+++++++-------
Msrc/entity.h | 16++++++++++------
Msrc/game.c | 12++++++------
Msrc/game.h | 15+++++++--------
Msrc/geometry.c | 41++++++-----------------------------------
Msrc/geometry.h | 37++++++++++---------------------------
Msrc/gpu.h | 1+
Msrc/mdl.c | 6+++---
Msrc/mdl.h | 4++--
Asrc/mkgeom.c | 33+++++++++++++++++++++++++++++++++
Asrc/mkgeom.h | 23+++++++++++++++++++++++
Msrc/model.c | 2+-
Msrc/model.h | 2+-
Msrc/movement.c | 2+-
Msrc/node.c | 28++++++++++++++--------------
Msrc/node.h | 16+++++++++-------
Msrc/orbit.h | 2+-
Msrc/ply.c | 2++
Msrc/ply.h | 2+-
Msrc/render.h | 2+-
Msrc/resource.h | 2+-
Msrc/test_game.c | 42+++++++++++++++++++++---------------------
Msrc/test_game.h | 15+++++++--------
Msrc/ui.c | 2+-
Msrc/ui.h | 2+-
Msrc/window.c | 2+-
Msrc/window.h | 2+-
Mtest/test_scene.c | 6+++---
Mtools/compile-model.c | 10+++++-----
40 files changed, 467 insertions(+), 204 deletions(-)

diff --git a/.envrc b/.envrc @@ -1 +1,2 @@ use nix +export CC=tcc diff --git a/Makefile b/Makefile @@ -1,16 +1,17 @@ NAME ?= polyadvent BIN ?= $(NAME) PREFIX ?= /usr/local -#DEFS= -DGLFW_INCLUDE_NONE -DDEBUG -O0 -g -U_FORTIFY_SOURCE +FLAGS= -O0 -g -DDEBUG -U_FORTIFY_SOURCE +#FLAGS= -O2 # release build lol -DEFS= -DGLFW_INCLUDE_NONE -DNDEBUG -Og -g +#FLAGS=-DGLFW_INCLUDE_NONE -DNDEBUG -Og -g TINYCC_CFLAGS=-DSTBI_NO_SIMD -DSDL_DISABLE_IMMINTRIN_H $(shell pkg-config --cflags sdl2 gl x11) TINYCC_LDFLAGS=$(shell pkg-config --libs sdl2 gl) \ $(shell pkg-config --libs-only-L x11 xcb xau xdmcp xext xcursor xrender xfixes xinerama xi xrandr xscrnsaver xxf86vm) -CFLAGS = $(DEFS) -Isrc \ +CFLAGS = -DGLFW_INCLUDE_NONE $(FLAGS) -Isrc \ $(TINYCC_CFLAGS) \ -Wall -Werror -Wextra -std=c99 \ -Wno-unused-function \ @@ -38,25 +39,17 @@ TOOLS = tools/compile-model all: $(BIN) $(MODELS) clean: - rm -f main.o polyadvent.o src/main.o test/*.o tools/*.o $(OBJS) $(TESTS) $(TOOLS) $(MODELS) $(SHLIB) $(BIN) $(SRC)/*.d* - -%.d: %.c - @rm -f $@; \ - $(CC) -MM $(CFLAGS) $< > $@.$$$$; \ - sed 's,\(.*\)\.o[ :]*,src/\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.o: %.c %.h - @echo "cc $<" - @$(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $< + rm -f main.o polyadvent.o src/main.o test/*.o tools/*.o $(TOOLS) $(MODELS) $(OBJS) $(TESTS) $(SHLIB) $(BIN) $(SRC)/*.d* test/%: test/%.o $(OBJS) - @echo "link $@" + @echo "$(CC) $@" @$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@ + +COMPILE_MODEL_DEPS=tools/compile-model.c src/ply.c src/mdl.c src/mkgeom.c src/file.c -tools/%: tools/%.o $(OBJS) - @echo "link $@" - @$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@ +tools/compile-model: $(COMPILE_MODEL_DEPS) src/ply.h src/mdl.h + @echo "$(CC) $@" + @$(CC) $(CFLAGS) $(COMPILE_MODEL_DEPS) $(LDFLAGS) -o $@ tools: $(TOOLS) @@ -69,8 +62,8 @@ check: $(TESTS) $(MODELS) ./test/test_resource ./test/test_scene -$(BIN): main.o $(OBJS) - @echo "link $@" +$(BIN): main.c $(SRCS) + @echo "$(CC) $@" @$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@ install: $(BIN) @@ -81,6 +74,6 @@ TAGS: etags $(SRCS) tags: - ctags $(SRCS) $(HEADERS) + ctags $(SRCS) $(SRCS:.c=.h) $(HEADERS) -.PHONY: TAGS tags +.PHONY: TAGS tags clean clean-models polyadvent diff --git a/default.nix b/default.nix @@ -14,7 +14,7 @@ stdenv.mkDerivation rec { makeFlags = "PREFIX=$(out)"; - nativeBuildInputs = with pkgs; [ tinycc pkg-config gdb ]; + nativeBuildInputs = with pkgs; [ tinycc pkg-config gdb sloccount ]; buildInputs = with pkgs; [ SDL2 mesa libglvnd ] ++ (with xorg; [ libX11 libxcb libXau libXdmcp libXext libXcursor diff --git a/main.c b/main.c @@ -20,6 +20,7 @@ #include "util.h" #include "window.h" #include "test_game.h" +#include "chess.h" //#include "rogue/rogue.h" @@ -37,8 +38,9 @@ int main(void) printf("seed %d\n", seed); srand(seed); - struct game engine; - struct test_game test_game; + struct engine engine; + struct test_game game; + //struct rogue_game game; engine.seed = seed; @@ -47,13 +49,13 @@ int main(void) int height = 480; game_init(&engine, width, height); - //rogue_game_init(&rogue_game); + //init_rogue_game(&game); - init_test_game(&engine, &test_game); + init_test_game(&engine, &game); //reset_scene(&engine); - default_scene(&test_game); - //pbr_scene(&test_game); - chess_scene(&engine, &test_game); + default_scene(&game); + //pbr_scene(&game); + chess_scene(&engine, &game); check_gl(); double last = hires_time_in_seconds(); @@ -67,6 +69,7 @@ int main(void) engine.input.resized_height); handle_resize(&engine, engine.input.resized_width, engine.input.resized_height); } + //default_config.camera = engine.test_resources.camera_node->mat; double new_time = hires_time_in_seconds(); double frame_time = new_time - last; @@ -74,7 +77,7 @@ int main(void) last = new_time; // render our game frame here - test_game_frame(&engine, &test_game); + test_game_frame(&engine, &game); //rogue_frame(&engine, rogue_game); /* Swap front and back buffers */ diff --git a/rogue/rogue.c b/rogue/rogue.c @@ -0,0 +1,226 @@ + +#include "rogue.h" + +void init_rogue_game(struct rogue_game *game) +{ + make_grid_geom(&game->grid.geom); +} + +void rogue_frame(struct game *engine, struct rogue_game *game) +{ + render(engine, game) +} + +static void make_grid(float *verts, float vert_capacity, + u32 *indices, float index_capacity, + float *normals, float normal_capacity, + float *colors, float color_capacity, + int width, int height) +{ + int c = 0; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++, c++) { + int grid_ind = y * height + x; + int vind = grid_ind * ARRAY_SIZE(quad_vertices); + int iind = grid_ind * ARRAY_SIZE(quad_indices); + int i = 0; + + for (i = 0; i < 4; i++) { + int nv = i*3; + assert(vind+2+nv < vert_capacity); + assert(vind+2+nv < color_capacity); + assert(vind+2+nv < normal_capacity); + verts[vind+0+nv] = (quad_vertices[0+nv] + x) * CELL_SIZE; + verts[vind+1+nv] = (quad_vertices[1+nv] + y) * CELL_SIZE; + verts[vind+2+nv] = quad_vertices[2+nv]; + + // recenter + verts[vind+0+nv] -= (width * CELL_SIZE)/2.0 - 0.5 * CELL_SIZE; + verts[vind+1+nv] -= (height * CELL_SIZE)/2.0 - 0.5 * CELL_SIZE; + verts[vind+2+nv] -= 0.5; + + normals[vind+0+nv] = quad_normals[0+nv]; + normals[vind+1+nv] = quad_normals[1+nv]; + normals[vind+2+nv] = quad_normals[2+nv]; + + float checkers = (x ^ y) & 1; + colors[vind+0+nv] = checkers; + colors[vind+1+nv] = checkers; + colors[vind+2+nv] = checkers; + } + + for (i = 0; i < 2; i++) { + int nv = i*3; + assert(iind+2+nv < index_capacity); + indices[iind+0+nv] = quad_indices[0+nv] + 4*c; + indices[iind+1+nv] = quad_indices[1+nv] + 4*c; + indices[iind+2+nv] = quad_indices[2+nv] + 4*c; + } + } + } +} + + +static void make_grid_geom(geometry_id *id) +{ + struct make_geometry mkgeom; + init_make_geometry(&mkgeom); + + static float verts[12*8*8]; // array_size(quad) 12 * 8 * 8 + static float colors[12*8*8]; // array_size(quad) 12 * 8 * 8 + static float normals[12*8*8]; // array_size(quad) 12 * 8 * 8 + static u32 indices[6*8*8]; // array_size(quad) 6 * 8 * 8 + + make_grid(verts, ARRAY_SIZE(verts), + indices, ARRAY_SIZE(indices), + normals, ARRAY_SIZE(normals), + colors, ARRAY_SIZE(colors), + 8, 8); + + mkgeom.indices = indices; + mkgeom.vertices = verts; + mkgeom.normals = normals; + mkgeom.colors = colors; + mkgeom.num_indices = ARRAY_SIZE(indices); + mkgeom.num_verts = ARRAY_SIZE(verts)/3; + mkgeom.num_uv_components = 0; + + init_id(id); + struct geometry *geom = new_geometry(id); + make_buffer_geometry(&mkgeom, geom); + check_gl(); +} + + +static void render(struct game *engine, struct rogue_game *game) { + glEnable(GL_DEPTH_TEST); + + glClearColor( gtmp[0], gtmp[1], gtmp[2], 1.0 ); //clear background screen to black + /* glClearColor( 0.5294f * adjust, 0.8078f * adjust, 0.9216f * adjust, 1.0f ); //clear background screen to black */ + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + check_gl(); + + static float id[MAT4_ELEMS] = { 0 }; + static float view[MAT4_ELEMS] = { 0 }; + static float view_proj[MAT4_ELEMS] = { 0 }; + static float normal_matrix[MAT4_ELEMS] = { 0 }; + static float model_view[MAT4_ELEMS] = { 0 }; + static float depth_mvp[MAT4_ELEMS] = { 0 }; + + mat4_id(id); + mat4_id(model_view); + + mat4 *mvp = res->test_mvp; + mat4 *projection = config->projection; + mat4 *light = res->light_dir; + + struct node *camera_node = get_node(&config->camera); + assert(camera_node); + + const mat4 *camera = camera_node->mat; + u32 num_entities; + + struct entity *entities = + get_all_entities(&num_entities, NULL); + + struct gpu_program *program = NULL; + + mat4_inverse((float*)camera, view); + mat4_multiply(projection, view, view_proj); + + if (config->is_depth_pass) { + glDisable(GL_CULL_FACE); + mat4_multiply(bias_matrix, view_proj, config->depth_vp); + } + else { + glCullFace(GL_BACK); + } + + mat4_inverse((float *)camera, view); + mat4_multiply(projection, view, view_proj); + + struct model *skybox_model = get_model(&res->skybox.model_id); + assert(skybox_model); + + glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_model->texture); + check_gl(); + + for (u32 i = 0; i < num_entities; ++i) { + struct entity *entity = &entities[i]; + struct model *model = get_model(&entity->model_id); + assert(model); + struct node *node = get_node(&entity->node_id); + assert(node); + + if (entity->flags & ENT_INVISIBLE) + continue; + + program = &game->gpu.programs[model->shader]; + glUseProgram(program->handle); + check_gl(); + + uniform_3f(program, UNIFORM_CAMERA_POSITION, &camera[M_X]); + + if (model->shader == CHESS_PIECE_PROGRAM) { + uniform_1i(program, UNIFORM_IS_WHITE, + (entity->flags & ENT_IS_WHITE) == ENT_IS_WHITE); + } + + uniform_1i(program, UNIFORM_FOG_ON, res->fog_on); + uniform_3f(program, UNIFORM_LIGHT_DIR, light); + uniform_1f(program, UNIFORM_LIGHT_INTENSITY, res->light_intensity); + uniform_1f(program, UNIFORM_SKY_INTENSITY, sky_intensity); + uniform_3f(program, UNIFORM_SUN_COLOR, res->sun_color); + + mat4_multiply(view_proj, node->mat, mvp); + mat4_copy(node->mat, model_view); + mat4_multiply(config->depth_vp, model_view, depth_mvp); + uniform_m4f(program, UNIFORM_DEPTH_MVP, depth_mvp); + uniform_m4f(program, UNIFORM_MVP, mvp); + uniform_m4f(program, UNIFORM_MODEL, node->mat); + + recalc_normals(program->uniforms[UNIFORM_NORMAL_MATRIX].location, + model_view, normal_matrix); + check_gl(); + + struct geometry *geo = get_geometry(&model->geom_id); + /* debug("geo node %s\n", node->label); */ + assert(geo); + render_geometry(geo, program->vertex_attrs, program); + check_gl(); + } + + if (game->wireframe) { + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + } + else { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + + if (!config->is_depth_pass) { + mat4_inverse((float*)camera, view); + mat4_remove_translations(view); + mat4_multiply(projection, view, view_proj); + + render_skybox(&res->skybox, view_proj); + } + + if (config->draw_ui) + render_ui(&game->ui, view); + + //player + // y tho + + // terrain + + /* glUniformMatrix4fv(res->uniforms.mvp, 1, 0, mvp); */ + /* glUniformMatrix4fv(res->uniforms.model_view, 1, 0, id); */ + /* glUniformMatrix4fv(res->uniforms.world, 1, 0, id); */ + /* glUniformMatrix4fv(res->uniforms.normal_matrix, 1, 0, id); */ + /* recalc_normals(res->uniforms.normal_matrix, model_view, normal_matrix); */ + /* render_geom(res, geom, GL_TRIANGLES); */ + /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */ + /* render_geom(res, geom, GL_TRIANGLES); */ +} + diff --git a/rogue/rogue.h b/rogue/rogue.h @@ -0,0 +1,23 @@ +#pragma once + +#include "geometry.h" +#include "orbit.h" +#include "entity.h" +#include "node.h" + +struct grid +{ + struct geometry_id goem; +}; + +struct rogue_game +{ + struct grid grid; + struct entity_id player; + + struct orbit orbit_camera; + float time; +}; + +void init_rogue_game(struct rogue_game *game); +void rogue_frame(struct engine *engine, struct rogue_game *game); diff --git a/src/animation.h b/src/animation.h @@ -14,7 +14,7 @@ struct joint int id; int children_ids[MAX_JOINT_CHILDREN]; int n_children_ids; - node_id node_id; + struct node_id node_id; }; struct pose diff --git a/src/camera.h b/src/camera.h @@ -8,7 +8,7 @@ struct camera { float frustum[16]; - node_id node_id; + struct node_id node_id; }; void camera_follow(vec3 *cam_pos, vec3 *target, mat4 *cam); diff --git a/src/chess.c b/src/chess.c @@ -91,7 +91,7 @@ void make_grid(float *verts, float vert_capacity, } } -static void make_chessboard_geom(geometry_id *id) +static void make_chessboard_geom(struct geometry_id *id) { struct make_geometry mkgeom; init_make_geometry(&mkgeom); @@ -140,7 +140,7 @@ static void position_piece(struct entity *piece, int x, int y) node->pos[1] += y * CELL_SIZE; } -static void setup_pieces(node_id *chessboard) { +static void setup_pieces(struct node_id *chessboard) { struct model *pirate_officer, *pawn_model, *tower_model, *rook_model; struct model_id pawn_model_id, rook_model_id; u32 ent_type; @@ -262,7 +262,7 @@ static struct gpu_program *make_chess_program(struct gpu *gpu) return program; } -void chess_scene(struct game *engine, struct test_game *game) +void chess_scene(struct engine *engine, struct test_game *game) { struct gpu_program *piece_program; struct entity *ent = new_entity(NULL); @@ -276,7 +276,7 @@ void chess_scene(struct game *engine, struct test_game *game) // // setup chessboard // - geometry_id chessboard_geom; + struct geometry_id chessboard_geom; make_chessboard_geom(&chessboard_geom); struct model_id chessboard_model_id; @@ -303,7 +303,7 @@ void chess_scene(struct game *engine, struct test_game *game) pnode->orientation[2] = -0.005; pnode->orientation[3] = -1.0; - node_id *cam_id = &game->orbit_camera.node_id; + struct node_id *cam_id = &game->orbit_camera.node_id; struct node *cam_node = get_node(cam_id); assert(cam_node); make_chess_program(&engine->gpu); diff --git a/src/chess.h b/src/chess.h @@ -5,6 +5,6 @@ #include "test_game.h" #include "game.h" -void chess_scene(struct game *engine, struct test_game *game); +void chess_scene(struct engine *engine, struct test_game *game); #endif /* POLYADVENT_CHESS_H */ diff --git a/src/dae.c b/src/dae.c @@ -200,7 +200,7 @@ static void parse_joint_matrix(struct dae_data *data, const char *d, struct node *node = new_node(&joint->node_id); assert(node); - assert((int64_t)joint->node_id.uuid != -1); + assert((int64_t)joint->node_id.id.uuid != -1); assert(&joint->node_id == &pose->joints[pose->njoints].node_id); parse_joint(d, pose->njoints, joint); @@ -351,7 +351,7 @@ void dae_attr(struct xmlparser *x, const char *t, size_t tl, } else if (data->state == PARSING_NODE && streq(a, "name")) { - strncpy(data->current_name, v, sizeof(data->current_name)); + strncpy(data->current_name, v, sizeof(data->current_name)-1); } else if (data->state == PARSING_NODE && streq(a, "type") diff --git a/src/entity.c b/src/entity.c @@ -15,11 +15,11 @@ struct resource_manager *_internal_get_entity_system() return &esys; } -struct entity *get_all_entities(u32 *count, entity_id **ids) { - return get_all_resources(&esys, count, ids); +struct entity *get_all_entities(u32 *count, struct entity_id **ids) { + return get_all_resources(&esys, count, (struct resource_id**)ids); } -struct entity *init_entity(struct entity *ent, node_id *id) { +struct entity *init_entity(struct entity *ent, struct node_id *id) { init_id(&ent->model_id.id); if (id == NULL) { init_id(&ent->node_id); @@ -33,8 +33,8 @@ struct entity *init_entity(struct entity *ent, node_id *id) { return ent; } -struct entity *get_entity(entity_id *ent_id) { - return get_resource(&esys, ent_id); +struct entity *get_entity(struct entity_id *ent_id) { + return get_resource(&esys, (struct resource_id *)ent_id); } static inline struct entity *new_uninitialized_entity(entity_id *id) { @@ -42,7 +42,7 @@ static inline struct entity *new_uninitialized_entity(entity_id *id) { } -struct entity *new_entity_with_node(entity_id *id, node_id *node) +struct entity *new_entity_with_node(struct entity_id *id, struct node_id *node) { entity_id new_id; @@ -70,7 +70,7 @@ void destroy_entities() } }; -void destroy_entity(entity_id *id) +void destroy_entity(struct entity_id *id) { struct entity *ent = get_entity(id); if (ent == NULL) diff --git a/src/entity.h b/src/entity.h @@ -19,7 +19,7 @@ enum entity_flags { }; struct entity { - node_id node_id; + struct node_id node_id; struct model_id model_id; u32 flags; u32 type; @@ -30,15 +30,19 @@ struct entity { typedef struct resource_id entity_id; -struct entity *init_entity(struct entity *, node_id *id); +struct entity_id { + struct resource_id id; +}; + +struct entity *init_entity(struct entity *, struct node_id *id); void destroy_entities(); struct resource_manager *_internal_get_entity_system(); -void destroy_entity(entity_id *); +void destroy_entity(struct entity_id *); void init_entity_system(); -struct entity *get_entity(entity_id *); +struct entity *get_entity(struct entity_id *); const char *entity_label(struct entity *); -struct entity *get_all_entities(u32 *count, entity_id **ids); -struct entity *new_entity_with_node(entity_id *, node_id *); +struct entity *get_all_entities(u32 *count, struct entity_id **ids); +struct entity *new_entity_with_node(struct entity_id *, struct node_id *); struct entity *new_debug_entity(entity_id *, float *pos); void destroy_entity_system(); diff --git a/src/game.c b/src/game.c @@ -25,12 +25,12 @@ mat4 *cam_init = (float[16]){ -71.766136, -47.881512, -44.216671, 1.000000 }; -bool was_key_pressed_this_frame(struct game *game, int scancode) +bool was_key_pressed_this_frame(struct engine *game, int scancode) { return is_key_down_on_frame(&game->input, scancode, game->frame); } -bool was_button_pressed_this_frame(struct game *game, SDL_GameControllerButton button) +bool was_button_pressed_this_frame(struct engine *game, SDL_GameControllerButton button) { return is_button_down_on_frame(&game->input, button, game->frame); } @@ -53,13 +53,13 @@ static void init_sdl(SDL_Window **window, int width, int height) SDL_GL_CreateContext(*window); } -void quit_game(struct game *game) +void quit_game(struct engine *game) { game->quit = 1; } // TODO: cleanup -void init_misc(struct game *game) { +void init_misc(struct engine *game) { game->quit = 0; game->frame = 0; game->gpu.num_programs = 0; @@ -90,7 +90,7 @@ void init_controller(struct input *input) { } } -void game_init(struct game *game, int width, int height) { +void game_init(struct engine *game, int width, int height) { game->width = width; game->height = height; debug("init sdl...\n"); @@ -106,7 +106,7 @@ void game_init(struct game *game, int width, int height) { check_gl(); - game->wireframe = 0; + game->gpu.wireframe = 0; init_input(&game->input); init_controller(&game->input); diff --git a/src/game.h b/src/game.h @@ -27,12 +27,11 @@ struct user_settings { float mouse_sens; }; -struct game { +struct engine { SDL_Window *window; int counter; int seed; int quit; - int wireframe; int width, height; float dt; u64 frame; @@ -42,11 +41,11 @@ struct game { struct gpu gpu; }; -void game_init(struct game *game, int width, int height); -void quit_game(struct game *game); -void should_update(struct game *game); -bool was_key_pressed_this_frame(struct game *game, int scancode); -bool was_button_pressed_this_frame(struct game *game, SDL_GameControllerButton button); -int is_free_camera(struct game *game); +void game_init(struct engine *game, int width, int height); +void quit_game(struct engine *game); +void should_update(struct engine *game); +bool was_key_pressed_this_frame(struct engine *game, int scancode); +bool was_button_pressed_this_frame(struct engine *game, SDL_GameControllerButton button); +int is_free_camera(struct engine *game); #endif /* PA_GAME_H */ diff --git a/src/geometry.c b/src/geometry.c @@ -8,7 +8,7 @@ struct resource_manager geom_manager; void -destroy_buffer_geometry(geometry_id *geom_id) { +destroy_buffer_geometry(struct geometry_id *geom_id) { struct geometry *geom = get_geometry(geom_id); gpu_addr buffers[MAX_VERTEX_ATTRS]; @@ -71,21 +71,6 @@ void render_geometry(struct geometry *geom, struct gpu_program *program) } } -void init_make_geometry(struct make_geometry *mkgeom) { - *mkgeom = (struct make_geometry){ - .colors = NULL, - .normals = NULL, - .indices = NULL, - .vertices = NULL, - .tex_coords = NULL, - .joint_ids = NULL, - .joint_weights = NULL, - .num_uv_components = 2, - .num_verts = 0, - .num_indices = 0, - }; -} - void init_geometry(struct geometry *geom) { geom->has_vbos = 0; @@ -173,22 +158,22 @@ void init_geometry_manager() { DEF_NUM_GEOMETRY, MAX_GEOMETRY, "geometry"); } -struct geometry *get_geometry(geometry_id *geom_id) { +struct geometry *get_geometry(struct geometry_id *geom_id) { return get_resource(&geom_manager, geom_id); } -struct geometry *new_geometry(geometry_id *geom_id) { +struct geometry *new_geometry(struct geometry_id *geom_id) { struct geometry *geom = new_resource(&geom_manager, geom_id); /* debug("new geometry %llu\n", geom_id->uuid); */ return geom; } -struct geometry *get_all_geometry(u32 *count, geometry_id **ids) { - return get_all_resources(&geom_manager, count, ids); +struct geometry *get_all_geometry(u32 *count, struct geometry_id **ids) { + return get_all_resources(&geom_manager, count, (struct resource_id**)ids); } -void destroy_geometry(geometry_id *geom_id) +void destroy_geometry(struct geometry_id *geom_id) { struct geometry *geom = get_geometry(geom_id); assert(geom); struct vbo *vbo; @@ -202,17 +187,3 @@ void destroy_geometry(geometry_id *geom_id) destroy_resource(&geom_manager, geom_id); } -void free_make_geometry(struct make_geometry *mkgeom) -{ - if (mkgeom->vertices) - free(mkgeom->vertices); - - if (mkgeom->normals) - free(mkgeom->normals); - - if (mkgeom->colors) - free(mkgeom->colors); - - if (mkgeom->indices) - free(mkgeom->indices); -} diff --git a/src/geometry.h b/src/geometry.h @@ -6,12 +6,15 @@ #include "vbo.h" #include "shader.h" #include "resource.h" +#include "mkgeom.h" #define DEF_NUM_GEOMETRY 64 #define MAX_GEOMETRY 1024 // -1 is uninitialized -typedef struct resource_id geometry_id; +struct geometry_id { + struct resource_id id; +}; struct geometry { struct vbo vbos[MAX_VERTEX_ATTRS]; @@ -24,24 +27,6 @@ struct geometry { int num_verts; }; -struct make_geometry { - float *vertices; - float *normals; - float *colors; - int num_verts; - - u32 *indices; - int num_indices; - - float *tex_coords; - int num_uv_components; - - u32 *joint_ids; - int num_joint_ids; - - float *joint_weights; -}; - struct geometry_manager { struct geometry geoms[MAX_GEOMETRY]; int num_geometry; @@ -50,17 +35,15 @@ struct geometry_manager { void render_geometry(struct geometry *geom, struct gpu_program *current_program); void bind_geometry(struct geometry *geom, struct gpu_program *program); void init_geometry(struct geometry *geom); -void init_make_geometry(struct make_geometry *mkgeom); -void free_make_geometry(struct make_geometry *mkgeom); void make_buffer_geometry(struct make_geometry *mkgeom, struct geometry *geom); -void destroy_buffer_geometry(geometry_id *geom); +void destroy_buffer_geometry(struct geometry_id *geom); void geometry_centroid(struct geometry *geom, float *v3); void init_geometry_manager(); -void init_geometry_id(geometry_id *); -struct geometry *new_geometry(geometry_id *); -struct geometry *get_geometry(geometry_id *); -struct geometry *get_all_geometry(u32 *count, geometry_id **ids); -void destroy_geometry(geometry_id *geom_id); +void init_geometry_id(struct geometry_id *); +struct geometry *new_geometry(struct geometry_id *); +struct geometry *get_geometry(struct geometry_id *); +struct geometry *get_all_geometry(u32 *count, struct geometry_id **ids); +void destroy_geometry(struct geometry_id *geom_id); struct resource_manager *get_geometry_manager(); extern struct resource_manager geom_manager; diff --git a/src/gpu.h b/src/gpu.h @@ -7,6 +7,7 @@ struct gpu { struct gpu_program programs[MAX_GPU_PROGRAMS]; int num_programs; + int wireframe; }; int try_reload_shaders(struct gpu *gpu); diff --git a/src/mdl.c b/src/mdl.c @@ -41,7 +41,7 @@ void init_mdl_geometry(struct mdl_geometry *lgeom) vec3_set(V3(0,0,0), lgeom->max); } -void save_mdl_fd(FILE *out, struct model *model, struct mdl_geometry *lgeom) +void save_mdl_fd(FILE *out, struct mdl_geometry *lgeom) { struct make_geometry *mkgeom = &lgeom->mkgeom; assert(mkgeom->vertices); @@ -235,11 +235,11 @@ void load_mdl_fd(FILE *in, struct model *model, struct mdl_geometry *lgeom) } } -void save_mdl(const char *filename, struct model *model, struct mdl_geometry *lgeom) +void save_mdl(const char *filename, struct mdl_geometry *lgeom) { FILE *out = fopen(filename, "wb"); assert(out); - save_mdl_fd(out, model, lgeom); + save_mdl_fd(out, lgeom); fclose(out); } diff --git a/src/mdl.h b/src/mdl.h @@ -26,8 +26,8 @@ struct mdl_geometry { }; -void save_mdl(const char *filename, struct model *model, struct mdl_geometry *geom); -void save_mdl_fd(FILE *out, struct model *model, struct mdl_geometry *geom); +void save_mdl(const char *filename, struct mdl_geometry *geom); +void save_mdl_fd(FILE *out, struct mdl_geometry *geom); void load_mdl(const char *filename, struct model *model, struct mdl_geometry *geom); void load_mdl_fd(FILE *in, struct model *model, struct mdl_geometry *geom); diff --git a/src/mkgeom.c b/src/mkgeom.c @@ -0,0 +1,33 @@ + +#include "mkgeom.h" +#include <stdlib.h> + +void init_make_geometry(struct make_geometry *mkgeom) { + *mkgeom = (struct make_geometry){ + .colors = 0, + .normals = 0, + .indices = 0, + .vertices = 0, + .tex_coords = 0, + .joint_ids = 0, + .joint_weights = 0, + .num_uv_components = 2, + .num_verts = 0, + .num_indices = 0, + }; +} + +void free_make_geometry(struct make_geometry *mkgeom) +{ + if (mkgeom->vertices) + free(mkgeom->vertices); + + if (mkgeom->normals) + free(mkgeom->normals); + + if (mkgeom->colors) + free(mkgeom->colors); + + if (mkgeom->indices) + free(mkgeom->indices); +} diff --git a/src/mkgeom.h b/src/mkgeom.h @@ -0,0 +1,23 @@ + +#pragma once + +struct make_geometry { + float *vertices; + float *normals; + float *colors; + int num_verts; + + unsigned *indices; + int num_indices; + + float *tex_coords; + int num_uv_components; + + unsigned *joint_ids; + int num_joint_ids; + + float *joint_weights; +}; + +void init_make_geometry(struct make_geometry *mkgeom); +void free_make_geometry(struct make_geometry *mkgeom); diff --git a/src/model.c b/src/model.c @@ -77,7 +77,7 @@ static struct model *load_model(const char *name, struct model_id *mid) // Load mesh debug("loading %s model uuid %" PRIu64 " with geom_id %" PRIu64 "\n", name, - mid->id.uuid, model->geom_id.uuid); + mid->id.uuid, model->geom_id.id.uuid); snprintf(path, 128, "data/models/%s.mdl", name); load_mdl(path, model, &lgeom); diff --git a/src/model.h b/src/model.h @@ -19,7 +19,7 @@ struct model_id { struct model { /* geometry_id geom_id; */ - geometry_id geom_id; + struct geometry_id geom_id; int shader; struct pose poses[MAX_POSES]; // TODO: separate animated_model buffer? int nposes; diff --git a/src/movement.c b/src/movement.c @@ -1,7 +1,7 @@ #include "game.h" -void movement(struct game *engine, struct node *node, float speed_mult) +void movement(struct engine *engine, struct node *node, float speed_mult) { float amt = 3.0 * engine->dt; float turn = 1.0 * engine->dt; diff --git a/src/node.c b/src/node.c @@ -10,32 +10,32 @@ struct resource_manager node_manager = {0}; -static inline struct node *new_uninitialized_node(node_id *id) +static inline struct node *new_uninitialized_node(struct node_id *id) { - return new_resource(&node_manager, id); + return new_resource(&node_manager, &id->id); } -struct node *new_node(node_id *id) +struct node *new_node(struct node_id *id) { - struct node *n = node_init(new_uninitialized_node(id)); - assert((int64_t)id->uuid != -1); + struct node *n = node_init(new_uninitialized_node(&id->id)); + assert((int64_t)id->id.uuid != -1); /* debug("new node %llu\n", id->uuid); */ return n; } -struct node *get_node(node_id *id) +struct node *get_node(struct node_id *id) { - return get_resource(&node_manager, id); + return get_resource(&node_manager, &id->id); } -void destroy_node(node_id *id) +void destroy_node(struct node_id *id) { #ifdef DEBUG - struct node *node = get_node(id); - debug("destroying node %" PRIu64 " %s\n", id->uuid, node->label); + struct node *node = get_node(&id->id); + debug("destroying node %" PRIu64 " %s\n", id->id.uuid, node->label); #endif - destroy_resource(&node_manager, id); + destroy_resource(&node_manager, &id->id); } void init_node_manager() @@ -174,7 +174,7 @@ int node_recalc(struct node *node) { int node_detach(struct node *node, struct node *from) { for (int i = 0; i < from->n_children; i++) { - node_id *child_id = &from->children_ids[i]; + struct node_id *child_id = &from->children_ids[i]; struct node *child = get_node(&from->children_ids[i]); if (child && child == node) { destroy_node(child_id); @@ -210,7 +210,7 @@ int node_count(struct node *node) } -void node_attach(struct resource_id *node_id, struct resource_id *to_id) +void node_attach(struct node_id *node_id, struct node_id *to_id) { struct node *node = get_node(node_id); struct node *to = get_node(to_id); @@ -222,7 +222,7 @@ void node_attach(struct resource_id *node_id, struct resource_id *to_id) assert(to && to->n_children <= MAX_NODE_CHILDREN); node->parent_id = *to_id; - assert(node->parent_id.uuid == to_id->uuid); + assert(node->parent_id.id.uuid == to_id->id.uuid); to->children_ids[to->n_children++] = *node_id; } diff --git a/src/node.h b/src/node.h @@ -10,7 +10,9 @@ enum node_flags { NODE_IGNORE_RECALC = 1 << 0 }; -typedef struct resource_id node_id; +struct node_id { + struct resource_id id; +}; struct node { float pos[3]; @@ -25,12 +27,12 @@ struct node { void (*custom_update)(struct node*); void *custom_update_data; - node_id parent_id; - node_id children_ids[MAX_NODE_CHILDREN]; + struct node_id parent_id; + struct node_id children_ids[MAX_NODE_CHILDREN]; }; int node_recalc(struct node *root); -void node_attach(node_id *node, node_id *to); +void node_attach(struct node_id *node, struct node_id *to); int node_detach(struct node *node, struct node *from); void node_detach_from_parent(struct node *node); void node_mark_for_recalc(struct node *node); @@ -44,9 +46,9 @@ int node_count(struct node *node); float *node_world(struct node *node); int node_set_label(struct node *node, const char *label); -struct node *get_node(node_id *); -struct node *new_node(node_id *); -void destroy_node(node_id *); +struct node *get_node(struct node_id *); +struct node *new_node(struct node_id *); +void destroy_node(struct node_id *); void init_node_manager(); diff --git a/src/orbit.h b/src/orbit.h @@ -14,7 +14,7 @@ struct spherical { struct orbit { struct spherical coords; - node_id node_id; + struct node_id node_id; }; void new_orbit(struct orbit *orbit); diff --git a/src/ply.c b/src/ply.c @@ -102,6 +102,7 @@ static int parse_magic(const char **cursor) { } +/* int parse_ply(const char *filename, struct geometry *geom) { struct mdl_geometry mdlgeom; @@ -115,6 +116,7 @@ int parse_ply(const char *filename, struct geometry *geom) return ok; } +*/ int parse_ply_with_mkgeom(const char *filename, struct mdl_geometry *mdlgeom) { diff --git a/src/ply.h b/src/ply.h @@ -5,7 +5,7 @@ #include "mdl.h" -int parse_ply(const char *filename, struct geometry *geom); +//int parse_ply(const char *filename, struct geometry *geom); int parse_ply_with_mkgeom(const char *filename, struct mdl_geometry *mdlgeom); #endif /* PLYPARSER_H */ diff --git a/src/render.h b/src/render.h @@ -9,7 +9,7 @@ struct render_config { int draw_ui; int is_depth_pass; - node_id camera; + struct node_id camera; float* projection; float* depth_vp; }; diff --git a/src/resource.h b/src/resource.h @@ -29,7 +29,7 @@ struct resource_manager { const char *name; }; -#define ideq(a, b) ((a)->uuid == (b)->uuid) +#define ideq(a, b) ((a)->id.uuid == (b)->id.uuid) void init_id(struct resource_id *id); void *get_resource(struct resource_manager *r, struct resource_id *id); diff --git a/src/test_game.c b/src/test_game.c @@ -105,7 +105,7 @@ static struct entity *get_terrain_entity(struct terrain *t) { return ent; } -static void player_movement(struct game *engine, struct entity *player) { +static void player_movement(struct engine *engine, struct entity *player) { /* if (player->flags & ENT_ON_GROUND) */ /* entity_movement(game, player); */ struct node *node = get_node(&player->node_id); @@ -136,7 +136,7 @@ static void camera_keep_above_ground(struct terrain *terrain, } } -static void entity_movement(struct game *game, struct entity *ent) +static void entity_movement(struct engine *engine, struct entity *ent) { static const float move_accel = 1.0f; static const float max_speed = 10.0f; @@ -144,9 +144,9 @@ static void entity_movement(struct game *game, struct entity *ent) float vel[3]; - float amt = 10.0 * game->dt; + float amt = 10.0 * engine->dt; - if (game->input.keystates[SDL_SCANCODE_W]) { + if (engine->input.keystates[SDL_SCANCODE_W]) { vec3_forward(ent->velocity, node->orientation, V3(0,amt,0), vel); if (vec3_lengthsq(vel) <= max_speed*max_speed) vec3_copy(vel, ent->velocity); @@ -228,7 +228,7 @@ static void day_night_cycle(float time, struct test_game *res) { /* look_at(light_pos, player->node.pos, V3(0, 0, 1.0), res->sun_camera.mat); */ } -static void player_update(struct game *engine, struct test_game *game, struct entity *player) +static void player_update(struct engine *engine, struct test_game *game, struct entity *player) { struct orbit *camera = &game->orbit_camera; struct node *node = get_node(&player->node_id); @@ -356,11 +356,11 @@ void init_test_gl(struct test_game *game, struct gpu *gpu, int width, int height // TODO: add uniforms automatically? -static void render_test_game(struct game *game, struct test_game *res, struct render_config *config) { +static void render_test_game(struct gpu *gpu, struct test_game *game, struct render_config *config) { float gtmp[3]; u32 num_entities; - struct common_uniforms *cvars = &res->common_vars; + struct common_uniforms *cvars = &game->common_vars; cvars->sky_intensity = clamp(cvars->light_intensity, 0.2, 1.0); vec3_scale(cvars->sun_color, cvars->sky_intensity, gtmp); @@ -407,7 +407,7 @@ static void render_test_game(struct game *game, struct test_game *res, struct re mat4_inverse((float *)camera, view); mat4_multiply(projection, view, view_proj); - struct model *skybox_model = get_model(&res->skybox.model_id); + struct model *skybox_model = get_model(&game->skybox.model_id); assert(skybox_model); glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_model->texture); @@ -428,7 +428,7 @@ static void render_test_game(struct game *game, struct test_game *res, struct re if (config->is_depth_pass && !(entity->flags & ENT_CASTS_SHADOWS)) continue; - program = &game->gpu.programs[model->shader]; + program = &gpu->programs[model->shader]; glUseProgram(program->handle); check_gl(); @@ -459,7 +459,7 @@ static void render_test_game(struct game *game, struct test_game *res, struct re check_gl(); } - if (game->wireframe) { + if (gpu->wireframe) { glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); } else { @@ -471,11 +471,11 @@ static void render_test_game(struct game *game, struct test_game *res, struct re mat4_remove_translations(view); mat4_multiply(projection, view, view_proj); - render_skybox(&res->skybox, view_proj); + render_skybox(&game->skybox, view_proj); } if (config->draw_ui) - render_ui(&res->ui, view); + render_ui(&game->ui, view); //player // y tho @@ -493,7 +493,7 @@ static void render_test_game(struct game *game, struct test_game *res, struct re } -void update_test_game (struct game *engine, struct test_game *game) { +void update_test_game (struct engine *engine, struct test_game *game) { static int toggle_fog = 0; static int needs_terrain_update = 0; //struct terrain *terrain = &game->terrain; @@ -509,7 +509,7 @@ void update_test_game (struct game *engine, struct test_game *game) { float *time = &game->time; float *light = cvars->light_dir; - gravity(player, engine->dt); + //gravity(player, engine->dt); if (needs_terrain_update) { /* update_terrain(terrain); */ @@ -530,7 +530,7 @@ void update_test_game (struct game *engine, struct test_game *game) { player_movement(engine, player); } - assert(root->parent_id.generation == 0); + assert(root->parent_id.id.generation == 0); player_update(engine, game, player); @@ -541,7 +541,7 @@ void update_test_game (struct game *engine, struct test_game *game) { #endif if (was_key_pressed_this_frame(engine, SDL_SCANCODE_F5)) { - engine->wireframe ^= 1; + engine->gpu.wireframe ^= 1; } if (was_key_pressed_this_frame(engine, SDL_SCANCODE_C)) { @@ -575,7 +575,7 @@ void update_test_game (struct game *engine, struct test_game *game) { node_recalc(root); } -void test_game_frame(struct game *engine, struct test_game *game) +void test_game_frame(struct engine *engine, struct test_game *game) { static float depth_vp[MAT4_ELEMS]; mat4_id(depth_vp); @@ -613,12 +613,12 @@ void test_game_frame(struct game *engine, struct test_game *game) bind_fbo(fbo); /* glDrawBuffer(GL_NONE); */ - render_test_game(engine, game, &fbo_render_config); + render_test_game(&engine->gpu, game, &fbo_render_config); unbind_fbo(&game->shadow_buffer); - render_test_game(engine, game, &default_config); + render_test_game(&engine->gpu, game, &default_config); } -void init_test_game(struct game *engine, struct test_game *game) +void init_test_game(struct engine *engine, struct test_game *game) { memset(game, 0, sizeof(*game)); struct terrain *terrain = &game->terrain; @@ -635,7 +635,7 @@ void init_test_game(struct game *engine, struct test_game *game) struct node *root = new_node(&game->root_id); struct node *sun_camera = new_node(&game->sun_camera_id); - assert(root->parent_id.generation == 0); + assert(root->parent_id.id.generation == 0); assert(root); assert(sun_camera); diff --git a/src/test_game.h b/src/test_game.h @@ -42,13 +42,13 @@ struct test_game { struct fbo shadow_buffer; struct common_uniforms common_vars; - node_id root_id; - entity_id player_id; + struct node_id root_id; + struct entity_id player_id; struct geometry qh_test; struct orbit orbit_camera; - node_id free_camera_id; - node_id camera_node_id; - node_id sun_camera_id; + struct node_id free_camera_id; + struct node_id camera_node_id; + struct node_id sun_camera_id; u32 test_cubemap; float time; @@ -61,13 +61,12 @@ struct test_game { void init_test_gl(struct test_game *game, struct gpu *gpu, int width, int height); -void init_test_game(struct game *engine, struct test_game *game); -void test_game_frame(struct game *engine, struct test_game *game); +void init_test_game(struct engine *engine, struct test_game *game); +void test_game_frame(struct engine *engine, struct test_game *game); void default_scene(struct test_game *); void entity_test_scene(struct terrain *); void pbr_scene(struct test_game *); -void chess_scene(struct game *, struct test_game *); struct lens *get_common_lenses(); int get_common_lenses_length(); diff --git a/src/ui.c b/src/ui.c @@ -35,7 +35,7 @@ static GLfloat quad_uvs[] = }; -static void create_quad(geometry_id *id) +static void create_quad(struct geometry_id *id) { struct make_geometry mkgeom = { .indices = quad_indices, diff --git a/src/ui.h b/src/ui.h @@ -8,7 +8,7 @@ struct ui { struct gpu_program *shader; - geometry_id quad_geom_id; + struct geometry_id quad_geom_id; GLint texture; float uipos[2]; diff --git a/src/window.c b/src/window.c @@ -7,7 +7,7 @@ #include "update.h" -void handle_resize(struct game *game, int width, int height) { +void handle_resize(struct engine *game, int width, int height) { /* printf("resizing %d %d\n", width, height); */ glViewport( 0, 0, width, height ); game->width = width; diff --git a/src/window.h b/src/window.h @@ -6,7 +6,7 @@ #include "game.h" void -handle_resize(struct game *game, int width, int height); +handle_resize(struct engine *game, int width, int height); #endif /* POLYADVENT_WINDOW_H */ diff --git a/test/test_scene.c b/test/test_scene.c @@ -77,10 +77,10 @@ int scene_tests(struct game *game) { int main(int argc, char *argv[]) { - struct game game; + struct engine engine; int res = chdir("/home/jb55/src/c/polyadvent"); assert(res == 0); - game_init(&game, 1024, 768); - scene_tests(&game); + game_init(&engine, 1024, 768); + scene_tests(&engine); return 0; } diff --git a/tools/compile-model.c b/tools/compile-model.c @@ -40,9 +40,9 @@ int main(int argc, char *argv[]) if (argc != 3) usage(); - init_node_manager(); - init_geometry_manager(); - init_model_manager(); + //init_node_manager(); + //init_geometry_manager(); + //init_model_manager(); char *filename = argv[1]; const char *outfile = argv[2]; @@ -51,7 +51,7 @@ int main(int argc, char *argv[]) struct mdl_geometry mdl_geom; struct make_geometry *mkgeom = &mdl_geom.mkgeom; - init_model(&model); + //init_model(&model); init_mdl_geometry(&mdl_geom); /* load_dae(filename, &model, NULL); */ @@ -60,7 +60,7 @@ int main(int argc, char *argv[]) int ok = parse_ply_with_mkgeom(filename, &mdl_geom); assert(ok); - save_mdl(outfile, &model, &mdl_geom); + save_mdl(outfile, &mdl_geom); return 0; }