From 3e700bda2c93772295f6f75e6ebaf530a7725da5 Mon Sep 17 00:00:00 2001 From: Eric-Paul Ickhorn Date: Fri, 13 Oct 2023 12:23:26 +0200 Subject: [PATCH] Finally, somewhat greedy meshing --- code/source-c/blocks.c | 15 +- code/source-c/blocks.h | 17 ++ code/source-c/chunk_loader.c | 26 +- code/source-c/cube_premeshing.c | 262 +++++++++++++++++ code/source-c/default_terrain_generator.c | 2 +- code/source-c/initialization.c | 4 +- code/source-c/meshize.c | 337 +++++++++------------- 7 files changed, 449 insertions(+), 214 deletions(-) create mode 100644 code/source-c/cube_premeshing.c diff --git a/code/source-c/blocks.c b/code/source-c/blocks.c index 071783e..117b5a9 100644 --- a/code/source-c/blocks.c +++ b/code/source-c/blocks.c @@ -30,6 +30,11 @@ tc_block_entry_s * tc_new_block_entry(char *name) return entry; } +uint32_t tc_sanitize_block_id(uint32_t id) +{ + return id & 0x00ffffff; +} + void tc_add_attribute_to_block_entry(tc_block_entry_s *entry, tc_block_attribute_s attribute) { if(entry->num_attributes >= entry->attributes_capacity) @@ -75,7 +80,7 @@ tc_block_entry_s * tc_resolve_id_to_block_entry(uint32_t id) uint32_t index = 0; while(index < tc_game_state_g.block_registry.num_blocks) { - if(tc_game_state_g.block_registry.blocks[index]->identifier == id) + if(tc_sanitize_block_id(tc_game_state_g.block_registry.blocks[index]->identifier) == tc_sanitize_block_id(id)) { return tc_game_state_g.block_registry.blocks[index]; } @@ -134,6 +139,8 @@ tc_block_entry_s * tc_new_cube_block(tc_cube_info_s info) front_attrib.value.pointer = tc_resolve_id_to_image(info.texture_front); tc_add_attribute_to_block_entry(entry, front_attrib); + tc_premesh_cube(entry); + return entry; } @@ -159,9 +166,9 @@ void tc_create_blocks() tc_image_s *grass_texture = tc_resolve_name_to_image("grass"); tc_image_s *stone_texture = tc_resolve_name_to_image("stone"); - tc_cube_info_s dirt = tc_gen_unitexture_cube_info("Dirt", 1, dirt_texture->image_id); - tc_cube_info_s grass = tc_gen_unitexture_cube_info("Grass", 2, grass_texture->image_id); - tc_cube_info_s stone = tc_gen_unitexture_cube_info("Stone", 3, stone_texture->image_id); + tc_cube_info_s dirt = tc_gen_unitexture_cube_info("Dirt", 1 | TC_BLOCK_OPAQUE_BIT, dirt_texture->image_id); + tc_cube_info_s grass = tc_gen_unitexture_cube_info("Grass", 2 | TC_BLOCK_OPAQUE_BIT, grass_texture->image_id); + tc_cube_info_s stone = tc_gen_unitexture_cube_info("Stone", 3 | TC_BLOCK_OPAQUE_BIT, stone_texture->image_id); tc_new_cube_block(dirt); tc_new_cube_block(grass); diff --git a/code/source-c/blocks.h b/code/source-c/blocks.h index a70431b..f897eb3 100644 --- a/code/source-c/blocks.h +++ b/code/source-c/blocks.h @@ -7,6 +7,19 @@ #include +#define TC_BLOCK_OPAQUE_BIT (1 << 31) + +typedef struct tc_cube_side_mesh +{ + uint32_t num_vertices; + + float *allocation; + + float *uv; + float *xyz; + +} tc_cube_side_mesh_s; + typedef struct tc_block_attribute { char *name; @@ -73,5 +86,9 @@ tc_cube_info_s tc_gen_unitexture_cube_info tc_block_entry_s * tc_new_cube_block (tc_cube_info_s info); void tc_create_blocks (); +// tc_premesh_cube: Creates a cube's mesh in advance so it is faster when generating a chunk. +// This is already being done by tc_new_cube_block. +void tc_premesh_cube (tc_block_entry_s *entry); + #endif diff --git a/code/source-c/chunk_loader.c b/code/source-c/chunk_loader.c index d9a3efc..0b3fa6e 100644 --- a/code/source-c/chunk_loader.c +++ b/code/source-c/chunk_loader.c @@ -158,21 +158,27 @@ void tc_reload_chunkloader_zone(tc_chunkloader_s *loader) tc_load_all_chunks_of_chunkloader(loader); } +uint64_t world_update_tick = 0; + void tc_update_world(tc_world_s *world) -{ - world->loaders[0].center.x = world->loading_center.x; - world->loaders[0].center.y = world->loading_center.y; - world->loaders[0].center.z = world->loading_center.z; - - uint32_t chunkloader_index = 0; - while(chunkloader_index < world->num_loaders) +{ + if((world_update_tick == 0))// % 512) == 0) { - if(world->loaders[chunkloader_index].needs_reload) + world->loaders[0].center.x = world->loading_center.x; + world->loaders[0].center.y = world->loading_center.y; + world->loaders[0].center.z = world->loading_center.z; + + uint32_t chunkloader_index = 0; + while(chunkloader_index < world->num_loaders) { - tc_reload_chunkloader_zone(&world->loaders[chunkloader_index]); + if(world->loaders[chunkloader_index].needs_reload) + { + tc_reload_chunkloader_zone(&world->loaders[chunkloader_index]); + } + ++chunkloader_index; } - ++chunkloader_index; } + ++world_update_tick; } // TODO: Set center chunk diff --git a/code/source-c/cube_premeshing.c b/code/source-c/cube_premeshing.c new file mode 100644 index 0000000..9a8881d --- /dev/null +++ b/code/source-c/cube_premeshing.c @@ -0,0 +1,262 @@ +#include "blocks.h" +#include "state.h" + +float tc_cube_front_uv[12] = +{ + 0.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, + + 1.0f, 1.0f, + 1.0f, 0.0f, + 0.0f, 1.0f +}; + +float tc_cube_front_xyz[18] = +{ + -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 +}; + + + +float tc_cube_back_uv[12] = +{ + 1.0f, 0.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, + + 0.0f, 1.0f, + 1.0f, 0.0f, + 1.0f, 1.0f +}; + +float tc_cube_back_xyz[18] = +{ + 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 +}; + + + +float tc_cube_west_uv[12] = +{ + // Left + 1.0f, 0.0f, + 0.0f, 0.0f, + 0.0f, 1.0f, + + 0.0f, 1.0f, + 1.0f, 1.0f, + 1.0f, 0.0f +}; + +float tc_cube_west_xyz[18] = +{ + -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 +}; + + + +float tc_cube_east_uv[12] = +{ + // Right + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, + + 1.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f +}; + +float tc_cube_east_xyz[18] = +{ + 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 +}; + + + +float tc_cube_top_uv[12] = +{ + // Top + 0.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, + + 0.0f, 1.0f, + 1.0f, 1.0f, + 1.0f, 0.0f +}; + +float tc_cube_top_xyz[18] = +{ + -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 +}; + + + +float tc_cube_bottom_uv[12] = +{ + // Bottom + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f, + + 1.0f, 1.0f, + 0.0f, 1.0f, + 1.0f, 0.0f +}; + +float tc_cube_bottom_xyz[18] = +{ + -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 +}; + + + +void tc_adjust_cube_uvs_for_image(tc_image_s *image, float *face_uvs) +{ + float lower_x = ((float) image->x) / ((float) image->width); + float lower_y = ((float) image->y) / ((float) image->height); + float higher_x; + float higher_y; + + if(image->superimage != NULL) + { + higher_x = (((float) (image->x + image->width)) / ((float) image->superimage->width)); + higher_y = (((float) (image->y + image->height)) / ((float) image->superimage->height)); + } + else + { + higher_x = 1.0f; + higher_y = 1.0f; + } + + uint32_t num_floats = 2 * 6; + uint32_t index = 0; + + while(index < num_floats) + { + if(face_uvs[index] == 1.0f) + { + face_uvs[index] = higher_x; + } + else + { + face_uvs[index] = lower_x; + } + + ++index; + + if(face_uvs[index] == 1.0f) + { + face_uvs[index] = higher_y; + } + else + { + face_uvs[index] = lower_y; + } + ++index; + } +} + +tc_cube_side_mesh_s * tc_premesh_cube_block_side( + tc_image_s *image, float *xyz, float *uv, uint32_t num_vertices +) { + tc_cube_side_mesh_s *side = malloc(sizeof(tc_cube_side_mesh_s)); + side->num_vertices = num_vertices; + side->allocation = malloc(sizeof(float) * num_vertices * (2+3)); + + side->xyz = side->allocation; + memcpy(side->xyz, xyz, sizeof(float) * num_vertices * 3); + side->uv = &side->allocation[num_vertices*3]; + memcpy(side->uv, uv, sizeof(float) * num_vertices * 2); + + tc_adjust_cube_uvs_for_image(image, side->uv); + + return side; +} + +void tc_premesh_cube(tc_block_entry_s *entry) +{ + tc_image_s *front_texture = tc_block_resolve_name_to_attribute(entry, "front_texture")->value.pointer; + tc_image_s *back_texture = tc_block_resolve_name_to_attribute(entry, "back_texture")->value.pointer; + tc_image_s *west_texture = tc_block_resolve_name_to_attribute(entry, "west_texture")->value.pointer; + tc_image_s *east_texture = tc_block_resolve_name_to_attribute(entry, "east_texture")->value.pointer; + tc_image_s *top_texture = tc_block_resolve_name_to_attribute(entry, "top_texture")->value.pointer; + tc_image_s *bottom_texture = tc_block_resolve_name_to_attribute(entry, "bottom_texture")->value.pointer; + + tc_cube_side_mesh_s *front = tc_premesh_cube_block_side(front_texture, tc_cube_front_xyz, tc_cube_front_uv, 6); + tc_cube_side_mesh_s *back = tc_premesh_cube_block_side(back_texture, tc_cube_back_xyz, tc_cube_back_uv, 6); + tc_cube_side_mesh_s *west = tc_premesh_cube_block_side(west_texture, tc_cube_west_xyz, tc_cube_west_uv, 6); + tc_cube_side_mesh_s *east = tc_premesh_cube_block_side(east_texture, tc_cube_east_xyz, tc_cube_east_uv, 6); + tc_cube_side_mesh_s *top = tc_premesh_cube_block_side(top_texture, tc_cube_top_xyz, tc_cube_top_uv, 6); + tc_cube_side_mesh_s *bottom = tc_premesh_cube_block_side(bottom_texture, tc_cube_bottom_xyz, tc_cube_bottom_uv, 6); + + tc_block_attribute_s front_attribute; + front_attribute.name = "south_mesh"; + front_attribute.value.pointer = front; + + tc_block_attribute_s back_attribute; + back_attribute.name = "north_mesh"; + back_attribute.value.pointer = back; + + tc_block_attribute_s west_attribute; + west_attribute.name = "west_mesh"; + west_attribute.value.pointer = west; + + tc_block_attribute_s east_attribute; + east_attribute.name = "east_mesh"; + east_attribute.value.pointer = east; + + tc_block_attribute_s top_attribute; + top_attribute.name = "top_mesh"; + top_attribute.value.pointer = top; + + tc_block_attribute_s bottom_attribute; + bottom_attribute.name = "bottom_mesh"; + bottom_attribute.value.pointer = bottom; + + tc_add_attribute_to_block_entry(entry, front_attribute); + tc_add_attribute_to_block_entry(entry, back_attribute); + tc_add_attribute_to_block_entry(entry, east_attribute); + tc_add_attribute_to_block_entry(entry, west_attribute); + tc_add_attribute_to_block_entry(entry, top_attribute); + tc_add_attribute_to_block_entry(entry, bottom_attribute); +} + diff --git a/code/source-c/default_terrain_generator.c b/code/source-c/default_terrain_generator.c index 0ec4aec..1b79b57 100644 --- a/code/source-c/default_terrain_generator.c +++ b/code/source-c/default_terrain_generator.c @@ -3,7 +3,7 @@ bool tc_generate_default_terrain_chunk(tc_worldgen_s *gen, tc_chunk_s *chunk) { tc_block_s block; - block.type_identifier = 1; + block.type_identifier = 1 | TC_BLOCK_OPAQUE_BIT; block.position.x = 0.0f; block.position.y = 0.0f; block.position.z = 0.0f; diff --git a/code/source-c/initialization.c b/code/source-c/initialization.c index 7195991..014105b 100644 --- a/code/source-c/initialization.c +++ b/code/source-c/initialization.c @@ -30,8 +30,8 @@ void tc_init_renderer(techneck_s *techneck) techneck->renderer.draw_shader = tc_make_shader_program("vertex_shader.glsl", "fragment_shader.glsl"); glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); + //glEnable(GL_CULL_FACE); + //glCullFace(GL_BACK); } void tc_load_textures() diff --git a/code/source-c/meshize.c b/code/source-c/meshize.c index f547bc5..bd79ae2 100644 --- a/code/source-c/meshize.c +++ b/code/source-c/meshize.c @@ -1,122 +1,42 @@ +#include "blocks.h" #include "world.h" #include "assets.h" #include #include -float tc_block_vertices[108] = +bool tc_block_is_opaque_by_id(uint32_t id) { - // 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 -}; + return !!(id & TC_BLOCK_OPAQUE_BIT); +} -float tc_generic_cube_uvs[72] = +uint32_t tc_count_vertices_of_block(tc_chunk_s *chunk, uint8_t x, uint8_t y, uint8_t z) { - // Front - 0.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, + uint32_t num_vertices = 0; - 1.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, + uint32_t top_neighbour = 0; + uint32_t bottom_neighbour = 0; + uint32_t north_neighbour = 0; + uint32_t south_neighbour = 0; + uint32_t east_neighbour = 0; + uint32_t west_neighbour = 0; - // Back - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, + if(x < 31) east_neighbour = chunk->blocks[x+1] [y] [z]; + if(x > 0) west_neighbour = chunk->blocks[x-1] [y] [z]; + if(y < 31) top_neighbour = chunk->blocks[x] [y+1] [z]; + if(y > 0) bottom_neighbour = chunk->blocks[x] [y-1] [z]; + if(z < 31) north_neighbour = chunk->blocks[x] [y] [z+1]; + if(z > 0) south_neighbour = chunk->blocks[x] [y] [z-1]; - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, + if(!tc_block_is_opaque_by_id(top_neighbour)) num_vertices += 6; + if(!tc_block_is_opaque_by_id(bottom_neighbour)) num_vertices += 6; + if(!tc_block_is_opaque_by_id(north_neighbour)) num_vertices += 6; + if(!tc_block_is_opaque_by_id(south_neighbour)) num_vertices += 6; + if(!tc_block_is_opaque_by_id(east_neighbour)) num_vertices += 6; + if(!tc_block_is_opaque_by_id(west_neighbour)) num_vertices += 6; - // Left - 1.0f, 0.0f, - 0.0f, 0.0f, - 0.0f, 1.0f, - - 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, - - // Right - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - - 1.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - - // Top - 0.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - - 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, - - // Bottom - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - - 1.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 0.0f -}; + return num_vertices; +} uint32_t tc_count_chunk_vertices(tc_chunk_s *chunk) { @@ -133,9 +53,9 @@ uint32_t tc_count_chunk_vertices(tc_chunk_s *chunk) z_in_chunk = 0; while(z_in_chunk < 32) { - if(chunk->blocks[x_in_chunk][y_in_chunk][z_in_chunk] > 0) + if(chunk->blocks[x_in_chunk][y_in_chunk][z_in_chunk] != 0) { - num_vertices += 36; + num_vertices += tc_count_vertices_of_block(chunk, x_in_chunk, y_in_chunk, z_in_chunk); } ++z_in_chunk; } @@ -146,83 +66,126 @@ uint32_t tc_count_chunk_vertices(tc_chunk_s *chunk) return num_vertices; } -void tc_modify_basic_cube_face_uvs_to_fit(tc_image_s *image, float *face_uvs) +void printfloatarr(float *arr, uint32_t num) { - float lower_x = ((float) image->x) / ((float) image->width); - float lower_y = ((float) image->y) / ((float) image->height); - float higher_x; - float higher_y; - - if(image->superimage != NULL) - { - higher_x = (((float) (image->x + image->width)) / ((float) image->superimage->width)); - higher_y = (((float) (image->y + image->height)) / ((float) image->superimage->height)); - } - else - { - higher_x = 1.0f; - higher_y = 1.0f; - } - - uint32_t num_floats = 2 * 6; - uint32_t index = 0; - - while(index < num_floats) - { - if(face_uvs[index] == 1.0f) - { - face_uvs[index] = higher_x; - } - else - { - face_uvs[index] = lower_x; - } - - ++index; - - if(face_uvs[index] == 1.0f) - { - face_uvs[index] = higher_y; - } - else - { - face_uvs[index] = lower_y; - } - ++index; - } + for(int i = 0; i < num; ++i) + printf("%f ", arr[i]); } -void tc_generate_basic_cube_uvs(tc_block_entry_s *entry, float *block_uvs) +uint32_t tc_meshize_block(tc_chunk_s *chunk, + uint8_t x, uint8_t y, uint8_t z, + float *xyz, float *uv) { - uint32_t num_floats = 2 * 36; - memcpy(block_uvs, tc_generic_cube_uvs, sizeof(float) * num_floats); + tc_block_entry_s *entry = + tc_resolve_id_to_block_entry( + chunk->blocks[x][y][z] + ); - tc_block_attribute_s *front = tc_block_resolve_name_to_attribute(entry, "front_texture"); - tc_block_attribute_s *back = tc_block_resolve_name_to_attribute(entry, "back_texture"); - tc_block_attribute_s *west = tc_block_resolve_name_to_attribute(entry, "west_texture"); - tc_block_attribute_s *east = tc_block_resolve_name_to_attribute(entry, "east_texture"); - tc_block_attribute_s *top = tc_block_resolve_name_to_attribute(entry, "top_texture"); - tc_block_attribute_s *bottom = tc_block_resolve_name_to_attribute(entry, "bottom_texture"); + if(entry == NULL) + { + return 0; + } - uint32_t num_floats_per_face = 2 * 6; + uint32_t num_vertices = 0; - tc_modify_basic_cube_face_uvs_to_fit(front->value.pointer, &block_uvs[0]); - tc_modify_basic_cube_face_uvs_to_fit(back->value.pointer, &block_uvs[num_floats_per_face]); - tc_modify_basic_cube_face_uvs_to_fit(west->value.pointer, &block_uvs[num_floats_per_face*2]); - tc_modify_basic_cube_face_uvs_to_fit(east->value.pointer, &block_uvs[num_floats_per_face*3]); - tc_modify_basic_cube_face_uvs_to_fit(top->value.pointer, &block_uvs[num_floats_per_face*4]); - tc_modify_basic_cube_face_uvs_to_fit(bottom->value.pointer, &block_uvs[num_floats_per_face*5]); + uint32_t top_neighbour = 0; + uint32_t bottom_neighbour = 0; + uint32_t north_neighbour = 0; + uint32_t south_neighbour = 0; + uint32_t east_neighbour = 0; + uint32_t west_neighbour = 0; + + if(x < 31) east_neighbour = chunk->blocks[x+1] [y] [z]; + if(x > 0) west_neighbour = chunk->blocks[x-1] [y] [z]; + if(y < 31) top_neighbour = chunk->blocks[x] [y+1] [z]; + if(y > 0) bottom_neighbour = chunk->blocks[x] [y-1] [z]; + if(z < 31) north_neighbour = chunk->blocks[x] [y] [z+1]; + if(z > 0) south_neighbour = chunk->blocks[x] [y] [z-1]; + + if(!tc_block_is_opaque_by_id(top_neighbour)) + { + tc_cube_side_mesh_s *side_mesh = + tc_block_resolve_name_to_attribute(entry, "top_mesh")->value.pointer; + + memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); + memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); + num_vertices += side_mesh->num_vertices; + } + + if(!tc_block_is_opaque_by_id(bottom_neighbour)) + { + tc_cube_side_mesh_s *side_mesh = + tc_block_resolve_name_to_attribute(entry, "bottom_mesh")->value.pointer; + + memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); + memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); + num_vertices += side_mesh->num_vertices; + } + + if(!tc_block_is_opaque_by_id(south_neighbour)) + { + tc_cube_side_mesh_s *side_mesh = + tc_block_resolve_name_to_attribute(entry, "south_mesh")->value.pointer; + + memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); + memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); + num_vertices += side_mesh->num_vertices; + } + + if(!tc_block_is_opaque_by_id(north_neighbour)) + { + tc_cube_side_mesh_s *side_mesh = + tc_block_resolve_name_to_attribute(entry, "north_mesh")->value.pointer; + + memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); + memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); + num_vertices += side_mesh->num_vertices; + } + + if(!tc_block_is_opaque_by_id(east_neighbour)) + { + tc_cube_side_mesh_s *side_mesh = + tc_block_resolve_name_to_attribute(entry, "east_mesh")->value.pointer; + + memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); + memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); + num_vertices += side_mesh->num_vertices; + } + + if(!tc_block_is_opaque_by_id(west_neighbour)) + { + tc_cube_side_mesh_s *side_mesh = + tc_block_resolve_name_to_attribute(entry, "west_mesh")->value.pointer; + + memcpy(&xyz[num_vertices*3], side_mesh->xyz, sizeof(float) * side_mesh->num_vertices * 3); + memcpy(&uv[num_vertices*2], side_mesh->uv, sizeof(float) * side_mesh->num_vertices * 2); + num_vertices += side_mesh->num_vertices; + } + + + uint32_t vertex_of_block = 0; + + vertex_of_block = 0; + while(vertex_of_block < num_vertices) + { + xyz[vertex_of_block*3 + 0] += (float) x; + xyz[vertex_of_block*3 + 1] += (float) y; + xyz[vertex_of_block*3 + 2] += (float) z; + ++vertex_of_block; + } + + 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); - chunk->vertex_uvs = malloc(sizeof(float) * (2) * chunk->num_vertices); + chunk->vertex_positions = calloc(sizeof(float), 3 * chunk->num_vertices); + chunk->vertex_uvs = calloc(sizeof(float), 2 * chunk->num_vertices); uint32_t vertex_index = 0; - float block_positions[36*3]; - float block_uvs[36*2]; + float block_positions[1024]; + float block_uvs[1024]; uint32_t x_in_chunk = 0; uint32_t y_in_chunk = 0; @@ -256,42 +219,22 @@ void tc_meshize_chunk(tc_chunk_s *chunk) if(!strcmp(block->value.string, "basic_cube")) { - 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(block_uvs, tc_generic_cube_uvs, sizeof(float) * 36 * 2); - tc_generate_basic_cube_uvs(entry, block_uvs); + memset(block_positions, 0x00, sizeof(float) * 1024); + memset(block_uvs, 0x00, sizeof(float) * 1024); + uint32_t made_vertices = tc_meshize_block(chunk, x_in_chunk, y_in_chunk, z_in_chunk, block_positions, block_uvs); memcpy( &chunk->vertex_positions[vertex_index*3], block_positions, - sizeof(float) * 36 * 3 + sizeof(float) * made_vertices * 3 ); memcpy( &chunk->vertex_uvs[vertex_index*2], block_uvs, - sizeof(float) * 36 * 2 + sizeof(float) * made_vertices * 2 ); - vertex_index += 36; + vertex_index += made_vertices; } ++z_in_chunk; }