From 535bc27c560f8ae11579bea77340f64844990a05 Mon Sep 17 00:00:00 2001 From: Chewico Date: Tue, 3 Nov 2026 18:56:57 +0100 Subject: [PATCH] simple box render --- .../include/deerith/client/graphics/input.h | 130 ++++++++++++++++- .../include/deerith/client/graphics/mesh.h | 27 +++- .../client/internals/cluster_generation.h | 73 ++++++++++ .../network.h} | 0 .../world_internals.h => internals/world.h} | 0 deerith_client/include/deerith/client/world.h | 4 + .../deerith/client/world/chunk_render.h | 13 -- deerith_client/shaders/lit.frag.glsl | 24 +++- deerith_client/shaders/lit.vert.glsl | 11 +- deerith_client/src/engine.cpp | 2 +- deerith_client/src/graphics/input.cpp | 66 +++++++++ deerith_client/src/graphics/mesh.cpp | 50 ++++++- deerith_client/src/graphics/window.cpp | 25 ++-- deerith_client/src/main.cpp | 7 - deerith_client/src/network/network.cpp | 2 +- .../src/world/cluster_generation.cpp | 134 ++++++++++++++++++ deerith_client/src/world/player_movment.cpp | 107 ++++++++++++-- .../src/world/server_communication.cpp | 5 +- deerith_client/src/world/world.cpp | 6 +- deerith_client/src/world/world_render.cpp | 42 ++++-- .../include/deerith/world/components.h | 1 + .../include/deerith/world/environment.h | 3 + deerith_engine_core/src/world/environment.cpp | 64 ++++++++- sandbox/src/build_world.cpp | 3 + 24 files changed, 725 insertions(+), 74 deletions(-) create mode 100644 deerith_client/include/deerith/client/internals/cluster_generation.h rename deerith_client/include/deerith/client/{network/network_internals.h => internals/network.h} (100%) rename deerith_client/include/deerith/client/{world/world_internals.h => internals/world.h} (100%) delete mode 100644 deerith_client/include/deerith/client/world/chunk_render.h create mode 100644 deerith_client/src/world/cluster_generation.cpp diff --git a/deerith_client/include/deerith/client/graphics/input.h b/deerith_client/include/deerith/client/graphics/input.h index bb297b6..3940538 100644 --- a/deerith_client/include/deerith/client/graphics/input.h +++ b/deerith_client/include/deerith/client/graphics/input.h @@ -4,4 +4,132 @@ namespace deerith { glm::vec2 get_joystick_axes(int controller_id, int axe_id); -} \ No newline at end of file + glm::vec2 get_mouse_delta(); + bool get_key_down(int key_id); + void set_mouse_locked(bool locked); + bool get_mouse_button(int id); +} + +/* Printable keys */ +#define DEERITH_KEY_SPACE 32 +#define DEERITH_KEY_APOSTROPHE 39 /* ' */ +#define DEERITH_KEY_COMMA 44 /* , */ +#define DEERITH_KEY_MINUS 45 /* - */ +#define DEERITH_KEY_PERIOD 46 /* . */ +#define DEERITH_KEY_SLASH 47 /* / */ +#define DEERITH_KEY_0 48 +#define DEERITH_KEY_1 49 +#define DEERITH_KEY_2 50 +#define DEERITH_KEY_3 51 +#define DEERITH_KEY_4 52 +#define DEERITH_KEY_5 53 +#define DEERITH_KEY_6 54 +#define DEERITH_KEY_7 55 +#define DEERITH_KEY_8 56 +#define DEERITH_KEY_9 57 +#define DEERITH_KEY_SEMICOLON 59 /* ; */ +#define DEERITH_KEY_EQUAL 61 /* = */ +#define DEERITH_KEY_A 65 +#define DEERITH_KEY_B 66 +#define DEERITH_KEY_C 67 +#define DEERITH_KEY_D 68 +#define DEERITH_KEY_E 69 +#define DEERITH_KEY_F 70 +#define DEERITH_KEY_G 71 +#define DEERITH_KEY_H 72 +#define DEERITH_KEY_I 73 +#define DEERITH_KEY_J 74 +#define DEERITH_KEY_K 75 +#define DEERITH_KEY_L 76 +#define DEERITH_KEY_M 77 +#define DEERITH_KEY_N 78 +#define DEERITH_KEY_O 79 +#define DEERITH_KEY_P 80 +#define DEERITH_KEY_Q 81 +#define DEERITH_KEY_R 82 +#define DEERITH_KEY_S 83 +#define DEERITH_KEY_T 84 +#define DEERITH_KEY_U 85 +#define DEERITH_KEY_V 86 +#define DEERITH_KEY_W 87 +#define DEERITH_KEY_X 88 +#define DEERITH_KEY_Y 89 +#define DEERITH_KEY_Z 90 +#define DEERITH_KEY_LEFT_BRACKET 91 /* [ */ +#define DEERITH_KEY_BACKSLASH 92 /* \ */ +#define DEERITH_KEY_RIGHT_BRACKET 93 /* ] */ +#define DEERITH_KEY_GRAVE_ACCENT 96 /* ` */ +#define DEERITH_KEY_WORLD_1 161 /* non-US #1 */ +#define DEERITH_KEY_WORLD_2 162 /* non-US #2 */ + +/* Function keys */ +#define DEERITH_KEY_ESCAPE 256 +#define DEERITH_KEY_ENTER 257 +#define DEERITH_KEY_TAB 258 +#define DEERITH_KEY_BACKSPACE 259 +#define DEERITH_KEY_INSERT 260 +#define DEERITH_KEY_DELETE 261 +#define DEERITH_KEY_RIGHT 262 +#define DEERITH_KEY_LEFT 263 +#define DEERITH_KEY_DOWN 264 +#define DEERITH_KEY_UP 265 +#define DEERITH_KEY_PAGE_UP 266 +#define DEERITH_KEY_PAGE_DOWN 267 +#define DEERITH_KEY_HOME 268 +#define DEERITH_KEY_END 269 +#define DEERITH_KEY_CAPS_LOCK 280 +#define DEERITH_KEY_SCROLL_LOCK 281 +#define DEERITH_KEY_NUM_LOCK 282 +#define DEERITH_KEY_PRINT_SCREEN 283 +#define DEERITH_KEY_PAUSE 284 +#define DEERITH_KEY_F1 290 +#define DEERITH_KEY_F2 291 +#define DEERITH_KEY_F3 292 +#define DEERITH_KEY_F4 293 +#define DEERITH_KEY_F5 294 +#define DEERITH_KEY_F6 295 +#define DEERITH_KEY_F7 296 +#define DEERITH_KEY_F8 297 +#define DEERITH_KEY_F9 298 +#define DEERITH_KEY_F10 299 +#define DEERITH_KEY_F11 300 +#define DEERITH_KEY_F12 301 +#define DEERITH_KEY_F13 302 +#define DEERITH_KEY_F14 303 +#define DEERITH_KEY_F15 304 +#define DEERITH_KEY_F16 305 +#define DEERITH_KEY_F17 306 +#define DEERITH_KEY_F18 307 +#define DEERITH_KEY_F19 308 +#define DEERITH_KEY_F20 309 +#define DEERITH_KEY_F21 310 +#define DEERITH_KEY_F22 311 +#define DEERITH_KEY_F23 312 +#define DEERITH_KEY_F24 313 +#define DEERITH_KEY_F25 314 +#define DEERITH_KEY_KP_0 320 +#define DEERITH_KEY_KP_1 321 +#define DEERITH_KEY_KP_2 322 +#define DEERITH_KEY_KP_3 323 +#define DEERITH_KEY_KP_4 324 +#define DEERITH_KEY_KP_5 325 +#define DEERITH_KEY_KP_6 326 +#define DEERITH_KEY_KP_7 327 +#define DEERITH_KEY_KP_8 328 +#define DEERITH_KEY_KP_9 329 +#define DEERITH_KEY_KP_DECIMAL 330 +#define DEERITH_KEY_KP_DIVIDE 331 +#define DEERITH_KEY_KP_MULTIPLY 332 +#define DEERITH_KEY_KP_SUBTRACT 333 +#define DEERITH_KEY_KP_ADD 334 +#define DEERITH_KEY_KP_ENTER 335 +#define DEERITH_KEY_KP_EQUAL 336 +#define DEERITH_KEY_LEFT_SHIFT 340 +#define DEERITH_KEY_LEFT_CONTROL 341 +#define DEERITH_KEY_LEFT_ALT 342 +#define DEERITH_KEY_LEFT_SUPER 343 +#define DEERITH_KEY_RIGHT_SHIFT 344 +#define DEERITH_KEY_RIGHT_CONTROL 345 +#define DEERITH_KEY_RIGHT_ALT 346 +#define DEERITH_KEY_RIGHT_SUPER 347 +#define DEERITH_KEY_MENU 348 \ No newline at end of file diff --git a/deerith_client/include/deerith/client/graphics/mesh.h b/deerith_client/include/deerith/client/graphics/mesh.h index 6b69421..357eae4 100644 --- a/deerith_client/include/deerith/client/graphics/mesh.h +++ b/deerith_client/include/deerith/client/graphics/mesh.h @@ -1,5 +1,6 @@ #pragma once #include +#include namespace deerith { @@ -14,17 +15,32 @@ namespace deerith ~mesh_2d_t(); private: - unsigned int vao; - unsigned int vbo; - unsigned int ebo; + unsigned int vao = 0; + unsigned int vbo = 0; + unsigned int ebo = 0; size_t index_count; }; + struct vertex_3d_t + { + glm::vec3 position; + glm::vec3 normal; + glm::vec2 uv; + }; + + struct mesh_3d_data_t + { + std::vector vertices; + std::vector indices; + }; + class mesh_3d_t { public: + // obsolete mesh_3d_t(const glm::vec3 *vertices, size_t vertex_size, const unsigned int *indices, size_t index_count); + mesh_3d_t(const mesh_3d_data_t &mesh_data); void bind() const; void draw() const; @@ -37,7 +53,8 @@ namespace deerith unsigned int vbo; unsigned int ebo; - size_t index_count; - size_t vertex_count; + size_t index_count = 0; + size_t vertex_count = 0; }; + } \ No newline at end of file diff --git a/deerith_client/include/deerith/client/internals/cluster_generation.h b/deerith_client/include/deerith/client/internals/cluster_generation.h new file mode 100644 index 0000000..81ea353 --- /dev/null +++ b/deerith_client/include/deerith/client/internals/cluster_generation.h @@ -0,0 +1,73 @@ +#pragma once +#include + +namespace deerith +{ + glm::ivec3 voxel_direction_order[6] = { + glm::ivec3(-1, 0, 0), + glm::ivec3(1, 0, 0), + glm::ivec3(0, -1, 0), + glm::ivec3(0, 1, 0), + glm::ivec3(0, 0, -1), + glm::ivec3(0, 0, 1), + }; + + glm::vec3 voxel_direction_vertices[6][4] = { + // -X + { + {0, 0, 0}, + {0, 0, 1}, + {0, 1, 1}, + {0, 1, 0}, + }, + + // +X + { + {1, 0, 0}, + {1, 1, 0}, + {1, 1, 1}, + {1, 0, 1}, + }, + + // -Y + { + {0, 0, 0}, + {1, 0, 0}, + {1, 0, 1}, + {0, 0, 1}, + }, + + // +Y + { + {0, 1, 0}, + {0, 1, 1}, + {1, 1, 1}, + {1, 1, 0}, + }, + + // -Z + { + {0, 0, 0}, + {0, 1, 0}, + {1, 1, 0}, + {1, 0, 0}, + }, + + // +Z + { + {0, 0, 1}, + {1, 0, 1}, + {1, 1, 1}, + {0, 1, 1}, + }, + }; + + uint32_t face_indices_order[6] = { + 0, + 1, + 2, + 0, + 2, + 3, + }; +} \ No newline at end of file diff --git a/deerith_client/include/deerith/client/network/network_internals.h b/deerith_client/include/deerith/client/internals/network.h similarity index 100% rename from deerith_client/include/deerith/client/network/network_internals.h rename to deerith_client/include/deerith/client/internals/network.h diff --git a/deerith_client/include/deerith/client/world/world_internals.h b/deerith_client/include/deerith/client/internals/world.h similarity index 100% rename from deerith_client/include/deerith/client/world/world_internals.h rename to deerith_client/include/deerith/client/internals/world.h diff --git a/deerith_client/include/deerith/client/world.h b/deerith_client/include/deerith/client/world.h index ed8842b..26f14d4 100644 --- a/deerith_client/include/deerith/client/world.h +++ b/deerith_client/include/deerith/client/world.h @@ -1,5 +1,6 @@ #pragma once #include +#include namespace deerith { @@ -11,5 +12,8 @@ namespace deerith bool is_world_running(); void render_world(); + void generate_cluster(glm::ivec2 cluster_id, size_t cluster_height_id); + void load_clusters_to_gpu(); + client_t *get_server_client(); } \ No newline at end of file diff --git a/deerith_client/include/deerith/client/world/chunk_render.h b/deerith_client/include/deerith/client/world/chunk_render.h deleted file mode 100644 index c3a4d29..0000000 --- a/deerith_client/include/deerith/client/world/chunk_render.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include -#include - -namespace deerith -{ - struct chunk_render_t - { - std::unique_ptr chunk_mesh; - - void draw(); - }; -} \ No newline at end of file diff --git a/deerith_client/shaders/lit.frag.glsl b/deerith_client/shaders/lit.frag.glsl index 5e5c1ff..daed9da 100644 --- a/deerith_client/shaders/lit.frag.glsl +++ b/deerith_client/shaders/lit.frag.glsl @@ -1,10 +1,28 @@ #version 330 core -uniform vec4 u_color = vec4(0.75, 0.8, 0.9, 1.0); +in vec3 frag_position; +in vec3 frag_normal; -out vec4 frag_color; +uniform vec3 u_color = vec3(1,1,1); +uniform vec3 u_light_direction = vec3(1, 3, 2); + +out vec4 FragColor; void main() { - frag_color = u_color; + + // 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; + + vec3 color = u_color * lighting; + + FragColor = vec4(color, 1.0); } \ No newline at end of file diff --git a/deerith_client/shaders/lit.vert.glsl b/deerith_client/shaders/lit.vert.glsl index 5259fbf..a3aab47 100644 --- a/deerith_client/shaders/lit.vert.glsl +++ b/deerith_client/shaders/lit.vert.glsl @@ -1,12 +1,21 @@ #version 330 core layout (location = 0) in vec3 a_position; +layout (location = 1) in vec3 a_normal; uniform mat4 u_model; uniform mat4 u_view; uniform mat4 u_projection; +out vec3 frag_position; +out vec3 frag_normal; + void main() { - gl_Position = u_projection * u_view * u_model * vec4(a_position, 1.0); + 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; } \ No newline at end of file diff --git a/deerith_client/src/engine.cpp b/deerith_client/src/engine.cpp index a2e9ad1..daf1847 100644 --- a/deerith_client/src/engine.cpp +++ b/deerith_client/src/engine.cpp @@ -1,5 +1,5 @@ #include -#include +#include void deerith::init_engine() { diff --git a/deerith_client/src/graphics/input.cpp b/deerith_client/src/graphics/input.cpp index 8888caf..3f32ac0 100644 --- a/deerith_client/src/graphics/input.cpp +++ b/deerith_client/src/graphics/input.cpp @@ -28,4 +28,70 @@ glm::vec2 deerith::get_joystick_axes(int controller_id, int axe_id) } return glm::vec2(corrected_axe_x, corrected_axe_y); +} + +glm::vec2 deerith::get_mouse_delta() +{ + static double last_x = 0.0; + static double last_y = 0.0; + static bool first_call = true; + + GLFWwindow *window = glfwGetCurrentContext(); + + if (!window) + { + return glm::vec2(0.0f); + } + + double current_x, current_y; + glfwGetCursorPos(window, ¤t_x, ¤t_y); + + if (first_call) + { + last_x = current_x; + last_y = current_y; + first_call = false; + + return glm::vec2(0.0f); + } + + glm::vec2 delta( + static_cast(current_x - last_x), + static_cast(last_y - current_y)); + + last_x = current_x; + last_y = current_y; + + return delta; +} + +bool deerith::get_key_down(int key_id) +{ + GLFWwindow *window = glfwGetCurrentContext(); + if (!window) + { + return false; + } + return glfwGetKey(window, key_id) == GLFW_PRESS; +} + +bool deerith::get_mouse_button(int button) +{ + GLFWwindow *window = glfwGetCurrentContext(); + if (!window) + return false; + + return glfwGetMouseButton(window, button) == GLFW_PRESS; +} + +void deerith::set_mouse_locked(bool locked) +{ + GLFWwindow *window = glfwGetCurrentContext(); + if (!window) + return; + + glfwSetInputMode( + window, + GLFW_CURSOR, + locked ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL); } \ No newline at end of file diff --git a/deerith_client/src/graphics/mesh.cpp b/deerith_client/src/graphics/mesh.cpp index 6ecb6c1..5a59190 100644 --- a/deerith_client/src/graphics/mesh.cpp +++ b/deerith_client/src/graphics/mesh.cpp @@ -1,5 +1,7 @@ #include +#include #include +#include deerith::mesh_2d_t::mesh_2d_t( const glm::vec2 *vertices, @@ -65,6 +67,51 @@ void deerith::mesh_2d_t::draw() const nullptr); } +deerith::mesh_3d_t::mesh_3d_t(const mesh_3d_data_t &mesh_data) + : index_count(mesh_data.indices.size()), vertex_count(mesh_data.vertices.size()) +{ + glGenVertexArrays(1, &vao); + glGenBuffers(1, &vbo); + glGenBuffers(1, &ebo); + + glBindVertexArray(vao); + + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData( + GL_ARRAY_BUFFER, + mesh_data.vertices.size() * sizeof(vertex_3d_t), + mesh_data.vertices.data(), + GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + glBufferData( + GL_ELEMENT_ARRAY_BUFFER, + mesh_data.indices.size() * sizeof(unsigned int), + mesh_data.indices.data(), + GL_STATIC_DRAW); + + glVertexAttribPointer( + 0, + 3, + GL_FLOAT, + GL_FALSE, + sizeof(vertex_3d_t), + (void *)offsetof(vertex_3d_t, position)); + + glVertexAttribPointer( + 1, + 3, + GL_FLOAT, + GL_FALSE, + sizeof(vertex_3d_t), + (void *)offsetof(vertex_3d_t, normal)); + + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + + glBindVertexArray(0); +} + deerith::mesh_3d_t::mesh_3d_t( const glm::vec3 *vertices, std::size_t _vertex_count, @@ -92,13 +139,12 @@ deerith::mesh_3d_t::mesh_3d_t( indices, GL_STATIC_DRAW); - // Position: vec2 glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, - 3 * sizeof(float), + sizeof(glm::vec3), nullptr); glEnableVertexAttribArray(0); diff --git a/deerith_client/src/graphics/window.cpp b/deerith_client/src/graphics/window.cpp index 7485f87..6dddc15 100644 --- a/deerith_client/src/graphics/window.cpp +++ b/deerith_client/src/graphics/window.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include @@ -65,11 +65,13 @@ int deerith::init_window() return -1; } - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + glFrontFace(GL_CCW); + + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); init_primitives(); init_imgui(); @@ -90,6 +92,17 @@ bool deerith::begin_window_display() return false; } + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + + glViewport(0, 0, display_w, display_h); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glClearColor(0.1f, 0.1f, 0.15f, 1.0f); + glClearDepth(1.0); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); @@ -122,10 +135,6 @@ void deerith::finish_window_display() frame_id++; glfwSwapBuffers(window); - - glClearColor(0.1f, 0.1f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - glClear(GL_DEPTH_BUFFER_BIT); } void deerith::shutdown_window() diff --git a/deerith_client/src/main.cpp b/deerith_client/src/main.cpp index 298c057..692a0d7 100644 --- a/deerith_client/src/main.cpp +++ b/deerith_client/src/main.cpp @@ -14,13 +14,6 @@ int main(int argc, const char **argv) int port = 8080; cmdl("port", 8080) >> port; - if (cmdl[{"-s", "--single"}] && !deerith::execute_client("../sandbox/SandboxServer", port)) - { - deerith_error("could not start server"); - deerith::shutdown_engine(); - return 1; - } - std::this_thread::sleep_for(std::chrono::milliseconds(100)); if (deerith::connect_to_world("127.0.0.1", port)) diff --git a/deerith_client/src/network/network.cpp b/deerith_client/src/network/network.cpp index 6400472..cac6353 100644 --- a/deerith_client/src/network/network.cpp +++ b/deerith_client/src/network/network.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include namespace deerith { diff --git a/deerith_client/src/world/cluster_generation.cpp b/deerith_client/src/world/cluster_generation.cpp new file mode 100644 index 0000000..5ebcdc5 --- /dev/null +++ b/deerith_client/src/world/cluster_generation.cpp @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include +#include + +namespace deerith +{ + cluster_voxel_type_id_data_t *cluster_data = nullptr; + glm::ivec2 cluster_id; + size_t cluster_height_id; + + void generate_voxel(int x, int y, int z); + voxel_type_id_t get_cluster_voxel(int x, int y, int z); + + std::unique_ptr test_mesh; + std::unique_ptr build_data; +} + +void deerith::load_clusters_to_gpu() +{ + if (build_data) + { + test_mesh = std::make_unique(*build_data); + build_data.reset(); + } +} + +void deerith::generate_cluster(glm::ivec2 _cluster_id, size_t _cluster_height_id) +{ + if (build_data) + { + return; + } + + build_data = std::make_unique(); + + cluster_data = get_cluster_voxel_type_id_raw_ponter(_cluster_id, _cluster_height_id); + cluster_id = _cluster_id; + cluster_height_id = _cluster_height_id; + + if (cluster_data == nullptr) + { + deerith_error("cluster data is null and it should not generate_cluster"); + return; + } + + for (int x = 0; x < CLUSTER_SIZE; x++) + { + for (int y = 0; y < CLUSTER_SIZE; y++) + { + for (int z = 0; z < CLUSTER_SIZE; z++) + { + generate_voxel(x, y, z); + } + } + } +} + +void deerith::generate_voxel(int x, int y, int z) +{ + voxel_type_id_t cur_type_id = (*cluster_data)[x][y][z]; + const voxel_type_t &cur_type = get_voxel_type(cur_type_id); + + if (!cur_type.is_solid) + { + // nothing to build + return; + } + + glm::vec3 voxel_position = glm::vec3(x, y, z) * VOXEL_SIZE; + + for (int i = 0; i < 6; i++) + { + const int check_x = x + voxel_direction_order[i].x; + const int check_y = y + voxel_direction_order[i].y; + const int check_z = z + voxel_direction_order[i].z; + + voxel_type_id_t check_voxel_id = get_cluster_voxel(check_x, check_y, check_z); + const voxel_type_t &check_voxel_type = get_voxel_type(check_voxel_id); + + if (check_voxel_type.is_solid) + { + continue; + } + + uint32_t starting_index = build_data->vertices.size(); + + // HEY BUILD FACE + for (int v = 0; v < 4; v++) + { + vertex_3d_t vertex = { + .position = voxel_position + voxel_direction_vertices[i][v] * VOXEL_SIZE, + .normal = voxel_direction_order[i], + }; + + build_data->vertices.push_back(vertex); + } + + for (int index = 0; index < 6; index++) + { + build_data->indices.push_back(starting_index + face_indices_order[index]); + } + } +} + +deerith::voxel_type_id_t deerith::get_cluster_voxel(int x, int y, int z) +{ + bool in_bounds_check = true; + if (x < 0 || x >= CLUSTER_SIZE) + { + in_bounds_check = false; + } + if (y < 0 || y >= CLUSTER_SIZE) + { + in_bounds_check = false; + } + if (z < 0 || z >= CLUSTER_SIZE) + { + in_bounds_check = false; + } + + if (in_bounds_check) + { + return (*cluster_data)[x][y][z]; + } + + glm::ivec3 coords(x + CLUSTER_SIZE * cluster_id.x, + y + (cluster_height_id - STARTING_CLUSTER_HEIGHT) * CLUSTER_SIZE, + z + cluster_id.y * CLUSTER_SIZE); + + return get_voxel_id(coords); +} \ No newline at end of file diff --git a/deerith_client/src/world/player_movment.cpp b/deerith_client/src/world/player_movment.cpp index 5b98b2d..d6fbc69 100644 --- a/deerith_client/src/world/player_movment.cpp +++ b/deerith_client/src/world/player_movment.cpp @@ -5,11 +5,100 @@ #include #include -#include +#include namespace deerith { + void process_player_look(component_client_sync_character_t &sync); + void process_player_movement(component_client_sync_character_t &sync); +} +void deerith::process_player_look(component_client_sync_character_t &sync) +{ + if (self_entity == entt::null) + return; + + if (!is_windows_focused()) + return; + + bool looking = get_mouse_button(0); + + set_mouse_locked(looking); + + glm::vec2 mouse_delta = get_mouse_delta(); + + if (!looking) + return; + + sync.player_look.x += mouse_delta.x * 0.1f; + sync.player_look.y -= mouse_delta.y * 0.1f; + + sync.player_look.y = glm::clamp( + sync.player_look.y, + -89.0f, + 89.0f); +} + +void deerith::process_player_movement(component_client_sync_character_t &sync) +{ + if (self_entity == entt::null) + { + return; + } + + if (!is_windows_focused()) + { + sync.move_input = glm::vec3(0.0f); + return; + } + + glm::vec3 movement(0.0f); + + // WASD + if (get_key_down(DEERITH_KEY_W)) + { + movement.z += 1.0f; + } + + if (get_key_down(DEERITH_KEY_S)) + movement.z -= 1.0f; + + if (get_key_down(DEERITH_KEY_D)) + movement.x += 1.0f; + + if (get_key_down(DEERITH_KEY_A)) + movement.x -= 1.0f; + + // Up / Down + if (get_key_down(DEERITH_KEY_SPACE)) + movement.y += 1.0f; + + if (get_key_down(DEERITH_KEY_LEFT_CONTROL)) + movement.y -= 1.0f; + + // Normalize to prevent faster diagonal movement + if (glm::length(movement) > 0.0f) + movement = glm::normalize(movement); + + float yaw = glm::radians(sync.player_look.x); + + glm::vec3 forward( + glm::sin(yaw), + 0.0f, + glm::cos(yaw)); + + glm::vec3 right( + glm::cos(yaw), + 0.0f, + -glm::sin(yaw)); + + sync.move_input = + right * movement.x + + glm::vec3(0.0f, movement.y, 0.0f) + + forward * movement.z; + + sync.move_input = right * movement.x + glm::vec3(0.0f, movement.y, 0.0f) + forward * movement.z; + sync.position = sync.position.read_value() + sync.move_input.read_value() * 0.075f; } void deerith::process_player_input() @@ -17,17 +106,15 @@ void deerith::process_player_input() if (self_entity == entt::null) return; - glm::vec2 movment = get_joystick_axes(0, 0); - if (!is_windows_focused()) - { - movment = glm::vec2(0, 0); - } + auto &sync = get_component(self_entity); - component_client_sync_character_t &entity_sync_position = get_component(self_entity); + packet_update_player_input_t packet{}; - glm::vec3 movment_3d = glm::vec3(movment.x, 0, movment.y); - entity_sync_position.move_input = movment_3d; - entity_sync_position.position = entity_sync_position.position.read_value() + movment_3d * 0.1f; + process_player_look(sync); + process_player_movement(sync); + + packet.input_transport.load(sync.move_input); + packet.position_transport.load(sync.position); } void deerith::send_player_input() diff --git a/deerith_client/src/world/server_communication.cpp b/deerith_client/src/world/server_communication.cpp index f21cee0..7a83d7c 100644 --- a/deerith_client/src/world/server_communication.cpp +++ b/deerith_client/src/world/server_communication.cpp @@ -7,8 +7,8 @@ #include -#include -#include +#include +#include void deerith::setup_base_protocols() { @@ -104,4 +104,5 @@ template <> void deerith::process_packet(deerith::packet_cluster_data_t &packet, client_t *client) { set_cluster_voxel_type_id_raw_data(*packet.__cluster_data, packet.surface_id, packet.cluster_height_id); + generate_cluster(packet.surface_id, packet.cluster_height_id); } \ No newline at end of file diff --git a/deerith_client/src/world/world.cpp b/deerith_client/src/world/world.cpp index ae9c891..0c9e3fd 100644 --- a/deerith_client/src/world/world.cpp +++ b/deerith_client/src/world/world.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -46,8 +46,6 @@ void deerith::world_simulation() { flush_network_events(); - process_player_input(); - if (get_world_tick() % 2 == 0) { send_player_input(); diff --git a/deerith_client/src/world/world_render.cpp b/deerith_client/src/world/world_render.cpp index b014931..f9692fb 100644 --- a/deerith_client/src/world/world_render.cpp +++ b/deerith_client/src/world/world_render.cpp @@ -5,20 +5,44 @@ #include #include #include +#include #include #include +namespace deerith +{ + + extern std::unique_ptr test_mesh; +} + void deerith::render_world() { + process_player_input(); + load_clusters_to_gpu(); + get_lit_shader()->set_vec3("u_color", glm::vec3(0.8f, 0.8f, 0.8f)); set_primitive_viewspace(glm::vec2(-10, -10), glm::vec2(10, 10)); camera_t camera; - camera.position = glm::vec3(0, 3, -10); - set_camera_to_shader(camera, get_lit_shader()); + + auto self_view = get_entity_registry().view(); + for (auto [entity, sync_coords, client_sync_coords] : self_view.each()) + { + camera.position = client_sync_coords.position.read_value(); + + float yaw = glm::radians(client_sync_coords.player_look.x); + float pitch = glm::radians(client_sync_coords.player_look.y); + + glm::quat yaw_rotation = glm::angleAxis(yaw, glm::vec3(0, 1, 0)); + glm::quat pitch_rotation = glm::angleAxis(pitch, glm::vec3(1, 0, 0)); + + camera.rotation = glm::normalize(yaw_rotation * pitch_rotation); + + set_camera_to_shader(camera, get_lit_shader()); + } get_lit_shader()->use(); - get_lit_shader()->set_vec4("u_color", glm::vec4(0.8f, 0.8f, 0.8f, 1)); + get_lit_shader()->set_vec3("u_color", glm::vec3(0.8f, 0.8f, 0.8f)); set_transform_to_shader(glm::vec3(0, 0, 0), glm::identity(), glm::vec3(1, 1, 1), get_lit_shader()); get_grid_mesh()->draw_lines(); @@ -42,19 +66,17 @@ void deerith::render_world() } // we should expect only one registry - auto self_view = get_entity_registry().view(); - for (auto [entity, sync_coords, client_sync_coords] : self_view.each()) - { - glm::vec2 user_pos = client_sync_coords.position.read_value(); - glm::vec3 position = glm::vec3(user_pos.x, 0, user_pos.y); + if (test_mesh) + { + get_lit_shader()->set_vec3("u_color", glm::vec3(0.9f, 0.9f, 0.9f)); + glm::vec3 position = glm::vec3(0, 0, 0); glm::quat rotation = glm::identity(); glm::vec3 scale = glm::vec3(1, 1, 1); - get_lit_shader()->set_vec4("u_color", glm::vec4(0.8f, 0.8f, 0.8f, 1)); set_transform_to_shader(position, rotation, scale, get_lit_shader()); get_lit_shader()->use(); - get_cube_mesh()->draw(); + test_mesh->draw(); } } \ No newline at end of file diff --git a/deerith_engine_core/include/deerith/world/components.h b/deerith_engine_core/include/deerith/world/components.h index 2d28554..43c3e78 100644 --- a/deerith_engine_core/include/deerith/world/components.h +++ b/deerith_engine_core/include/deerith/world/components.h @@ -20,6 +20,7 @@ namespace deerith { sync_variable_t move_input; sync_variable_t position; + glm::vec2 player_look; }; struct component_sync_coordinates_t diff --git a/deerith_engine_core/include/deerith/world/environment.h b/deerith_engine_core/include/deerith/world/environment.h index f512814..e3702a8 100644 --- a/deerith_engine_core/include/deerith/world/environment.h +++ b/deerith_engine_core/include/deerith/world/environment.h @@ -9,6 +9,8 @@ namespace deerith inline constexpr int MAX_CLUSTER_IN_SURFACE = 16; inline constexpr int STARTING_CLUSTER_HEIGHT = -8; + inline constexpr float VOXEL_SIZE = 0.5f; + using surface_height_t = int16_t; using surface_height_data_t = std::array, CLUSTER_SIZE>; using cluster_voxel_type_id_data_t = std::array, CLUSTER_SIZE>, CLUSTER_SIZE>; @@ -24,6 +26,7 @@ namespace deerith void get_cluster_voxel_type_id_raw_data(cluster_voxel_type_id_data_t &data, glm::ivec2 surface_id, size_t cluster_height_id); void set_cluster_voxel_type_id_raw_data(const cluster_voxel_type_id_data_t &data, glm::ivec2 surface_id, size_t cluster_height_id); + cluster_voxel_type_id_data_t *get_cluster_voxel_type_id_raw_ponter(glm::ivec2 surface_id, size_t cluster_height_id); int32_t get_cluster_last_tick_update(glm::ivec2 surface_id, size_t height_id); } diff --git a/deerith_engine_core/src/world/environment.cpp b/deerith_engine_core/src/world/environment.cpp index 03628b6..5b89e58 100644 --- a/deerith_engine_core/src/world/environment.cpp +++ b/deerith_engine_core/src/world/environment.cpp @@ -38,6 +38,7 @@ namespace deerith size_t get_voxel_cluster_height_id(int height); surface_t *create_surface(glm::ivec2); + voxel_cluster_t *create_cluster(glm::ivec2, size_t); } deerith::surface_t *deerith::create_surface(glm::ivec2 surface_id) @@ -51,6 +52,35 @@ deerith::surface_t *deerith::create_surface(glm::ivec2 surface_id) return surfaces.back().get(); } +deerith::voxel_cluster_t *deerith::create_cluster(glm::ivec2 surface_id, size_t cluster_height_id) +{ + surface_t *surface = nullptr; + if (surface_id_index_map.contains(surface_id)) + { + size_t surface_index = surface_id_index_map[surface_id]; + surface = surfaces[surface_index].get(); + } + + surface->voxel_clusters[cluster_height_id] = std::make_unique(); + voxel_cluster_t *cluster = surface->voxel_clusters[cluster_height_id].get(); + + for (int x = 0; x < CLUSTER_SIZE; x++) + { + for (int z = 0; z < CLUSTER_SIZE; z++) + { + int start_height = 0; + int end_height = surface->__layer_height[x][z] - ((int)cluster_height_id + STARTING_CLUSTER_HEIGHT) * CLUSTER_SIZE; + + for (int y = start_height; y < end_height; y++) + { + cluster->data[x][y][z] = 1; + } + } + } + + return cluster; +} + deerith::voxel_type_id_t deerith::get_default_voxel(glm::ivec3 coords) { if (coords.y > 0) @@ -166,8 +196,7 @@ void deerith::set_voxel(voxel_type_id_t voxel_id, glm::ivec3 coordinates) voxel_cluster_t *cluster = surface->voxel_clusters[cluster_height_id].get(); if (cluster == nullptr) { - surface->voxel_clusters[cluster_height_id] = std::make_unique(); - cluster = surface->voxel_clusters[cluster_height_id].get(); + cluster = create_cluster(surface_id, cluster_height_id); } cluster->last_update_tick_id = get_world_tick(); @@ -311,8 +340,7 @@ void deerith::get_cluster_voxel_type_id_raw_data(cluster_voxel_type_id_data_t &d voxel_cluster_t *cluster = surface->voxel_clusters[cluster_height_id].get(); if (cluster == nullptr) { - surface->voxel_clusters[cluster_height_id] = std::make_unique(); - cluster = surface->voxel_clusters[cluster_height_id].get(); + cluster = create_cluster(surface_id, cluster_height_id); } data = cluster->data; @@ -342,10 +370,34 @@ void deerith::set_cluster_voxel_type_id_raw_data(const cluster_voxel_type_id_dat if (cluster == nullptr) { - surface->voxel_clusters[cluster_height_id] = std::make_unique(); - cluster = surface->voxel_clusters[cluster_height_id].get(); + cluster = create_cluster(surface_id, cluster_height_id); } cluster->data = data; cluster->last_update_tick_id = get_world_tick(); +} + +deerith::cluster_voxel_type_id_data_t *deerith::get_cluster_voxel_type_id_raw_ponter(glm::ivec2 surface_id, size_t cluster_height_id) +{ + if (cluster_height_id >= MAX_CLUSTER_IN_SURFACE) + { + deerith_warn("tried to write voxel data out of bounds"); + return nullptr; + } + + surface_t *surface = nullptr; + if (surface_id_index_map.contains(surface_id)) + { + size_t surface_index = surface_id_index_map[surface_id]; + surface = surfaces[surface_index].get(); + } + + if (surface == nullptr) + { + return nullptr; + } + + voxel_cluster_t *cluster = surface->voxel_clusters[cluster_height_id].get(); + + return &cluster->data; } \ No newline at end of file diff --git a/sandbox/src/build_world.cpp b/sandbox/src/build_world.cpp index a34f022..af4dd41 100644 --- a/sandbox/src/build_world.cpp +++ b/sandbox/src/build_world.cpp @@ -10,5 +10,8 @@ namespace deerith void sandbox::build_world() { deerith::set_surface_height(glm::ivec2(2, 2), 5); + deerith::set_surface_height(glm::ivec2(2, 3), 7); + deerith::set_surface_height(glm::ivec2(2, 1), 6); deerith::set_voxel(1, glm::vec3(2, 2, 2)); + deerith::set_voxel(1, glm::vec3(3, 4, 1)); } \ No newline at end of file