#include #include #include #include #include #include #include tc_entity_type_s *tc_chunk_entity_type_g = NULL; // entity/chunk.c: Functions for the Chunk's entity-type. // The userdata should be the corresponding world void tc_create_chunk_entity(tc_entity_s *entity, void *userdata) { tc_chunk_s *chunk = tc_allocate_chunk(); tc_world_s *world = userdata; entity->specific = chunk; chunk->location.world = world; chunk->refcounter = 1; chunk->is_renderable = TRUE; tc_set_integer_for_entity(entity, "grid_x", 0); tc_set_integer_for_entity(entity, "grid_y", 0); tc_set_integer_for_entity(entity, "grid_z", 0); tc_run_hooklist(&world->on_chunk_create, entity); } void tc_delete_chunk_entity(tc_entity_s *entity) { tc_chunk_s *chunk = entity->specific; tc_world_s *world = chunk->location.world; tc_run_hooklist(&world->on_chunk_delete, entity); if(chunk->vao != 0) glDeleteVertexArrays(1, &chunk->vao); if(chunk->vbo != 0) glDeleteBuffers(1, &chunk->vbo); if(chunk->vertex_positions != NULL) free(chunk->vertex_positions); if(chunk->vertex_uvs != NULL) free(chunk->vertex_uvs); tc_physics_entity_s *physics_body = tc_get_pointer_from_entity(entity, "physics_body"); if(physics_body != 0) { tc_remove_physics_entity(physics_body); } tc_deallocate_chunk(entity->specific); } void tc_draw_chunk_entity(tc_entity_s *entity) { tc_chunk_s *chunk = entity->specific; tc_mat4f_s model_matrix = tc_mat4f_identity(); tc_vec3f_s position_3f; position_3f.x = ((float) tc_get_integer_from_entity(entity, "grid_x")) * 32.0f; position_3f.y = ((float) tc_get_integer_from_entity(entity, "grid_y")) * 32.0f; position_3f.z = ((float) tc_get_integer_from_entity(entity, "grid_z")) * 32.0f; model_matrix = tc_mat4f_translate(model_matrix, position_3f); tc_shader_uniform_mat4f(&tc_game_state_g.renderer.draw_shader, "model_matrix", model_matrix); glBindBuffer(GL_ARRAY_BUFFER, chunk->vbo); 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_generate_chunk_entity(tc_chunk_s *chunk) { tc_world_s *world = chunk->location.world; tc_run_hooklist(&world->before_chunk_generate, chunk); world->worldgen->fn_generate_chunk(world->worldgen, chunk); tc_run_hooklist(&world->after_chunk_generate, chunk); } void tc_meshize_chunk_entity(tc_chunk_s *chunk) { if(chunk->vertex_positions != NULL) free(chunk->vertex_positions); if(chunk->vertex_uvs != NULL) free(chunk->vertex_uvs); tc_meshize_chunk(chunk); } void tc_receive_chunk_entity_event(tc_entity_s *entity, tc_entity_event_s event) { tc_chunk_s *chunk = entity->specific; if(!strcmp(event.identifier, "draw")) tc_draw_chunk_entity(entity); if(!strcmp(event.identifier, "generate")) tc_generate_chunk_entity(chunk); if(!strcmp(event.identifier, "meshize")) tc_meshize_chunk_entity(chunk); if(!strcmp(event.identifier, "gl_upload")) tc_upload_chunk(chunk); } void tc_register_chunk_entity() { tc_fn_entity_s chunk_functions; chunk_functions.fn_create = &tc_create_chunk_entity; chunk_functions.fn_delete = &tc_delete_chunk_entity; chunk_functions.fn_send_event = &tc_receive_chunk_entity_event; tc_entity_type_s chunk_type; chunk_type.internal_name = "chunk"; chunk_type.display_name = NULL; chunk_type.functions = chunk_functions; chunk_type.instances_capacity = 512; tc_register_entity_type(chunk_type); tc_chunk_entity_type_g = tc_get_entity_type_with_name("chunk"); }