simple box render

This commit is contained in:
Chewico 2026-11-03 18:56:57 +01:00
parent 59e939a1ea
commit 535bc27c56
24 changed files with 725 additions and 74 deletions

View File

@ -4,4 +4,132 @@
namespace deerith
{
glm::vec2 get_joystick_axes(int controller_id, int axe_id);
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

View File

@ -1,5 +1,6 @@
#pragma once
#include <glm/glm.hpp>
#include <vector>
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<vertex_3d_t> vertices;
std::vector<unsigned int> 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;
};
}

View File

@ -0,0 +1,73 @@
#pragma once
#include <glm/glm.hpp>
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,
};
}

View File

@ -1,5 +1,6 @@
#pragma once
#include <deerith/world/world_core.h>
#include <glm/glm.hpp>
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();
}

View File

@ -1,13 +0,0 @@
#pragma once
#include <deerith/engine.h>
#include <deerith/client/graphics/mesh.h>
namespace deerith
{
struct chunk_render_t
{
std::unique_ptr<mesh_2d_t> chunk_mesh;
void draw();
};
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -1,5 +1,5 @@
#include <deerith/engine.h>
#include <deerith/client/network/network_internals.h>
#include <deerith/client/internals/network.h>
void deerith::init_engine()
{

View File

@ -29,3 +29,69 @@ 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, &current_x, &current_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<float>(current_x - last_x),
static_cast<float>(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);
}

View File

@ -1,5 +1,7 @@
#include <deerith/client/graphics/mesh.h>
#include <deerith/engine.h>
#include <glad/gl.h>
#include <cstddef>
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);

View File

@ -1,6 +1,6 @@
#include <deerith/client/graphics/window.h>
#include <deerith/client/graphics/primitive_internals.h>
#include <deerith/client/network/network_internals.h>
#include <deerith/client/internals/network.h>
#include <deerith/client/world.h>
#include <glad/gl.h>
@ -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()

View File

@ -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))

View File

@ -6,7 +6,7 @@
#include <thread>
#include <memory>
#include <deerith/client/network/network_internals.h>
#include <deerith/client/internals/network.h>
namespace deerith
{

View File

@ -0,0 +1,134 @@
#include <deerith/client/world.h>
#include <deerith/world/environment.h>
#include <deerith/client/internals/cluster_generation.h>
#include <vector>
#include <memory>
#include <deerith/client/graphics/mesh.h>
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<mesh_3d_t> test_mesh;
std::unique_ptr<mesh_3d_data_t> build_data;
}
void deerith::load_clusters_to_gpu()
{
if (build_data)
{
test_mesh = std::make_unique<mesh_3d_t>(*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<mesh_3d_data_t>();
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);
}

View File

@ -5,11 +5,100 @@
#include <deerith/network/packets.h>
#include <deerith/world/components.h>
#include <deerith/client/world/world_internals.h>
#include <deerith/client/internals/world.h>
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<component_client_sync_character_t>(self_entity);
component_client_sync_character_t &entity_sync_position = get_component<component_client_sync_character_t>(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()

View File

@ -7,8 +7,8 @@
#include <deerith/client/world.h>
#include <deerith/client/world/world_internals.h>
#include <deerith/client/network/network_internals.h>
#include <deerith/client/internals/world.h>
#include <deerith/client/internals/network.h>
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);
}

View File

@ -1,8 +1,8 @@
#include <deerith/engine.h>
#include <deerith/client/world.h>
#include <deerith/client/network/network_internals.h>
#include <deerith/client/world/world_internals.h>
#include <deerith/client/internals/network.h>
#include <deerith/client/internals/world.h>
#include <thread>
#include <memory>
@ -46,8 +46,6 @@ void deerith::world_simulation()
{
flush_network_events();
process_player_input();
if (get_world_tick() % 2 == 0)
{
send_player_input();

View File

@ -5,20 +5,44 @@
#include <deerith/client/graphics/mesh.h>
#include <deerith/client/graphics/shader.h>
#include <deerith/client/graphics/primitive.h>
#include <deerith/client/internals/world.h>
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
namespace deerith
{
extern std::unique_ptr<mesh_3d_t> 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);
auto self_view = get_entity_registry().view<component_sync_coordinates_t, component_client_sync_character_t>();
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::quat>(), 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<component_sync_coordinates_t, component_client_sync_character_t>();
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::quat>();
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();
}
}

View File

@ -20,6 +20,7 @@ namespace deerith
{
sync_variable_t<glm::vec3> move_input;
sync_variable_t<glm::vec3> position;
glm::vec2 player_look;
};
struct component_sync_coordinates_t

View File

@ -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<std::array<surface_height_t, CLUSTER_SIZE>, CLUSTER_SIZE>;
using cluster_voxel_type_id_data_t = std::array<std::array<std::array<voxel_type_id_t, CLUSTER_SIZE>, 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);
}

View File

@ -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>();
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<voxel_cluster_t>();
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<voxel_cluster_t>();
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<voxel_cluster_t>();
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;
}

View File

@ -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));
}