From 132f84a43fd3d99feb7b10f354882c04dfee47f0 Mon Sep 17 00:00:00 2001 From: Eric-Paul Ickhorn Date: Wed, 11 Oct 2023 10:10:06 +0200 Subject: [PATCH] Created chunk renderer --- code/source-c/blocks.h | 1 + code/source-c/default_terrain_generator.c | 31 +++++ code/source-c/initialization.c | 7 ++ code/source-c/main.c | 12 +- code/source-c/meshize.c | 147 ++++++++++++++++++++++ code/source-c/state.h | 27 +--- code/source-c/utility.h | 23 ++++ code/source-c/world.c | 106 ++++++++++++++++ code/source-c/world.h | 70 +++++++++++ 9 files changed, 394 insertions(+), 30 deletions(-) create mode 100644 code/source-c/default_terrain_generator.c create mode 100644 code/source-c/meshize.c create mode 100644 code/source-c/utility.h create mode 100644 code/source-c/world.c create mode 100644 code/source-c/world.h diff --git a/code/source-c/blocks.h b/code/source-c/blocks.h index 4b1e309..251c92a 100644 --- a/code/source-c/blocks.h +++ b/code/source-c/blocks.h @@ -20,6 +20,7 @@ typedef struct tc_block_attribute typedef struct tc_block_entry { char *name; + uint32_t identifier; uint32_t attributes_capacity; uint32_t num_attributes; diff --git a/code/source-c/default_terrain_generator.c b/code/source-c/default_terrain_generator.c new file mode 100644 index 0000000..646e46a --- /dev/null +++ b/code/source-c/default_terrain_generator.c @@ -0,0 +1,31 @@ +#include "world.h" + +bool tc_generate_default_terrain_chunk(tc_worldgen_s *gen, tc_chunk_s *chunk) +{ + tc_block_s block; + block.type_identifier = 1; + block.position.x = 0.0f; + block.position.y = 0.0f; + block.position.z = 0.0f; + + uint32_t x_in_chunk = 0; + uint32_t y_in_chunk = 0; + uint32_t z_in_chunk = 0; + while(x_in_chunk < 32) + { + y_in_chunk = 0; + while(y_in_chunk < 32) + { + z_in_chunk = 0; + while(z_in_chunk < 32) + { + tc_set_block_in_chunk(chunk, x_in_chunk, y_in_chunk, z_in_chunk, block); + ++z_in_chunk; + } + ++y_in_chunk; + } + ++x_in_chunk; + } + + return true; +} diff --git a/code/source-c/initialization.c b/code/source-c/initialization.c index 733783a..0b2de14 100644 --- a/code/source-c/initialization.c +++ b/code/source-c/initialization.c @@ -1,4 +1,5 @@ #include "state.h" +#include "world.h" #include @@ -17,6 +18,10 @@ void tc_init_renderer(techneck_s *techneck) SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE ); + techneck->renderer.active_camera.position.x = 0.0f; + techneck->renderer.active_camera.position.y = 0.0f; + techneck->renderer.active_camera.position.z = 0.0f; + techneck->renderer.gl_context = SDL_GL_CreateContext(techneck->renderer.window); gladLoadGLLoader(&SDL_GL_GetProcAddress); gladLoadGL(); @@ -31,6 +36,8 @@ techneck_s tc_init() { techneck_s techneck; tc_init_renderer(&techneck); + techneck.main_world = tc_init_worlds(); + techneck.block_registry = tc_init_blocks(); return techneck; } diff --git a/code/source-c/main.c b/code/source-c/main.c index 954b2ea..8d693a8 100644 --- a/code/source-c/main.c +++ b/code/source-c/main.c @@ -9,7 +9,8 @@ techneck_s tc_game_state_g; mat4x4 projection_matrix; mat4x4 view_matrix; -float triangle_vertices[108] = { +float triangle_vertices[108] = +{ // Front -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, @@ -62,9 +63,7 @@ float triangle_vertices[108] = { 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, -0.5f, - - + 0.5f, -0.5f, -0.5f }; tc_vec3_s tc_camera_position = { 0.0f, 0.0f, 0.0f }; @@ -124,7 +123,8 @@ void render() glUniformMatrix4fv(view_uniform_location, 1, GL_FALSE, &view_matrix[0][0]); // printf("%d\n", view_uniform_location); - render_block(block); + // render_block(block); + tc_draw_world(&tc_game_state_g.main_world); SDL_GL_SwapWindow(tc_game_state_g.renderer.window); } @@ -261,7 +261,7 @@ bool update() int main(int argc, char **argv) { tc_game_state_g = tc_init(); - tc_game_state_g.block_registry = tc_init_blocks(); + tc_new_chunk(&tc_game_state_g.main_world, 0.0f, 0.0f, 0.0f); block = tc_new_block_at_3f(0.0, 0.0, 0.0); diff --git a/code/source-c/meshize.c b/code/source-c/meshize.c new file mode 100644 index 0000000..e701f46 --- /dev/null +++ b/code/source-c/meshize.c @@ -0,0 +1,147 @@ +#include "world.h" + +#include +#include + +float tc_block_vertices[108] = +{ + // Front + -0.5f, -0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + + 0.5f, 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + + // Back + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + + 0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + + // Left + -0.5f, 0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + + -0.5f, -0.5f, -0.5f, + -0.5f, 0.5f, 0.5f, + -0.5f, -0.5f, 0.5f, + + // Right + 0.5f, 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, 0.5f, + + 0.5f, -0.5f, -0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + + // Top + -0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, -0.5f, + + 0.5f, 0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, -0.5f, + + // Bottom + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, -0.5f, + + 0.5f, -0.5f, 0.5f, + -0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, -0.5f +}; + +uint32_t tc_count_chunk_vertices(tc_chunk_s *chunk) +{ + uint32_t num_vertices = 0; + + uint32_t x_in_chunk = 0; + uint32_t y_in_chunk = 0; + uint32_t z_in_chunk = 0; + while(x_in_chunk < 32) + { + y_in_chunk = 0; + while(y_in_chunk < 32) + { + z_in_chunk = 0; + while(z_in_chunk < 32) + { + if(chunk->blocks[x_in_chunk][y_in_chunk][z_in_chunk].type_identifier > 0) + { + num_vertices += 36; + } + ++z_in_chunk; + } + ++y_in_chunk; + } + ++x_in_chunk; + } + return num_vertices; +} + +void tc_meshize_chunk(tc_chunk_s *chunk) +{ + chunk->num_vertices = tc_count_chunk_vertices(chunk); + chunk->vertex_positions = malloc(sizeof(float) * 3 * chunk->num_vertices); + + uint32_t vertex_index = 0; + float block_positions[36*3]; + + uint32_t x_in_chunk = 0; + uint32_t y_in_chunk = 0; + uint32_t z_in_chunk = 0; + while(x_in_chunk < 32) + { + y_in_chunk = 0; + while(y_in_chunk < 32) + { + z_in_chunk = 0; + while(z_in_chunk < 32) + { + if(chunk->blocks[x_in_chunk][y_in_chunk][z_in_chunk].type_identifier > 0) + { + memcpy( + block_positions, + tc_block_vertices, + sizeof(float) * 36 * 3 + ); + + // Move the current block to where it is supposed to be + + uint32_t vertex_of_block = 0; + while(vertex_of_block < 36) + { + uint32_t vertex_start = vertex_of_block * 3; + block_positions[vertex_start] += + x_in_chunk; + block_positions[vertex_start + 1] += + y_in_chunk; + block_positions[vertex_start + 2] += + z_in_chunk; + ++vertex_of_block; + } + + memcpy( + &chunk->vertex_positions[vertex_index], + block_positions, + sizeof(float) * 36 * 3 + ); + vertex_index += 36; + } + ++z_in_chunk; + } + ++y_in_chunk; + } + ++x_in_chunk; + } +} + diff --git a/code/source-c/state.h b/code/source-c/state.h index a58f801..90692e1 100644 --- a/code/source-c/state.h +++ b/code/source-c/state.h @@ -8,30 +8,8 @@ #include "shaders.h" #include "blocks.h" - -typedef struct tc_vec3 -{ - float x; - float y; - float z; - -} tc_vec3_s; - -typedef struct tc_object -{ - uint32_t vbo; - uint32_t vao; - tc_vec3_s position; - tc_vec3_s rotation; - -} tc_object_s; - -typedef struct tc_block -{ - tc_vec3_s position; - tc_object_s drawing; - -} tc_block_s; +#include "world.h" +#include "utility.h" typedef struct tc_camera { @@ -55,6 +33,7 @@ typedef struct { tc_renderer_s renderer; tc_block_registry_s block_registry; + tc_world_s main_world; } techneck_s; diff --git a/code/source-c/utility.h b/code/source-c/utility.h new file mode 100644 index 0000000..7cc4467 --- /dev/null +++ b/code/source-c/utility.h @@ -0,0 +1,23 @@ + +#ifndef TC_UTILITY_H +#define TC_UTILITY_H + +typedef struct tc_vec3 +{ + float x; + float y; + float z; + +} tc_vec3_s; + +typedef struct tc_object +{ + uint32_t vbo; + uint32_t vao; + tc_vec3_s position; + tc_vec3_s rotation; + +} tc_object_s; + +#endif + diff --git a/code/source-c/world.c b/code/source-c/world.c new file mode 100644 index 0000000..75955d8 --- /dev/null +++ b/code/source-c/world.c @@ -0,0 +1,106 @@ +#include "world.h" +#include "state.h" +#include + +#include + +tc_worldgen_s tc_default_terrain_generator_g; + +void tc_draw_chunk(tc_chunk_s *chunk) +{ + mat4x4 model_matrix; + mat4x4_translate(model_matrix, chunk->position.x*32, chunk->position.y*32, chunk->position.z*32); + + int model_matrix_uniform_location = + glGetUniformLocation(tc_game_state_g.renderer.draw_shader.program_id, "model_matrix"); + glUniformMatrix4fv(model_matrix_uniform_location, 1, GL_FALSE, &model_matrix[0][0]); + + // glBindVertexArray(chunk->vao); + glBindBuffer(GL_ARRAY_BUFFER, chunk->vertex_data); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0); + glEnableVertexAttribArray(0); + + glDrawArrays(GL_TRIANGLES, 0, chunk->num_vertices); + + glBindVertexArray(0); +} + +void tc_init_world_generators() +{ + tc_default_terrain_generator_g.name = "Default Terrain Generator"; + tc_default_terrain_generator_g.fn_generate_chunk = &tc_generate_default_terrain_chunk; +} + +tc_world_s tc_init_worlds() +{ + tc_init_world_generators(); + + tc_world_s world; + world.chunks_capacity = 256; + world.num_chunks = 0; + world.chunks = calloc(sizeof(tc_chunk_s *), world.chunks_capacity); + world.worldgen = &tc_default_terrain_generator_g; + + return world; +} + + + +void tc_set_block_in_chunk( + tc_chunk_s *chunk, + uint32_t x, uint32_t y, uint32_t z, + tc_block_s block +) { + chunk->blocks[x][y][z] = block; +} + + + +void tc_draw_world(tc_world_s *world) +{ + uint32_t chunk_index = 0; + while(chunk_index < world->num_chunks) + { + tc_draw_chunk(world->chunks[chunk_index]); + ++chunk_index; + } +} + +void tc_add_chunk(tc_world_s *world, tc_chunk_s *chunk) +{ + if(world->num_chunks >= world->chunks_capacity) + { + world->chunks_capacity *= 2; + world->chunks = realloc(world->chunks, sizeof(tc_chunk_s *) * world->chunks_capacity); + } + world->chunks[world->num_chunks] = chunk; + ++world->num_chunks; +} + +// Creates & Generates a chunk and provides a pointer to it +tc_chunk_s * tc_new_chunk(tc_world_s *world, float x, float y, float z) +{ + tc_chunk_s *chunk = malloc(sizeof(tc_chunk_s)); + chunk->position.x = x; + chunk->position.y = y; + chunk->position.z = z; + world->worldgen->fn_generate_chunk(world->worldgen, chunk); + tc_meshize_chunk(chunk); + + glGenVertexArrays(1, &chunk->vao); + glBindVertexArray(chunk->vao); + + glGenBuffers(1, &chunk->vertex_data); + glBindBuffer(GL_ARRAY_BUFFER, chunk->vertex_data); + + glBufferData(GL_ARRAY_BUFFER, chunk->num_vertices * 3 * sizeof(float), chunk->vertex_positions, GL_STATIC_DRAW); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0); + glEnableVertexAttribArray(0); + + glBindVertexArray(0); + + tc_add_chunk(world, chunk); + + return chunk; +} + diff --git a/code/source-c/world.h b/code/source-c/world.h new file mode 100644 index 0000000..2e4d2f2 --- /dev/null +++ b/code/source-c/world.h @@ -0,0 +1,70 @@ + +#ifndef TC_WORLD_H +#define TC_WORLD_H + +#include +#include + +#include "blocks.h" +#include "utility.h" + +typedef struct tc_worldgen tc_worldgen_s; +typedef struct tc_block tc_block_s; +typedef struct tc_chunk tc_chunk_s; +typedef struct tc_world tc_world_s; + +struct tc_worldgen +{ + char *name; + bool (*fn_generate_chunk) (tc_worldgen_s *gen, tc_chunk_s *chunk); + +}; + +struct tc_block +{ + uint32_t type_identifier; + tc_vec3_s position; + tc_object_s drawing; + +}; + +struct tc_chunk +{ + tc_vec3_s position; + tc_block_s blocks[32][32][32]; + + uint32_t num_vertices; + float *vertex_positions; + + uint32_t vao; + uint32_t vertex_data; + +}; + +struct tc_world +{ + uint32_t chunks_capacity; + uint32_t num_chunks; + tc_chunk_s **chunks; + + tc_worldgen_s *worldgen; + +}; + +tc_world_s tc_init_worlds (); +void tc_draw_world (tc_world_s *world); + +tc_chunk_s * tc_new_chunk (tc_world_s *world, float x, float y, float z); + +void tc_set_block_in_chunk( + tc_chunk_s *chunk, + uint32_t x, uint32_t y, uint32_t z, + tc_block_s block +); + +void tc_meshize_chunk (tc_chunk_s *chunk); + +bool tc_generate_default_terrain_chunk (tc_worldgen_s *gen, tc_chunk_s *chunk); + +#endif +