#include #include #include #include #include #include #include #include #include namespace deerith { std::unordered_map, ivec3_hash_t> loaded_clusters; void render_cluster(glm::ivec3); } void deerith::shutdown_environment() { loaded_clusters.clear(); } void deerith::flush_cluster_to_gpu() { std::lock_guard lock(cluster_workers_mutex); for (std::unique_ptr &cluster_generator : cluster_workers) { glm::ivec3 cluster_position; cluster_position.x = cluster_generator->cluster->surface_id.x; cluster_position.z = cluster_generator->cluster->surface_id.y; cluster_position.y = cluster_generator->cluster->layer; loaded_clusters[cluster_position] = std::make_unique(cluster_generator->build_data); } cluster_workers.clear(); } void deerith::render_clusters(glm::ivec3 position, int rad, const camera_t &camera) { texture_t *voxel_texture = get_voxel_texture(); get_voxel_shader()->use(); get_voxel_shader()->set_vec4("u_color", glm::vec4(1, 0.4f, 0.6f, 1)); set_camera_to_shader(camera, get_voxel_shader()); if (voxel_texture) { voxel_texture->bind(0); get_voxel_shader()->set_int("u_texture", 0); } // Radial outward for (int r = 0; r < rad; r++) { for (int x = -r; x <= r; x++) { for (int y = -r; y <= r; y++) { for (int z = -r; z <= r; z++) { // Only process the current outer layer if (std::max({std::abs(x), std::abs(y), std::abs(z)}) != r) { continue; } glm::ivec3 cluster_position = position + glm::ivec3(x, y, z); render_cluster(cluster_position); } } } } } void deerith::render_cluster(glm::ivec3 pos) { if (!loaded_clusters.contains(pos)) { return; } std::unique_ptr &cluster_mesh = loaded_clusters[pos]; float offset = static_cast(CLUSTER_SIZE) * static_cast(VOXEL_SIZE); glm::vec3 position = glm::vec3(offset * static_cast(pos.x), offset * static_cast(pos.y), offset * static_cast(pos.z)); glm::quat rotation = glm::identity(); glm::vec3 scale = glm::vec3(1, 1, 1); set_transform_to_shader(position, rotation, scale, get_voxel_shader()); cluster_mesh->draw(); }