gen_chunk *get_gen_chunk_for_coord(int x, int y) { gen_chunk_cache *gcc = get_gen_chunk_cache_for_coord(x,y); if (gcc == NULL) { gcc = put_chunk_in_cache(x, y, generate_chunk(x, y)); } assert(gcc->chunk_x*GEN_CHUNK_SIZE_X == x && gcc->chunk_y*GEN_CHUNK_SIZE_Y == y); return gcc->chunk; }
int mesh_worker_handler(void *data) { for(;;) { task t; if (get_pending_task(&t)) { switch (t.task_type) { case JOB_build_mesh: { stbvox_mesh_maker mm; mesh_chunk *mc = malloc(sizeof(*mc)); built_mesh out_mesh; vec3i wc = { t.world_x, t.world_y, 0 }; stbvox_init_mesh_maker(&mm); mc->chunk_x = t.world_x >> MESH_CHUNK_CACHE_X_LOG2; mc->chunk_y = t.world_y >> MESH_CHUNK_CACHE_Y_LOG2; generate_mesh_for_chunk_set(&mm, mc, wc, &t.cs, vertex_build_buffer, sizeof(vertex_build_buffer), face_buffer); out_mesh.vertex_build_buffer = malloc(mc->num_quads * 16); out_mesh.face_buffer = malloc(mc->num_quads * 4); memcpy(out_mesh.vertex_build_buffer, vertex_build_buffer, mc->num_quads * 16); memcpy(out_mesh.face_buffer, face_buffer, mc->num_quads * 4); { int i; for (i=0; i < 16; ++i) release_gen_chunk(t.cs.chunk[0][i]); } out_mesh.mc = mc; if (!add_to_queue(&built_meshes, &out_mesh)) { free(out_mesh.vertex_build_buffer); free(out_mesh.face_buffer); } else waiter_wake(&manager_monitor); break; } case JOB_generate_terrain: { finished_gen_chunk fgc; fgc.world_x = t.world_x; fgc.world_y = t.world_y; fgc.gc = generate_chunk(t.world_x, t.world_y); if (!add_to_queue(&finished_gen, &fgc)) release_gen_chunk(fgc.gc); else { ++fgc.gc->ref_count; waiter_wake(&manager_monitor); } break; } } } } }
// {{{ generate size_t generate(cnf_t *config) { size_t written; written = 0; /** At first fill chunks in all parallel threads. * If no size is specified, then the program * will never get over this. */ written = generate_chunk(config); /** Then fill the few ending bytes in one thread. */ written += generate_ending(config); return written; }
int mesh_worker_handler(void *data) { for(;;) { task t; if (get_pending_task(&t)) { switch (t.task_type) { case JOB_build_mesh: { stbvox_mesh_maker mm; mesh_chunk *mc = malloc(sizeof(*mc)); built_mesh out_mesh; vec3i wc = { t.world_x, t.world_y, 0 }; stbvox_init_mesh_maker(&mm); mc->chunk_x = t.world_x >> MESH_CHUNK_CACHE_X_LOG2; mc->chunk_y = t.world_y >> MESH_CHUNK_CACHE_Y_LOG2; generate_mesh_for_chunk_set(&mm, mc, wc, &t.cs, vertex_build_buffer, sizeof(vertex_build_buffer), face_buffer); out_mesh.vertex_build_buffer = malloc(mc->num_quads * 16); out_mesh.face_buffer = malloc(mc->num_quads * 4); memcpy(out_mesh.vertex_build_buffer, vertex_build_buffer, mc->num_quads * 16); memcpy(out_mesh.face_buffer, face_buffer, mc->num_quads * 4); out_mesh.mc = mc; if (!add_built_mesh(&out_mesh)) { free(out_mesh.vertex_build_buffer); free(out_mesh.face_buffer); } break; } case JOB_generate_terrain: { finished_gen_chunk fgc; fgc.world_x = t.world_x; fgc.world_y = t.world_y; fgc.gc = generate_chunk(t.world_x, t.world_y); if (!add_gen(fgc)) free(fgc.gc); break; } } } } }