mountains
This commit is contained in:
parent
fad6f4d697
commit
b7165d226a
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
build/
|
build/
|
||||||
|
textures/
|
||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <deerith/world/environment.h>
|
#include <deerith/world/environment.h>
|
||||||
#include <deerith/client/graphics/mesh.h>
|
#include <deerith/client/graphics/mesh.h>
|
||||||
|
#include <deerith/client/graphics/camera.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
namespace deerith
|
namespace deerith
|
||||||
@ -16,9 +17,9 @@ namespace deerith
|
|||||||
};
|
};
|
||||||
|
|
||||||
void generate_cluster(voxel_cluster_t *cluster);
|
void generate_cluster(voxel_cluster_t *cluster);
|
||||||
void render_clusters(glm::ivec3 position, int rad);
|
void render_clusters(glm::ivec3 position, int rad, const camera_t &);
|
||||||
void flush_cluster_to_gpu();
|
void flush_cluster_to_gpu();
|
||||||
void clear_all_clusters();
|
void shutdown_environment();
|
||||||
|
|
||||||
extern std::mutex cluster_workers_mutex;
|
extern std::mutex cluster_workers_mutex;
|
||||||
extern std::vector<std::unique_ptr<cluster_generator_t>> cluster_workers;
|
extern std::vector<std::unique_ptr<cluster_generator_t>> cluster_workers;
|
||||||
|
|||||||
@ -56,5 +56,4 @@ namespace deerith
|
|||||||
size_t index_count = 0;
|
size_t index_count = 0;
|
||||||
size_t vertex_count = 0;
|
size_t vertex_count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
17
deerith_client/include/deerith/client/graphics/texture.h
Normal file
17
deerith_client/include/deerith/client/graphics/texture.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <deerith/engine.h>
|
||||||
|
|
||||||
|
namespace deerith
|
||||||
|
{
|
||||||
|
class texture_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
texture_t(const uint8_t *__data, int width, int height, int channels = 4, int max_mip_map = 0);
|
||||||
|
|
||||||
|
void bind(int);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t texture_id;
|
||||||
|
int max_mip_map = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -12,11 +12,17 @@ namespace deerith
|
|||||||
glm::ivec3(0, 0, 1),
|
glm::ivec3(0, 0, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
glm::vec2 voxel_uv_order[4] = {
|
||||||
|
glm::vec2(0.0f, 0.0f),
|
||||||
|
glm::vec2(1.0f, 0.0f),
|
||||||
|
glm::vec2(0.0f, 1.0f),
|
||||||
|
glm::vec2(1.0f, 1.0f),
|
||||||
|
};
|
||||||
glm::vec3 voxel_direction_vertices[6][4] = {
|
glm::vec3 voxel_direction_vertices[6][4] = {
|
||||||
// -X
|
// -X
|
||||||
{
|
{
|
||||||
{0, 0, 0},
|
|
||||||
{0, 0, 1},
|
{0, 0, 1},
|
||||||
|
{0, 0, 0},
|
||||||
{0, 1, 1},
|
{0, 1, 1},
|
||||||
{0, 1, 0},
|
{0, 1, 0},
|
||||||
},
|
},
|
||||||
@ -24,39 +30,39 @@ namespace deerith
|
|||||||
// +X
|
// +X
|
||||||
{
|
{
|
||||||
{1, 0, 0},
|
{1, 0, 0},
|
||||||
|
{1, 0, 1},
|
||||||
{1, 1, 0},
|
{1, 1, 0},
|
||||||
{1, 1, 1},
|
{1, 1, 1},
|
||||||
{1, 0, 1},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// -Y
|
// -Y
|
||||||
{
|
{
|
||||||
|
{0, 0, 1},
|
||||||
|
{1, 0, 1},
|
||||||
{0, 0, 0},
|
{0, 0, 0},
|
||||||
{1, 0, 0},
|
{1, 0, 0},
|
||||||
{1, 0, 1},
|
|
||||||
{0, 0, 1},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// +Y
|
// +Y
|
||||||
{
|
{
|
||||||
{0, 1, 0},
|
{0, 1, 0},
|
||||||
|
{1, 1, 0},
|
||||||
{0, 1, 1},
|
{0, 1, 1},
|
||||||
{1, 1, 1},
|
{1, 1, 1},
|
||||||
{1, 1, 0},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// -Z
|
// -Z
|
||||||
{
|
{
|
||||||
{0, 0, 0},
|
{0, 0, 0},
|
||||||
|
{1, 0, 0},
|
||||||
{0, 1, 0},
|
{0, 1, 0},
|
||||||
{1, 1, 0},
|
{1, 1, 0},
|
||||||
{1, 0, 0},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// +Z
|
// +Z
|
||||||
{
|
{
|
||||||
{0, 0, 1},
|
|
||||||
{1, 0, 1},
|
{1, 0, 1},
|
||||||
|
{0, 0, 1},
|
||||||
{1, 1, 1},
|
{1, 1, 1},
|
||||||
{0, 1, 1},
|
{0, 1, 1},
|
||||||
},
|
},
|
||||||
@ -64,10 +70,10 @@ namespace deerith
|
|||||||
|
|
||||||
uint32_t face_indices_order[6] = {
|
uint32_t face_indices_order[6] = {
|
||||||
0,
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
3,
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
0,
|
|
||||||
2,
|
|
||||||
3,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
7
deerith_client/include/deerith/client/internals/engine.h
Normal file
7
deerith_client/include/deerith/client/internals/engine.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace deerith
|
||||||
|
{
|
||||||
|
void init_engine_render_specific();
|
||||||
|
void shutdown_engine_render_specific();
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <deerith/client/world.h>
|
#include <deerith/client/world.h>
|
||||||
|
#include <deerith/client/graphics/texture.h>
|
||||||
|
#include <deerith/client/graphics/shader.h>
|
||||||
|
|
||||||
namespace deerith
|
namespace deerith
|
||||||
{
|
{
|
||||||
@ -7,4 +9,9 @@ namespace deerith
|
|||||||
|
|
||||||
void process_player_input();
|
void process_player_input();
|
||||||
void send_player_input();
|
void send_player_input();
|
||||||
|
|
||||||
|
void generate_voxel_texture();
|
||||||
|
void init_voxel_shader();
|
||||||
|
|
||||||
|
void shutdown_world_variables();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <deerith/world/world_core.h>
|
#include <deerith/world/world_core.h>
|
||||||
#include <deerith/world/environment.h>
|
#include <deerith/world/environment.h>
|
||||||
|
#include <deerith/client/graphics/texture.h>
|
||||||
|
#include <deerith/client/graphics/shader.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
namespace deerith
|
namespace deerith
|
||||||
@ -16,5 +18,8 @@ namespace deerith
|
|||||||
void generate_cluster(voxel_cluster_t *_cluster);
|
void generate_cluster(voxel_cluster_t *_cluster);
|
||||||
void load_clusters_to_gpu();
|
void load_clusters_to_gpu();
|
||||||
|
|
||||||
|
shader_t *get_voxel_shader();
|
||||||
|
texture_t *get_voxel_texture();
|
||||||
|
|
||||||
client_t *get_server_client();
|
client_t *get_server_client();
|
||||||
}
|
}
|
||||||
34
deerith_client/shaders/voxel.frag.glsl
Normal file
34
deerith_client/shaders/voxel.frag.glsl
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec3 frag_position;
|
||||||
|
in vec3 frag_normal;
|
||||||
|
in vec2 frag_uv;
|
||||||
|
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
|
uniform vec3 u_color = vec3(1, 1, 1);
|
||||||
|
uniform vec3 u_light_direction = vec3(-1, 3, -2);
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Sample texture
|
||||||
|
vec4 tex_color = texture(u_texture, frag_uv);
|
||||||
|
|
||||||
|
// Face normal
|
||||||
|
vec3 normal = normalize(frag_normal);
|
||||||
|
|
||||||
|
// Directional lighting
|
||||||
|
vec3 light_direction = normalize(u_light_direction);
|
||||||
|
float diffuse = max(dot(normal, light_direction), 0.0);
|
||||||
|
|
||||||
|
// Ambient + diffuse
|
||||||
|
float ambient = 0.25;
|
||||||
|
float lighting = ambient + diffuse * 0.75;
|
||||||
|
|
||||||
|
// Final color
|
||||||
|
vec3 color = tex_color.rgb * u_color * lighting;
|
||||||
|
|
||||||
|
FragColor = vec4(color, tex_color.a);
|
||||||
|
}
|
||||||
24
deerith_client/shaders/voxel.vert.glsl
Normal file
24
deerith_client/shaders/voxel.vert.glsl
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 a_position;
|
||||||
|
layout (location = 1) in vec3 a_normal;
|
||||||
|
layout (location = 2) in vec2 a_uv;
|
||||||
|
|
||||||
|
uniform mat4 u_model;
|
||||||
|
uniform mat4 u_view;
|
||||||
|
uniform mat4 u_projection;
|
||||||
|
|
||||||
|
out vec3 frag_position;
|
||||||
|
out vec3 frag_normal;
|
||||||
|
out vec2 frag_uv;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 world_position = u_model * vec4(a_position, 1.0);
|
||||||
|
|
||||||
|
gl_Position = u_projection * u_view * world_position;
|
||||||
|
|
||||||
|
frag_position = world_position.xyz;
|
||||||
|
frag_normal = mat3(transpose(inverse(u_model))) * a_normal;
|
||||||
|
frag_uv = a_uv;
|
||||||
|
}
|
||||||
@ -1,5 +1,10 @@
|
|||||||
#include <deerith/engine.h>
|
#include <deerith/engine.h>
|
||||||
#include <deerith/client/internals/network.h>
|
#include <deerith/client/internals/network.h>
|
||||||
|
#include <deerith/client/internals/engine.h>
|
||||||
|
|
||||||
|
#include <deerith/client/internals/primitive.h>
|
||||||
|
#include <deerith/client/internals/world.h>
|
||||||
|
#include <deerith/client/internals/cluster_generation.h>
|
||||||
|
|
||||||
void deerith::init_engine()
|
void deerith::init_engine()
|
||||||
{
|
{
|
||||||
@ -16,3 +21,19 @@ void deerith::shutdown_engine()
|
|||||||
deerith_trace("shutdown engine");
|
deerith_trace("shutdown engine");
|
||||||
shutdown_log();
|
shutdown_log();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void deerith::init_engine_render_specific()
|
||||||
|
{
|
||||||
|
init_primitives();
|
||||||
|
init_voxel_shader();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::shutdown_engine_render_specific()
|
||||||
|
{
|
||||||
|
shutdown_environment();
|
||||||
|
|
||||||
|
shutdown_primitives();
|
||||||
|
shutdown_world();
|
||||||
|
shutdown_network();
|
||||||
|
shutdown_world_variables();
|
||||||
|
}
|
||||||
@ -106,8 +106,17 @@ deerith::mesh_3d_t::mesh_3d_t(const mesh_3d_data_t &mesh_data)
|
|||||||
sizeof(vertex_3d_t),
|
sizeof(vertex_3d_t),
|
||||||
(void *)offsetof(vertex_3d_t, normal));
|
(void *)offsetof(vertex_3d_t, normal));
|
||||||
|
|
||||||
|
glVertexAttribPointer(
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(vertex_3d_t),
|
||||||
|
(void *)offsetof(vertex_3d_t, uv));
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include <deerith/client/graphics/primitive_internals.h>
|
#include <deerith/client/internals/primitive.h>
|
||||||
#include <deerith/client/graphics/primitive.h>
|
#include <deerith/client/graphics/primitive.h>
|
||||||
#include <deerith/client/graphics/shader.h>
|
#include <deerith/client/graphics/shader.h>
|
||||||
#include <deerith/client/graphics/mesh.h>
|
#include <deerith/client/graphics/mesh.h>
|
||||||
|
|||||||
52
deerith_client/src/graphics/texture.cpp
Normal file
52
deerith_client/src/graphics/texture.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#include <deerith/client/graphics/texture.h>
|
||||||
|
|
||||||
|
#include <glad/gl.h>
|
||||||
|
|
||||||
|
namespace deerith
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
deerith::texture_t::texture_t(const uint8_t *__data, int width, int height, int channels, int mip_map)
|
||||||
|
{
|
||||||
|
glGenTextures(1, &texture_id);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
int chanel_value = 0;
|
||||||
|
|
||||||
|
switch (channels)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
chanel_value = GL_RED;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
chanel_value = GL_RG;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
chanel_value = GL_RGB;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
chanel_value = GL_RGBA;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
deerith_error("incorrect channel value {}", channels);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, chanel_value, GL_UNSIGNED_BYTE, __data);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
max_mip_map = mip_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::texture_t::bind(int v)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + v);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, max_mip_map);
|
||||||
|
}
|
||||||
@ -1,8 +1,10 @@
|
|||||||
#include <deerith/client/graphics/window.h>
|
#include <deerith/client/graphics/window.h>
|
||||||
#include <deerith/client/graphics/primitive_internals.h>
|
#include <deerith/client/internals/primitive.h>
|
||||||
#include <deerith/client/internals/network.h>
|
#include <deerith/client/internals/network.h>
|
||||||
#include <deerith/client/world.h>
|
#include <deerith/client/world.h>
|
||||||
#include <deerith/client/cluster.h>
|
#include <deerith/client/cluster.h>
|
||||||
|
#include <deerith/client/internals/world.h>
|
||||||
|
#include <deerith/client/internals/engine.h>
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@ -74,9 +76,10 @@ int deerith::init_window()
|
|||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
init_primitives();
|
|
||||||
init_imgui();
|
init_imgui();
|
||||||
|
|
||||||
|
init_engine_render_specific();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,11 +148,7 @@ void deerith::shutdown_window()
|
|||||||
ImGui_ImplGlfw_Shutdown();
|
ImGui_ImplGlfw_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
clear_all_clusters();
|
shutdown_engine_render_specific();
|
||||||
|
|
||||||
shutdown_primitives();
|
|
||||||
shutdown_world();
|
|
||||||
shutdown_network();
|
|
||||||
|
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|||||||
@ -55,6 +55,7 @@ void deerith::cluster_generator_t::generate_voxel(int x, int y, int z)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
texture_atlas_t *texture_atlas = get_voxel_texture_atlas();
|
||||||
glm::vec3 voxel_position = glm::vec3(x, y, z) * VOXEL_SIZE;
|
glm::vec3 voxel_position = glm::vec3(x, y, z) * VOXEL_SIZE;
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
@ -72,13 +73,15 @@ void deerith::cluster_generator_t::generate_voxel(int x, int y, int z)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t starting_index = build_data.vertices.size();
|
uint32_t starting_index = build_data.vertices.size();
|
||||||
|
const voxel_material_t material = get_voxel_material(cur_type.material_id);
|
||||||
|
glm::vec2 uv_position = material.face_texture_id[i];
|
||||||
|
|
||||||
// HEY BUILD FACE
|
|
||||||
for (int v = 0; v < 4; v++)
|
for (int v = 0; v < 4; v++)
|
||||||
{
|
{
|
||||||
vertex_3d_t vertex = {
|
vertex_3d_t vertex = {
|
||||||
.position = voxel_position + voxel_direction_vertices[i][v],
|
.position = voxel_position + voxel_direction_vertices[i][v] * VOXEL_SIZE,
|
||||||
.normal = voxel_direction_order[i],
|
.normal = voxel_direction_order[i],
|
||||||
|
.uv = (uv_position + voxel_uv_order[v]) / glm::vec2(texture_atlas->size_x, texture_atlas->size_y),
|
||||||
};
|
};
|
||||||
|
|
||||||
build_data.vertices.push_back(vertex);
|
build_data.vertices.push_back(vertex);
|
||||||
@ -113,11 +116,4 @@ deerith::voxel_type_id_t deerith::cluster_generator_t::get_cluster_voxel(int x,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
glm::ivec3 coords;
|
|
||||||
coords.x = x + CLUSTER_SIZE * cluster->surface_id.x;
|
|
||||||
coords.y = y + CLUSTER_SIZE * cluster->layer;
|
|
||||||
coords.z = z + CLUSTER_SIZE * cluster->surface_id.y;
|
|
||||||
|
|
||||||
return get_voxel_id(coords);
|
|
||||||
}
|
}
|
||||||
@ -16,7 +16,7 @@ namespace deerith
|
|||||||
void render_cluster(glm::ivec3);
|
void render_cluster(glm::ivec3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deerith::clear_all_clusters()
|
void deerith::shutdown_environment()
|
||||||
{
|
{
|
||||||
loaded_clusters.clear();
|
loaded_clusters.clear();
|
||||||
}
|
}
|
||||||
@ -38,10 +38,22 @@ void deerith::flush_cluster_to_gpu()
|
|||||||
cluster_workers.clear();
|
cluster_workers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void deerith::render_clusters(glm::ivec3 position, int rad)
|
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
|
// Radial outward
|
||||||
for (int r = 0; r <= rad; r++)
|
for (int r = 0; r < rad; r++)
|
||||||
{
|
{
|
||||||
for (int x = -r; x <= r; x++)
|
for (int x = -r; x <= r; x++)
|
||||||
{
|
{
|
||||||
@ -56,7 +68,6 @@ void deerith::render_clusters(glm::ivec3 position, int rad)
|
|||||||
}
|
}
|
||||||
|
|
||||||
glm::ivec3 cluster_position = position + glm::ivec3(x, y, z);
|
glm::ivec3 cluster_position = position + glm::ivec3(x, y, z);
|
||||||
|
|
||||||
render_cluster(cluster_position);
|
render_cluster(cluster_position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,10 +87,8 @@ void deerith::render_cluster(glm::ivec3 pos)
|
|||||||
float offset = static_cast<float>(CLUSTER_SIZE) * static_cast<float>(VOXEL_SIZE);
|
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::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::quat rotation = glm::identity<glm::quat>();
|
||||||
glm::vec3 scale = glm::vec3(VOXEL_SIZE, VOXEL_SIZE, VOXEL_SIZE);
|
glm::vec3 scale = glm::vec3(1, 1, 1);
|
||||||
|
|
||||||
get_lit_shader()->use();
|
set_transform_to_shader(position, rotation, scale, get_voxel_shader());
|
||||||
get_lit_shader()->set_vec4("u_color", glm::vec4(1, 0.4f, 0.6f, 1));
|
|
||||||
set_transform_to_shader(position, rotation, scale, get_lit_shader());
|
|
||||||
cluster_mesh->draw();
|
cluster_mesh->draw();
|
||||||
}
|
}
|
||||||
@ -19,6 +19,7 @@ void deerith::setup_base_protocols()
|
|||||||
router_add_packet_processor<packet_destroy_entity_t>();
|
router_add_packet_processor<packet_destroy_entity_t>();
|
||||||
router_add_packet_processor<packet_voxel_data_definition_t>();
|
router_add_packet_processor<packet_voxel_data_definition_t>();
|
||||||
router_add_packet_processor<packet_cluster_data_t>();
|
router_add_packet_processor<packet_cluster_data_t>();
|
||||||
|
router_add_packet_processor<packet_voxel_texture_atlas_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@ -103,3 +104,10 @@ void deerith::process_packet(deerith::packet_cluster_data_t &packet, client_t *c
|
|||||||
|
|
||||||
generate_cluster(cluster);
|
generate_cluster(cluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void deerith::process_packet(deerith::packet_voxel_texture_atlas_t &packet, client_t *client)
|
||||||
|
{
|
||||||
|
packet.texture_atlas->save_atlas("client_generated/voxel_texture_atlas.png");
|
||||||
|
set_voxel_texture_atlas(std::move(packet.texture_atlas));
|
||||||
|
}
|
||||||
@ -55,5 +55,5 @@ void deerith::render_world()
|
|||||||
pos = get_nearest_cluster(sync_coords.position);
|
pos = get_nearest_cluster(sync_coords.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
render_clusters(pos, 10);
|
render_clusters(pos, 6, camera);
|
||||||
}
|
}
|
||||||
53
deerith_client/src/world/world_variables.cpp
Normal file
53
deerith_client/src/world/world_variables.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include <deerith/client/world.h>
|
||||||
|
#include <deerith/client/internals/world.h>
|
||||||
|
#include <deerith/client/world.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace deerith
|
||||||
|
{
|
||||||
|
std::unique_ptr<shader_t> voxel_shader;
|
||||||
|
std::unique_ptr<texture_t> voxel_texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
deerith::shader_t *deerith::get_voxel_shader()
|
||||||
|
{
|
||||||
|
return voxel_shader.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
deerith::texture_t *deerith::get_voxel_texture()
|
||||||
|
{
|
||||||
|
if (voxel_texture == nullptr)
|
||||||
|
{
|
||||||
|
generate_voxel_texture();
|
||||||
|
}
|
||||||
|
|
||||||
|
return voxel_texture.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::generate_voxel_texture()
|
||||||
|
{
|
||||||
|
texture_atlas_t *texture_atlas = get_voxel_texture_atlas();
|
||||||
|
|
||||||
|
if (texture_atlas == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
voxel_texture = std::make_unique<texture_t>(
|
||||||
|
texture_atlas->__texture_data.get(),
|
||||||
|
texture_atlas->size_x * texture_atlas->unit_size,
|
||||||
|
texture_atlas->size_y * texture_atlas->unit_size,
|
||||||
|
texture_atlas_t::channel_count,
|
||||||
|
4);
|
||||||
|
}
|
||||||
|
void deerith::init_voxel_shader()
|
||||||
|
{
|
||||||
|
voxel_shader = std::make_unique<shader_t>(
|
||||||
|
"shaders/voxel.vert.glsl",
|
||||||
|
"shaders/voxel.frag.glsl");
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::shutdown_world_variables()
|
||||||
|
{
|
||||||
|
voxel_shader.reset();
|
||||||
|
}
|
||||||
2586
deerith_engine_core/include/FastNoise/FastNoiseLite.h
Normal file
2586
deerith_engine_core/include/FastNoise/FastNoiseLite.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,9 +3,11 @@
|
|||||||
#include <deerith/world/voxels.h>
|
#include <deerith/world/voxels.h>
|
||||||
#include <deerith/world/environment.h>
|
#include <deerith/world/environment.h>
|
||||||
|
|
||||||
|
#include <deerith/network/serialization_ext.h>
|
||||||
#include <cereal/types/vector.hpp>
|
#include <cereal/types/vector.hpp>
|
||||||
#include <cereal/types/string.hpp>
|
#include <cereal/types/string.hpp>
|
||||||
#include <cereal/types/array.hpp>
|
#include <cereal/types/array.hpp>
|
||||||
|
#include <cereal/types/unordered_map.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -29,11 +31,32 @@ namespace deerith
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct packet_cluster_data_t
|
struct packet_voxel_texture_atlas_t
|
||||||
{
|
{
|
||||||
static constexpr uint16_t packet_id = 1002;
|
static constexpr uint16_t packet_id = 1002;
|
||||||
static constexpr bool reliable = true;
|
static constexpr bool reliable = true;
|
||||||
|
|
||||||
|
std::unique_ptr<texture_atlas_t> texture_atlas;
|
||||||
|
|
||||||
|
template <typename Archive>
|
||||||
|
void save(Archive &archive) const
|
||||||
|
{
|
||||||
|
archive(*texture_atlas);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Archive>
|
||||||
|
void load(Archive &archive)
|
||||||
|
{
|
||||||
|
texture_atlas = std::make_unique<texture_atlas_t>();
|
||||||
|
archive(*texture_atlas);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct packet_cluster_data_t
|
||||||
|
{
|
||||||
|
static constexpr uint16_t packet_id = 1003;
|
||||||
|
static constexpr bool reliable = true;
|
||||||
|
|
||||||
int layer;
|
int layer;
|
||||||
glm::ivec2 surface_id;
|
glm::ivec2 surface_id;
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@ namespace deerith
|
|||||||
const voxel_type_t &get_voxel(glm::ivec3 coordinates);
|
const voxel_type_t &get_voxel(glm::ivec3 coordinates);
|
||||||
|
|
||||||
int32_t get_cluster_last_tick_update(glm::ivec2 surface_id, int layer);
|
int32_t get_cluster_last_tick_update(glm::ivec2 surface_id, int layer);
|
||||||
|
|
||||||
surface_t *get_surface(glm::ivec2);
|
surface_t *get_surface(glm::ivec2);
|
||||||
surface_t *get_create_surface(glm::ivec2);
|
surface_t *get_create_surface(glm::ivec2);
|
||||||
|
|
||||||
|
|||||||
@ -19,24 +19,66 @@ namespace deerith
|
|||||||
path_t texture_location;
|
path_t texture_location;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct texture_builder_t
|
struct atlas_builder_t
|
||||||
{
|
{
|
||||||
int unit_size = 32;
|
int unit_size = 32;
|
||||||
|
|
||||||
std::vector<texture_builder_entry_t> entries;
|
std::vector<texture_builder_entry_t> entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct texture_atlas_t
|
struct texture_atlas_t
|
||||||
{
|
{
|
||||||
texture_atlas_t(const texture_builder_t &);
|
static constexpr int channel_count = 4;
|
||||||
|
|
||||||
int size_x;
|
int size_x;
|
||||||
int size_y;
|
int size_y;
|
||||||
|
|
||||||
|
int unit_size;
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> __texture_data;
|
std::unique_ptr<uint8_t[]> __texture_data;
|
||||||
std::unordered_map<std::string, glm::ivec2> texture_name_id_map;
|
std::unordered_map<std::string, glm::ivec2> texture_name_id_map;
|
||||||
|
|
||||||
// RGBA
|
// RGBA
|
||||||
uint8_t *get_pixel(int x, int y);
|
uint8_t *get_pixel(int x, int y);
|
||||||
|
void copy_image(const uint8_t *data, int x_pos, int y_pos, int width, int height);
|
||||||
|
void save_atlas(const path_t &location);
|
||||||
|
|
||||||
|
glm::ivec2 get_texture_position(const std::string &);
|
||||||
|
|
||||||
|
template <typename Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(unit_size);
|
||||||
|
archive(size_x);
|
||||||
|
archive(size_y);
|
||||||
|
|
||||||
|
archive(texture_name_id_map);
|
||||||
|
|
||||||
|
int data_size = unit_size * unit_size * size_x * size_y * texture_atlas_t::channel_count;
|
||||||
|
if constexpr (Archive::is_loading::value)
|
||||||
|
{
|
||||||
|
__texture_data = std::make_unique<uint8_t[]>(data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < data_size; i++)
|
||||||
|
{
|
||||||
|
archive(__texture_data.get()[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_atlas_t() = default;
|
||||||
|
texture_atlas_t(const texture_atlas_t &other)
|
||||||
|
{
|
||||||
|
size_x = other.size_x;
|
||||||
|
size_y = other.size_y;
|
||||||
|
unit_size = other.unit_size;
|
||||||
|
|
||||||
|
texture_name_id_map = other.texture_name_id_map;
|
||||||
|
int data_size = unit_size * unit_size * size_x * size_y * channel_count;
|
||||||
|
|
||||||
|
__texture_data = std::make_unique<uint8_t[]>(data_size);
|
||||||
|
std::copy(other.__texture_data.get(), other.__texture_data.get() + data_size, __texture_data.get());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<texture_atlas_t> generate_texture_atlas(const atlas_builder_t &builder);
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <deerith/engine.h>
|
#include <deerith/engine.h>
|
||||||
|
#include <deerith/world/texture.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -9,6 +10,13 @@ namespace deerith
|
|||||||
using voxel_type_id_t = uint16_t;
|
using voxel_type_id_t = uint16_t;
|
||||||
using voxel_material_id_t = uint16_t;
|
using voxel_material_id_t = uint16_t;
|
||||||
|
|
||||||
|
constexpr int direction_left = 0;
|
||||||
|
constexpr int direction_right = 1;
|
||||||
|
constexpr int direction_down = 2;
|
||||||
|
constexpr int direction_up = 3;
|
||||||
|
constexpr int direction_front = 4;
|
||||||
|
constexpr int direction_back = 5;
|
||||||
|
|
||||||
enum class voxel_material_type_t : int
|
enum class voxel_material_type_t : int
|
||||||
{
|
{
|
||||||
AIR = 0,
|
AIR = 0,
|
||||||
@ -19,6 +27,7 @@ namespace deerith
|
|||||||
{
|
{
|
||||||
// universal identifies
|
// universal identifies
|
||||||
std::string id;
|
std::string id;
|
||||||
|
glm::ivec2 face_texture_id[6] = {};
|
||||||
voxel_material_type_t material_type = voxel_material_type_t::AIR;
|
voxel_material_type_t material_type = voxel_material_type_t::AIR;
|
||||||
|
|
||||||
template <typename Archive>
|
template <typename Archive>
|
||||||
@ -26,7 +35,16 @@ namespace deerith
|
|||||||
{
|
{
|
||||||
archive(id);
|
archive(id);
|
||||||
archive(material_type);
|
archive(material_type);
|
||||||
|
|
||||||
|
archive(face_texture_id[0]);
|
||||||
|
archive(face_texture_id[1]);
|
||||||
|
archive(face_texture_id[2]);
|
||||||
|
archive(face_texture_id[3]);
|
||||||
|
archive(face_texture_id[4]);
|
||||||
|
archive(face_texture_id[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_same_face_texture(glm::ivec2);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct voxel_type_t
|
struct voxel_type_t
|
||||||
@ -47,6 +65,10 @@ namespace deerith
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void set_voxel_texture_atlas(const atlas_builder_t &builder);
|
||||||
|
void set_voxel_texture_atlas(std::unique_ptr<texture_atlas_t> texture_atlas);
|
||||||
|
texture_atlas_t *get_voxel_texture_atlas();
|
||||||
|
|
||||||
void set_voxel_materials(const std::vector<voxel_material_t> &mats);
|
void set_voxel_materials(const std::vector<voxel_material_t> &mats);
|
||||||
voxel_material_id_t register_voxel_material(const voxel_material_t &type);
|
voxel_material_id_t register_voxel_material(const voxel_material_t &type);
|
||||||
voxel_material_id_t get_voxel_material_id(const std::string &name);
|
voxel_material_id_t get_voxel_material_id(const std::string &name);
|
||||||
|
|||||||
7988
deerith_engine_core/include/stb/stb_image.h
Normal file
7988
deerith_engine_core/include/stb/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
1724
deerith_engine_core/include/stb/stb_image_write.h
Normal file
1724
deerith_engine_core/include/stb/stb_image_write.h
Normal file
File diff suppressed because it is too large
Load Diff
4
deerith_engine_core/src/vendor/stb_image_compile.cpp
vendored
Normal file
4
deerith_engine_core/src/vendor/stb_image_compile.cpp
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include <stb/stb_image.h>
|
||||||
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
|
#include <stb/stb_image_write.h>
|
||||||
@ -19,8 +19,6 @@ namespace deerith
|
|||||||
glm::ivec3 get_internal_voxel_coords(glm::ivec3 coords);
|
glm::ivec3 get_internal_voxel_coords(glm::ivec3 coords);
|
||||||
glm::ivec3 get_internal_voxel_coords(glm::ivec2 coords, int height = 0);
|
glm::ivec3 get_internal_voxel_coords(glm::ivec2 coords, int height = 0);
|
||||||
|
|
||||||
surface_t *get_surface(glm::ivec2);
|
|
||||||
surface_t *get_create_surface(glm::ivec2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deerith::voxel_cluster_t *deerith::surface_t::get_cluster(int layer)
|
deerith::voxel_cluster_t *deerith::surface_t::get_cluster(int layer)
|
||||||
|
|||||||
@ -1,18 +1,131 @@
|
|||||||
#include <deerith/world/texture.h>
|
#include <deerith/world/texture.h>
|
||||||
|
#include <stb/stb_image.h>
|
||||||
|
#include <stb/stb_image_write.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <math.h>
|
||||||
|
#include <functional>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
namespace deerith
|
namespace deerith
|
||||||
{
|
{
|
||||||
|
struct temp_image_data_t
|
||||||
|
{
|
||||||
|
std::string id;
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int channels;
|
||||||
|
|
||||||
|
uint8_t *data;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *deerith::texture_atlas_t::get_pixel(int x, int y)
|
uint8_t *deerith::texture_atlas_t::get_pixel(int x, int y)
|
||||||
{
|
{
|
||||||
if (x < 0 || y < 0 || x >= size_x || y >= size_y)
|
if (x < 0 || y < 0 || x >= size_x * unit_size || y >= size_y * unit_size)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
return &__texture_data[(y * size_x * unit_size + x) * channel_count];
|
||||||
return &__texture_data[(y * size_x + x) * 4];
|
|
||||||
}
|
}
|
||||||
|
glm::ivec2 deerith::texture_atlas_t::get_texture_position(const std::string &str)
|
||||||
deerith::texture_atlas_t::texture_atlas_t(const texture_builder_t &)
|
|
||||||
{
|
{
|
||||||
|
if (!texture_name_id_map.contains(str))
|
||||||
|
{
|
||||||
|
deerith_error("get_texture_position could not find {}", str.c_str());
|
||||||
|
return glm::ivec2(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture_name_id_map[str];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<deerith::texture_atlas_t> deerith::generate_texture_atlas(const atlas_builder_t &builder)
|
||||||
|
{
|
||||||
|
stbi_set_flip_vertically_on_load(true);
|
||||||
|
|
||||||
|
std::unique_ptr<texture_atlas_t> texture_atlas = std::make_unique<texture_atlas_t>();
|
||||||
|
std::vector<temp_image_data_t> temp_data;
|
||||||
|
|
||||||
|
int total_area = 1;
|
||||||
|
for (const texture_builder_entry_t &entry : builder.entries)
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int channels;
|
||||||
|
|
||||||
|
uint8_t *data = stbi_load(entry.texture_location.generic_string().c_str(), &width, &height, &channels, texture_atlas_t::channel_count);
|
||||||
|
if (data == nullptr)
|
||||||
|
{
|
||||||
|
deerith_error("failed to find {} while processing image {}", entry.texture_location.generic_string().c_str(), entry.id.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_area += 1;
|
||||||
|
temp_data.push_back(
|
||||||
|
temp_image_data_t{
|
||||||
|
.id = entry.id,
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
.channels = channels,
|
||||||
|
.data = data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
int atlas_map_width = static_cast<int>(std::ceilf(std::sqrtf(total_area)));
|
||||||
|
texture_atlas->unit_size = builder.unit_size;
|
||||||
|
texture_atlas->size_x = atlas_map_width;
|
||||||
|
texture_atlas->size_y = atlas_map_width;
|
||||||
|
|
||||||
|
texture_atlas->__texture_data = std::make_unique<uint8_t[]>(atlas_map_width * atlas_map_width * texture_atlas_t::channel_count * builder.unit_size * builder.unit_size);
|
||||||
|
|
||||||
|
int x_pos = 0;
|
||||||
|
int y_pos = 0;
|
||||||
|
for (const temp_image_data_t &temp_image : temp_data)
|
||||||
|
{
|
||||||
|
int max_x_size = std::min(builder.unit_size, temp_image.width);
|
||||||
|
int max_y_size = std::min(builder.unit_size, temp_image.height);
|
||||||
|
|
||||||
|
texture_atlas->texture_name_id_map[temp_image.id] = glm::ivec2(x_pos, y_pos);
|
||||||
|
texture_atlas->copy_image(temp_image.data, x_pos * builder.unit_size, y_pos * builder.unit_size, max_x_size, max_y_size);
|
||||||
|
|
||||||
|
stbi_image_free(temp_image.data);
|
||||||
|
|
||||||
|
x_pos++;
|
||||||
|
if (x_pos >= atlas_map_width)
|
||||||
|
{
|
||||||
|
x_pos = 0;
|
||||||
|
y_pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture_atlas;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::texture_atlas_t::copy_image(const uint8_t *data, int x_pos, int y_pos, int width, int height)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
uint8_t *pixel = get_pixel(x + x_pos, y + y_pos);
|
||||||
|
const uint8_t *data_pixel = &data[(x + y * width) * channel_count];
|
||||||
|
|
||||||
|
pixel[0] = data_pixel[0];
|
||||||
|
pixel[1] = data_pixel[1];
|
||||||
|
pixel[2] = data_pixel[2];
|
||||||
|
pixel[3] = data_pixel[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::texture_atlas_t::save_atlas(const path_t &location)
|
||||||
|
{
|
||||||
|
stbi_flip_vertically_on_write(true);
|
||||||
|
|
||||||
|
std::filesystem::create_directories(location.parent_path());
|
||||||
|
int result = stbi_write_png(location.generic_string().c_str(), size_x * unit_size, size_y * unit_size, channel_count, __texture_data.get(), size_x * unit_size * channel_count);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
deerith_error("failed to save atlas at {}", location.generic_string().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace deerith
|
namespace deerith
|
||||||
{
|
{
|
||||||
@ -10,6 +11,8 @@ namespace deerith
|
|||||||
|
|
||||||
std::vector<voxel_material_t> voxel_material_array;
|
std::vector<voxel_material_t> voxel_material_array;
|
||||||
std::unordered_map<std::string, voxel_material_id_t> voxel_material_name_id;
|
std::unordered_map<std::string, voxel_material_id_t> voxel_material_name_id;
|
||||||
|
|
||||||
|
std::unique_ptr<texture_atlas_t> voxel_texture_atlas;
|
||||||
}
|
}
|
||||||
|
|
||||||
deerith::voxel_type_id_t deerith::register_voxel_type(const voxel_type_t &type)
|
deerith::voxel_type_id_t deerith::register_voxel_type(const voxel_type_t &type)
|
||||||
@ -63,6 +66,21 @@ const std::vector<deerith::voxel_type_t> &deerith::get_voxel_type_vector()
|
|||||||
return voxel_type_array;
|
return voxel_type_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void deerith::set_voxel_texture_atlas(const atlas_builder_t &builder)
|
||||||
|
{
|
||||||
|
voxel_texture_atlas = generate_texture_atlas(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::set_voxel_texture_atlas(std::unique_ptr<texture_atlas_t> texture_atlas)
|
||||||
|
{
|
||||||
|
voxel_texture_atlas = std::move(texture_atlas);
|
||||||
|
}
|
||||||
|
|
||||||
|
deerith::texture_atlas_t *deerith::get_voxel_texture_atlas()
|
||||||
|
{
|
||||||
|
return voxel_texture_atlas.get();
|
||||||
|
}
|
||||||
|
|
||||||
void deerith::set_voxel_materials(const std::vector<deerith::voxel_material_t> &mats)
|
void deerith::set_voxel_materials(const std::vector<deerith::voxel_material_t> &mats)
|
||||||
{
|
{
|
||||||
voxel_material_array = mats;
|
voxel_material_array = mats;
|
||||||
@ -86,3 +104,13 @@ void deerith::set_voxel_types(const std::vector<deerith::voxel_type_t> &types)
|
|||||||
voxel_type_name_id[type.id] = id;
|
voxel_type_name_id[type.id] = id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void deerith::voxel_material_t::set_same_face_texture(glm::ivec2 pos)
|
||||||
|
{
|
||||||
|
face_texture_id[0] = pos;
|
||||||
|
face_texture_id[1] = pos;
|
||||||
|
face_texture_id[2] = pos;
|
||||||
|
face_texture_id[3] = pos;
|
||||||
|
face_texture_id[4] = pos;
|
||||||
|
face_texture_id[5] = pos;
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <deerith/network/client.h>
|
#include <deerith/network/client.h>
|
||||||
#include <deerith/world/components.h>
|
#include <deerith/world/components.h>
|
||||||
|
#include <deerith/server/runtime_settings.h>
|
||||||
|
|
||||||
namespace deerith
|
namespace deerith
|
||||||
{
|
{
|
||||||
@ -21,4 +22,6 @@ namespace deerith
|
|||||||
void send_entity_data();
|
void send_entity_data();
|
||||||
void send_voxel_data_to_client(client_t *client);
|
void send_voxel_data_to_client(client_t *client);
|
||||||
void send_clients_environment_data();
|
void send_clients_environment_data();
|
||||||
|
|
||||||
|
extern world_settings_t world_settings;
|
||||||
}
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <deerith/world/environment.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace deerith
|
||||||
|
{
|
||||||
|
struct world_settings_t
|
||||||
|
{
|
||||||
|
int port = 8080;
|
||||||
|
|
||||||
|
std::function<void(atlas_builder_t &)> define_voxel_texture_atlas_function;
|
||||||
|
std::function<void(texture_atlas_t *)> define_voxels_materials_function;
|
||||||
|
std::function<void()> define_voxels_types_function;
|
||||||
|
|
||||||
|
std::function<void(voxel_cluster_t *)> generate_voxel_cluster;
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,9 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <deerith/world/world_core.h>
|
#include <deerith/world/world_core.h>
|
||||||
|
#include <deerith/server/runtime_settings.h>
|
||||||
|
|
||||||
namespace deerith
|
namespace deerith
|
||||||
{
|
{
|
||||||
void run_world(int port);
|
void run_world(const world_settings_t &);
|
||||||
void shutdown_world();
|
void shutdown_world();
|
||||||
|
|
||||||
bool is_world_running();
|
bool is_world_running();
|
||||||
|
|||||||
29
deerith_engine_server/src/world/init_world.cpp
Normal file
29
deerith_engine_server/src/world/init_world.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include <deerith/engine.h>
|
||||||
|
#include <deerith/server/world.h>
|
||||||
|
|
||||||
|
namespace deerith
|
||||||
|
{
|
||||||
|
extern world_settings_t world_settings;
|
||||||
|
|
||||||
|
void init_voxel_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::init_world()
|
||||||
|
{
|
||||||
|
init_voxel_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::init_voxel_data()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
atlas_builder_t atlas_builder;
|
||||||
|
world_settings.define_voxel_texture_atlas_function(atlas_builder);
|
||||||
|
set_voxel_texture_atlas(atlas_builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_atlas_t *voxel_texture_atlas = get_voxel_texture_atlas();
|
||||||
|
voxel_texture_atlas->save_atlas("generated/voxel_texture_atlas.png");
|
||||||
|
|
||||||
|
world_settings.define_voxels_materials_function(voxel_texture_atlas);
|
||||||
|
world_settings.define_voxels_types_function();
|
||||||
|
}
|
||||||
@ -25,6 +25,13 @@ void deerith::send_voxel_data_to_client(client_t *client)
|
|||||||
voxel_data_definition.voxel_types = get_voxel_type_vector();
|
voxel_data_definition.voxel_types = get_voxel_type_vector();
|
||||||
|
|
||||||
router_send_packet(voxel_data_definition, client);
|
router_send_packet(voxel_data_definition, client);
|
||||||
|
|
||||||
|
texture_atlas_t *texture_atlas = get_voxel_texture_atlas();
|
||||||
|
|
||||||
|
packet_voxel_texture_atlas_t voxel_texture_atlas;
|
||||||
|
voxel_texture_atlas.texture_atlas = std::make_unique<texture_atlas_t>(*texture_atlas);
|
||||||
|
|
||||||
|
router_send_packet(voxel_texture_atlas, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deerith::send_clients_environment_data()
|
void deerith::send_clients_environment_data()
|
||||||
@ -57,24 +64,27 @@ void deerith::check_client_surface_knowledge(client_t *client, component_client_
|
|||||||
for (int z = -SURFACE_RADIUS; z <= SURFACE_RADIUS; z++)
|
for (int z = -SURFACE_RADIUS; z <= SURFACE_RADIUS; z++)
|
||||||
{
|
{
|
||||||
glm::ivec2 surface_id = {surface_x + x, surface_z + z};
|
glm::ivec2 surface_id = {surface_x + x, surface_z + z};
|
||||||
surface_t *surface = get_surface(surface_id);
|
surface_t *surface = get_create_surface(surface_id);
|
||||||
|
|
||||||
if (surface != nullptr)
|
|
||||||
{
|
|
||||||
if (check_client_cluster_knowledge(client, knowledge, surface))
|
if (check_client_cluster_knowledge(client, knowledge, surface))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deerith::check_client_cluster_knowledge(client_t *client, component_client_environment_knowledge_t &knowledge, surface_t *surface)
|
bool deerith::check_client_cluster_knowledge(client_t *client, component_client_environment_knowledge_t &knowledge, surface_t *surface)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < surface->voxel_clusters.size(); i++)
|
for (int layer = -3; layer < 4; layer++)
|
||||||
{
|
{
|
||||||
voxel_cluster_t *cluster = surface->voxel_clusters[i].get();
|
voxel_cluster_t *cluster = surface->get_cluster(layer);
|
||||||
|
if (cluster == nullptr)
|
||||||
|
{
|
||||||
|
cluster = surface->get_create_cluster(layer);
|
||||||
|
world_settings.generate_voxel_cluster(cluster);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t cluster_last_update = cluster->last_update_tick_id;
|
int32_t cluster_last_update = cluster->last_update_tick_id;
|
||||||
|
|
||||||
int32_t actual_cluster_kknowledge = -1;
|
int32_t actual_cluster_kknowledge = -1;
|
||||||
|
|||||||
@ -7,17 +7,23 @@
|
|||||||
namespace deerith
|
namespace deerith
|
||||||
{
|
{
|
||||||
void server_loop();
|
void server_loop();
|
||||||
|
void init_world();
|
||||||
|
|
||||||
|
world_settings_t world_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deerith::run_world(int port)
|
void deerith::run_world(const world_settings_t &__world_settings)
|
||||||
{
|
{
|
||||||
if (!init_server(port))
|
world_settings = __world_settings;
|
||||||
|
if (!init_server(world_settings.port))
|
||||||
{
|
{
|
||||||
deerith_error("could not init server");
|
deerith_error("could not init server");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
deerith_trace("server init on port {}", port);
|
init_world();
|
||||||
|
|
||||||
|
deerith_trace("server init on port {}", world_settings.port);
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
server_loop();
|
server_loop();
|
||||||
|
|||||||
@ -18,6 +18,13 @@ target_link_libraries(Sandbox
|
|||||||
DeerithServer
|
DeerithServer
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_custom_target(DeerithSandboxTextures ALL
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/textures"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/textures"
|
||||||
|
COMMENT "Copying DeerithClient shaders"
|
||||||
|
)
|
||||||
|
|
||||||
target_compile_definitions(Sandbox PRIVATE
|
target_compile_definitions(Sandbox PRIVATE
|
||||||
$<$<CONFIG:Debug>:DEBUG>
|
$<$<CONFIG:Debug>:DEBUG>
|
||||||
)
|
)
|
||||||
@ -1,8 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <deerith/world/environment.h>
|
||||||
|
|
||||||
namespace sandbox
|
namespace sandbox
|
||||||
{
|
{
|
||||||
|
void define_voxel_texture_atlas(deerith::atlas_builder_t &);
|
||||||
void define_voxel_materials();
|
void define_voxels_materials(deerith::texture_atlas_t *);
|
||||||
void define_voxels_types();
|
void define_voxels_types();
|
||||||
|
|
||||||
|
void generate_voxel_cluster(deerith::voxel_cluster_t *);
|
||||||
}
|
}
|
||||||
@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace sandbox
|
|
||||||
{
|
|
||||||
void build_world();
|
|
||||||
}
|
|
||||||
@ -1,120 +1,44 @@
|
|||||||
#include "world.h"
|
#include "voxels.h"
|
||||||
|
#include <FastNoise/FastNoiseLite.h>
|
||||||
#include <deerith/world/environment.h>
|
#include <deerith/world/environment.h>
|
||||||
|
|
||||||
namespace deerith
|
namespace deerith
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
void sandbox::generate_voxel_cluster(deerith::voxel_cluster_t *cluster)
|
||||||
void sandbox::build_world()
|
|
||||||
{
|
{
|
||||||
|
FastNoiseLite noise;
|
||||||
|
noise.SetNoiseType(FastNoiseLite::NoiseType_Perlin);
|
||||||
|
|
||||||
constexpr int SIZE = 32;
|
for (int x = 0; x < deerith::CLUSTER_SIZE; x++)
|
||||||
constexpr int WALL_HEIGHT = 5;
|
{
|
||||||
constexpr int TOWER_HEIGHT = 12;
|
for (int z = 0; z < deerith::CLUSTER_SIZE; z++)
|
||||||
|
{
|
||||||
|
float world_x = static_cast<float>(cluster->surface_id.x * deerith::CLUSTER_SIZE + x) * deerith::VOXEL_SIZE;
|
||||||
|
float world_z = static_cast<float>(cluster->surface_id.y * deerith::CLUSTER_SIZE + z) * deerith::VOXEL_SIZE;
|
||||||
|
|
||||||
// Foundation
|
float noise_height_1 = noise.GetNoise(world_x, world_z);
|
||||||
for (int x = 0; x < SIZE; ++x)
|
float noise_height_2 = noise.GetNoise(world_x * 5 + 101, world_z * 5 + 221);
|
||||||
{
|
float noise_height_3 = noise.GetNoise(world_x * 8 - 1030, world_z * 8 - 540);
|
||||||
for (int z = 0; z < SIZE; ++z)
|
|
||||||
{
|
|
||||||
deerith::set_voxel(1, glm::vec3(x, 0, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Outer walls
|
// Terrain height in voxel units
|
||||||
for (int x = 0; x < SIZE; ++x)
|
int terrain_height = static_cast<int>(noise_height_1 * 240.0f * deerith::VOXEL_SIZE);
|
||||||
{
|
terrain_height += static_cast<int>(noise_height_2 * 20.0f * deerith::VOXEL_SIZE);
|
||||||
for (int y = 1; y <= WALL_HEIGHT; ++y)
|
terrain_height += static_cast<int>(noise_height_3 * 5.0f * deerith::VOXEL_SIZE);
|
||||||
{
|
|
||||||
// Entrance
|
|
||||||
if (x >= 13 && x <= 18 && y <= 3)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
deerith::set_voxel(1, glm::vec3(x, y, 0));
|
// Cluster's bottom position in voxel units
|
||||||
deerith::set_voxel(1, glm::vec3(x, y, SIZE - 1));
|
int cluster_bottom = cluster->layer * deerith::CLUSTER_SIZE;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int z = 0; z < SIZE; ++z)
|
// Height relative to this cluster
|
||||||
{
|
int relative_height = terrain_height - cluster_bottom;
|
||||||
for (int y = 1; y <= WALL_HEIGHT; ++y)
|
|
||||||
{
|
|
||||||
deerith::set_voxel(1, glm::vec3(0, y, z));
|
|
||||||
deerith::set_voxel(1, glm::vec3(SIZE - 1, y, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Corner towers
|
relative_height = std::clamp(relative_height, 0, deerith::CLUSTER_SIZE);
|
||||||
for (int tx : {0, SIZE - 1})
|
|
||||||
{
|
|
||||||
for (int tz : {0, SIZE - 1})
|
|
||||||
{
|
|
||||||
for (int x = tx - 2; x <= tx + 2; ++x)
|
|
||||||
{
|
|
||||||
for (int z = tz - 2; z <= tz + 2; ++z)
|
|
||||||
{
|
|
||||||
for (int y = 1; y <= TOWER_HEIGHT; ++y)
|
|
||||||
{
|
|
||||||
bool inside =
|
|
||||||
x > tx - 2 && x < tx + 2 &&
|
|
||||||
z > tz - 2 && z < tz + 2;
|
|
||||||
|
|
||||||
if (!inside)
|
for (int y = 0; y < relative_height; y++)
|
||||||
{
|
{
|
||||||
deerith::set_voxel(1, glm::vec3(x, y, z));
|
cluster->__data[x][y][z] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Tower roofs
|
|
||||||
for (int x = tx - 3; x <= tx + 3; ++x)
|
|
||||||
{
|
|
||||||
for (int z = tz - 3; z <= tz + 3; ++z)
|
|
||||||
{
|
|
||||||
deerith::set_voxel(
|
|
||||||
1, glm::vec3(x, TOWER_HEIGHT + 1, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Central keep
|
|
||||||
for (int x = 10; x <= 21; ++x)
|
|
||||||
{
|
|
||||||
for (int z = 10; z <= 21; ++z)
|
|
||||||
{
|
|
||||||
for (int y = 1; y <= 10; ++y)
|
|
||||||
{
|
|
||||||
bool inside =
|
|
||||||
x > 11 && x < 20 &&
|
|
||||||
z > 11 && z < 20;
|
|
||||||
|
|
||||||
if (!inside)
|
|
||||||
{
|
|
||||||
deerith::set_voxel(1, glm::vec3(x, y, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep roof
|
|
||||||
for (int x = 9; x <= 22; ++x)
|
|
||||||
{
|
|
||||||
for (int z = 9; z <= 22; ++z)
|
|
||||||
{
|
|
||||||
deerith::set_voxel(1, glm::vec3(x, 11, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entrance bridge
|
|
||||||
for (int x = 13; x <= 18; ++x)
|
|
||||||
{
|
|
||||||
for (int z = -5; z < 0; ++z)
|
|
||||||
{
|
|
||||||
deerith::set_voxel(1, glm::vec3(x, 0, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,7 +1,34 @@
|
|||||||
#include "voxels.h"
|
#include "voxels.h"
|
||||||
#include <deerith/world/voxels.h>
|
#include <deerith/world/voxels.h>
|
||||||
|
#include <deerith/world/texture.h>
|
||||||
|
|
||||||
void sandbox::define_voxel_materials()
|
#include <memory>
|
||||||
|
|
||||||
|
void define_voxels_materials(deerith::texture_atlas_t *);
|
||||||
|
void define_voxels_types();
|
||||||
|
|
||||||
|
void sandbox::define_voxel_texture_atlas(deerith::atlas_builder_t &builder)
|
||||||
|
{
|
||||||
|
builder.unit_size = 64;
|
||||||
|
|
||||||
|
{
|
||||||
|
deerith::texture_builder_entry_t entry;
|
||||||
|
entry.id = "snow";
|
||||||
|
entry.texture_location = "textures/snow.png";
|
||||||
|
|
||||||
|
builder.entries.push_back(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
deerith::texture_builder_entry_t entry;
|
||||||
|
entry.id = "grass_block_snow";
|
||||||
|
entry.texture_location = "textures/grass_block_snow.png";
|
||||||
|
|
||||||
|
builder.entries.push_back(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sandbox::define_voxels_materials(deerith::texture_atlas_t *voxel_atlas)
|
||||||
{
|
{
|
||||||
// air
|
// air
|
||||||
{
|
{
|
||||||
@ -12,13 +39,14 @@ void sandbox::define_voxel_materials()
|
|||||||
deerith::register_voxel_material(voxel_material);
|
deerith::register_voxel_material(voxel_material);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rock
|
// snow
|
||||||
{
|
{
|
||||||
deerith::voxel_material_t voxel_material;
|
deerith::voxel_material_t voxel_material;
|
||||||
voxel_material.id = "rock";
|
voxel_material.id = "snow";
|
||||||
voxel_material.material_type = deerith::voxel_material_type_t::SOLID;
|
voxel_material.material_type = deerith::voxel_material_type_t::SOLID;
|
||||||
|
|
||||||
// textures...
|
voxel_material.set_same_face_texture(voxel_atlas->get_texture_position("grass_block_snow"));
|
||||||
|
voxel_material.face_texture_id[deerith::direction_up] = voxel_atlas->get_texture_position("snow");
|
||||||
|
|
||||||
deerith::register_voxel_material(voxel_material);
|
deerith::register_voxel_material(voxel_material);
|
||||||
}
|
}
|
||||||
@ -40,9 +68,9 @@ void sandbox::define_voxels_types()
|
|||||||
{
|
{
|
||||||
deerith::voxel_type_t voxel_type;
|
deerith::voxel_type_t voxel_type;
|
||||||
voxel_type.is_solid = true;
|
voxel_type.is_solid = true;
|
||||||
voxel_type.id = "rock";
|
voxel_type.id = "snow";
|
||||||
|
|
||||||
voxel_type.material_id = deerith::get_voxel_material_id("rock");
|
voxel_type.material_id = deerith::get_voxel_material_id("snow");
|
||||||
deerith::register_voxel_type(voxel_type);
|
deerith::register_voxel_type(voxel_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,23 +5,23 @@
|
|||||||
#include <args/argh.h>
|
#include <args/argh.h>
|
||||||
|
|
||||||
#include "voxels.h"
|
#include "voxels.h"
|
||||||
#include "world.h"
|
|
||||||
|
|
||||||
int main(int argc, const char **argv)
|
int main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
deerith::init_engine();
|
deerith::init_engine();
|
||||||
auto cmdl = argh::parser(argc, argv);
|
auto cmdl = argh::parser(argc, argv);
|
||||||
|
|
||||||
int port = 8080;
|
deerith::world_settings_t world_settings;
|
||||||
cmdl("port", 8080) >> port;
|
cmdl("port", 8080) >> world_settings.port;
|
||||||
|
|
||||||
sandbox::define_voxel_materials();
|
world_settings.define_voxel_texture_atlas_function = sandbox::define_voxel_texture_atlas;
|
||||||
sandbox::define_voxels_types();
|
world_settings.define_voxels_materials_function = sandbox::define_voxels_materials;
|
||||||
|
world_settings.define_voxels_types_function = sandbox::define_voxels_types;
|
||||||
|
|
||||||
sandbox::build_world();
|
world_settings.generate_voxel_cluster = sandbox::generate_voxel_cluster;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (cmdl[{"-s", "--single"}] && !deerith::execute_client("../deerith_client/DeerithClient", port))
|
if (cmdl[{"-s", "--single"}] && !deerith::execute_client("../deerith_client/DeerithClient", world_settings.port))
|
||||||
{
|
{
|
||||||
deerith_error("could not start server");
|
deerith_error("could not start server");
|
||||||
deerith::shutdown_engine();
|
deerith::shutdown_engine();
|
||||||
@ -29,7 +29,7 @@ int main(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
deerith::run_world(8080);
|
deerith::run_world(world_settings);
|
||||||
|
|
||||||
deerith::shutdown_executing_servers();
|
deerith::shutdown_executing_servers();
|
||||||
deerith::shutdown_engine();
|
deerith::shutdown_engine();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user