94 lines
2.8 KiB
C++
94 lines
2.8 KiB
C++
#include <deerith/client/cluster.h>
|
|
#include <deerith/world/environment.h>
|
|
#include <unordered_map>
|
|
|
|
#include <deerith/client/graphics/shader.h>
|
|
#include <deerith/client/graphics/camera.h>
|
|
#include <deerith/client/graphics/mesh.h>
|
|
#include <deerith/client/graphics/primitive.h>
|
|
#include <deerith/client/internals/world.h>
|
|
#include <deerith/client/cluster.h>
|
|
|
|
namespace deerith
|
|
{
|
|
std::unordered_map<glm::ivec3, std::unique_ptr<mesh_3d_t>, 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<std::mutex> lock(cluster_workers_mutex);
|
|
|
|
for (std::unique_ptr<cluster_generator_t> &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<mesh_3d_t>(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<mesh_3d_t> &cluster_mesh = loaded_clusters[pos];
|
|
|
|
float offset = static_cast<float>(CLUSTER_SIZE) * static_cast<float>(VOXEL_SIZE);
|
|
glm::vec3 position = glm::vec3(offset * static_cast<float>(pos.x), offset * static_cast<float>(pos.y), offset * static_cast<float>(pos.z));
|
|
glm::quat rotation = glm::identity<glm::quat>();
|
|
glm::vec3 scale = glm::vec3(1, 1, 1);
|
|
|
|
set_transform_to_shader(position, rotation, scale, get_voxel_shader());
|
|
cluster_mesh->draw();
|
|
} |