#include "world.h" #include "state.h" #include #include tc_worldgen_s tc_default_terrain_generator_g; void tc_upload_chunk(tc_chunk_s *chunk) { // If the chunk has no mesh yet if(chunk->num_vertices == 0) { // Create one tc_meshize_chunk(chunk); } if(chunk->vao != 0) glDeleteVertexArrays(1, &chunk->vao); if(chunk->vertex_data != 0) glDeleteBuffers(1, &chunk->vertex_data); 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 * 5 * sizeof(float), NULL, GL_STATIC_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, chunk->num_vertices * 3 * sizeof(float), chunk->vertex_positions ); glBufferSubData(GL_ARRAY_BUFFER, chunk->num_vertices * 3 * sizeof(float), chunk->num_vertices * 2 * sizeof(float), chunk->vertex_uvs ); glBindVertexArray(0); } void tc_draw_chunk(tc_chunk_s *chunk, tc_world_s *world) { mat4x4 model_matrix; mat4x4_identity(model_matrix); mat4x4_translate_in_place(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); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *) (sizeof(float) * 3 * chunk->num_vertices) ); glEnableVertexAttribArray(1); glActiveTexture(GL_TEXTURE0); glUniform1i( glGetUniformLocation(tc_game_state_g.renderer.draw_shader.program_id, "block_atlas"), 0 ); glBindTexture(GL_TEXTURE_2D, tc_game_state_g.block_texture_atlas->gl_identifier); 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; } void tc_init_worlds() { tc_init_world_generators(); } void tc_set_block_in_chunk( tc_chunk_s *chunk, uint8_t x, uint8_t y, uint8_t z, tc_block_s block ) { chunk->blocks[x][y][z] = block.type_identifier; } void tc_draw_world(tc_world_s *world) { for(uint32_t loader_index = 0; loader_index < world->num_loaders; ++loader_index) for(uint32_t chunk_index = 0; chunk_index < world->loaders[loader_index].num_chunks; ++chunk_index) tc_draw_chunk(world->loaders[loader_index].chunks[chunk_index], world); } tc_chunkloader_s tc_create_chunkloader(tc_world_s *world) { tc_chunkloader_s loader; loader.extent.x = UPDATE_DISTANCE * 2 + 1; loader.extent.y = UPDATE_DISTANCE * 2 + 1; loader.extent.z = UPDATE_DISTANCE * 2 + 1; loader.center.x = 0; loader.center.y = 0; loader.center.z = 0; loader.chunks_capacity = 512; loader.chunks = calloc(sizeof(tc_chunk_s *), loader.chunks_capacity); loader.num_chunks = 0; loader.needs_reload = false; return loader; } tc_chunkloader_s tc_create_spawn_loader(tc_world_s *world) { tc_chunkloader_s loader = tc_create_chunkloader(world); loader.needs_reload = true; loader.world = world; return loader; } tc_world_s * tc_new_world(tc_worldgen_s *generator) { tc_world_s *world = calloc(sizeof(tc_world_s), 1); world->pool = tc_new_chunk_pool(512); world->worldgen = &tc_default_terrain_generator_g; world->num_loaders = 1; world->loaders = malloc(sizeof(tc_chunkloader_s) * world->num_loaders); world->loaders[0] = tc_create_spawn_loader(world); world->spawn_loader = &world->loaders[0]; return world; }