diff --git a/assets/shaders/block_f_shader.glsl b/assets/shaders/block_f_shader.glsl index 89921be..d13036c 100644 --- a/assets/shaders/block_f_shader.glsl +++ b/assets/shaders/block_f_shader.glsl @@ -19,7 +19,7 @@ void main(void) { discard; } - vec3 lightDir = normalize(sunlightDir); + vec3 lightDir = normalize(-sunlightDir); vec3 ambient = ambientStrength * sunlightColor; diff --git a/assets/shaders/sky_f_shader.glsl b/assets/shaders/sky_f_shader.glsl index e52005f..859a6dd 100644 --- a/assets/shaders/sky_f_shader.glsl +++ b/assets/shaders/sky_f_shader.glsl @@ -2,8 +2,10 @@ out vec4 frag_color; +uniform vec3 color; + void main(void) { - frag_color = vec4(0.529, 0.808, 0.922, 1.0); + frag_color = vec4(color, 1.0); } \ No newline at end of file diff --git a/include/Cubed/dev_panel.hpp b/include/Cubed/dev_panel.hpp index 4756805..6560cb5 100644 --- a/include/Cubed/dev_panel.hpp +++ b/include/Cubed/dev_panel.hpp @@ -44,8 +44,11 @@ private: bool m_need_save_config = false; bool m_gen_thread_running = true; int m_theme = 0; + int m_pre_set_day_tick = 0; + int m_pre_set_tick_speed = 0; void show_about_table_bar(); void show_biome_table_bar(); + void show_time_table_bar(); void show_cave_table_bar(); void show_river_table_bar(); void show_settings_tab_item(); diff --git a/include/Cubed/gameplay/game_time.hpp b/include/Cubed/gameplay/game_time.hpp new file mode 100644 index 0000000..875b1e5 --- /dev/null +++ b/include/Cubed/gameplay/game_time.hpp @@ -0,0 +1,9 @@ +#pragma once + +using TickType = long long; + +constexpr int DEFAULT_PER_TICK_TIME = 50; + +constexpr TickType DAY_TIME = 24000; + +constexpr TickType PER_HOUR = 1000; \ No newline at end of file diff --git a/include/Cubed/gameplay/world.hpp b/include/Cubed/gameplay/world.hpp index dbad426..046623b 100644 --- a/include/Cubed/gameplay/world.hpp +++ b/include/Cubed/gameplay/world.hpp @@ -2,6 +2,7 @@ #include "Cubed/AABB.hpp" #include "Cubed/gameplay/cave_carver.hpp" #include "Cubed/gameplay/chunk.hpp" +#include "Cubed/gameplay/game_time.hpp" #include "Cubed/gameplay/river_worm.hpp" #include @@ -39,13 +40,21 @@ private: std::unordered_map; using ChunkPosSet = std::unordered_set; using ChunkHashMap = std::unordered_map; + glm::vec3 m_gen_player_pos{0.0f, 0.0f, 0.0f}; - glm::vec3 m_sunlight_dir{1.0f, 2.0f, 1.0f}; ChunkHashMap m_chunks; std::unordered_map m_players; std::vector m_planes; std::thread m_gen_thread; + std::thread m_server_thread; + + std::stop_source m_server_stop_source; + + std::atomic m_per_tick_time = DEFAULT_PER_TICK_TIME; // ms + + std::atomic m_day_tick = 6000; + mutable std::mutex m_chunks_mutex; std::mutex m_gen_signal_mutex; std::mutex m_new_chunk_queue_mutex; @@ -62,6 +71,9 @@ private: std::atomic m_could_gen{true}; std::atomic m_rendering_distance{24}; std::atomic m_chunk_gen_fraction{0.0f}; + + std::atomic m_game_ticks{0}; + std::vector m_dirty_queue; std::vector m_render_snapshots; std::vector> m_new_chunk; @@ -120,7 +132,10 @@ public: int rendering_distance() const; void rendering_distance(int rendering_distance); void start_gen_thread(); + void start_server_thread(); void stop_gen_thread(); + void stop_server_thread(); + void serever_run(std::stop_token stoken); CaveCarver& cave_carcer(); RiverWorm& river_worm(); @@ -128,6 +143,11 @@ public: std::vector& render_snapshots(); glm::vec3 sunlight_dir() const; + TickType game_tick() const; + TickType day_tick() const; + void day_tick(TickType tick); + int per_tick_time() const; + void per_tick_time(int ms); }; } // namespace Cubed diff --git a/include/Cubed/renderer.hpp b/include/Cubed/renderer.hpp index 5bee9a6..e08eee4 100644 --- a/include/Cubed/renderer.hpp +++ b/include/Cubed/renderer.hpp @@ -31,6 +31,13 @@ public: private: static constexpr glm::vec3 SUNLIGHT_COLOR{1.0f, 1.0f, 1.0f}; + static constexpr glm::vec3 SUN_COLOR{1.00f, 0.95f, 0.80f}; + static constexpr glm::vec3 MOON_COLOR{0.75f, 0.80f, 1.00f}; + static constexpr glm::vec3 SKY_COLOR{0.529, 0.808, 0.922}; + static constexpr float FAR_PLANE = 1000.0f; + static constexpr float NEAR_PLANE = 0.1f; + static constexpr float SUN_SIZE = 50.0f; + static constexpr float MOON_SIZE = 50.0f; const Camera& m_camera; DevPanel& m_dev_panel; const TextureManager& m_texture_manager; @@ -75,6 +82,7 @@ private: 2 - outline vao 3 - ui vao 4 - text vao + */ std::vector m_vao; std::vector m_ui; diff --git a/src/dev_panel.cpp b/src/dev_panel.cpp index d2902e2..c6956af 100644 --- a/src/dev_panel.cpp +++ b/src/dev_panel.cpp @@ -263,6 +263,29 @@ void DevPanel::show_biome_table_bar() { } } +void DevPanel::show_time_table_bar() { + World& world = m_app.world(); + ImGui::Text("Game Tick %lld", world.game_tick()); + ImGui::Text("Day Tick %lld", world.day_tick()); + ImGui::Text("Set Day Tick"); + ImGui::SameLine(); + if (ImGui::SliderInt("DayTick", &m_pre_set_day_tick, 0, DAY_TIME)) { + } + ImGui::SameLine(); + if (ImGui::Button("Save##DayTick")) { + world.day_tick(static_cast(m_pre_set_day_tick)); + } + ImGui::Text("MSPT %d", world.per_tick_time()); + ImGui::Text("Set MSPT"); + ImGui::SameLine(); + if (ImGui::SliderInt("SetMSPT", &m_pre_set_tick_speed, 0, 200)) { + } + ImGui::SameLine(); + if (ImGui::Button("Save##MSPT")) { + world.per_tick_time(m_pre_set_tick_speed); + } +} + void DevPanel::show_cave_table_bar() { auto& cave_carcer = m_app.world().cave_carcer(); @@ -457,6 +480,10 @@ void DevPanel::show_world_tab_item() { ImGui::Text("Chunk Build Progress\n"); ImGui::ProgressBar(m_app.world().chunk_gen_fraction()); if (ImGui::BeginTabBar("World Settings")) { + if (ImGui::BeginTabItem("Time")) { + show_time_table_bar(); + ImGui::EndTabItem(); + } if (ImGui::BeginTabItem("Cave")) { show_cave_table_bar(); ImGui::EndTabItem(); diff --git a/src/gameplay/world.cpp b/src/gameplay/world.cpp index d074e65..ca57225 100644 --- a/src/gameplay/world.cpp +++ b/src/gameplay/world.cpp @@ -7,6 +7,8 @@ #include +using namespace std::chrono; + namespace Cubed { struct ChunkRenderData { @@ -18,6 +20,7 @@ World::World() {} World::~World() { stop_gen_thread(); + stop_server_thread(); m_chunks.clear(); { std::lock_guard lk(m_delete_vbo_mutex); @@ -86,6 +89,8 @@ void World::init_world() { auto d = std::chrono::duration_cast(t2 - t1); Logger::info("Chunk Block Init Finish, Time Consuming: {}", d); + start_server_thread(); + Logger::info("TestPlayer Create Finish"); } void World::init_chunks() { @@ -727,6 +732,11 @@ void World::start_gen_thread() { }); } +void World::start_server_thread() { + m_server_thread = std::thread( + [this]() { serever_run(m_server_stop_source.get_token()); }); +} + void World::stop_gen_thread() { m_gen_running = false; m_gen_cv.notify_all(); @@ -736,6 +746,23 @@ void World::stop_gen_thread() { Logger::info("Gen Thread Stopped"); } +void World::stop_server_thread() { + m_server_stop_source.request_stop(); + if (m_server_thread.joinable()) { + m_server_thread.join(); + } +} + +void World::serever_run(std::stop_token stoken) { + Logger::info("Server Thread Started!"); + while (!stoken.stop_requested()) { + std::this_thread::sleep_for(milliseconds(m_per_tick_time)); + ++m_game_ticks; + m_day_tick = (++m_day_tick) % DAY_TIME; + } + Logger::info("Server Thread Stopped!"); +} + void World::need_gen() { if (!m_could_gen) { Logger::warn("It is generating or consuming new chunks"); @@ -1006,6 +1033,47 @@ std::vector& World::planes() { return m_planes; } std::vector& World::render_snapshots() { return m_render_snapshots; }; -glm::vec3 World::sunlight_dir() const { return m_sunlight_dir; } +/* +glm::vec3 World::sunlight_dir() const { + float t = static_cast(m_day_tick) / DAY_TIME; + + float azimuth = glm::radians(90.0f - t * 360.0f); + + float altitude = + glm::half_pi() * sin((t - 0.25f) * glm::two_pi()); + + glm::vec3 dir{cos(altitude) * cos(azimuth), sin(altitude), + cos(altitude) * sin(azimuth)}; + + return glm::normalize(dir); +} +*/ + +glm::vec3 World::sunlight_dir() const { + float altitude = sin((m_day_tick - 6 * PER_HOUR) / + static_cast(DAY_TIME / 2) * std::numbers::pi) * + 90.0f; + + float t = static_cast(m_day_tick) / DAY_TIME; + float azimuth = 90.0f - 360.0f * (t - 0.25f); + + float alt = glm::radians(altitude); + float az = glm::radians(azimuth); + glm::vec3 dir; + dir.x = cos(alt) * sin(az); + dir.y = sin(alt); + dir.z = cos(alt) * cos(az); + + return glm::normalize(-dir); +} + +TickType World::game_tick() const { return m_game_ticks.load(); } +TickType World::day_tick() const { return m_day_tick.load(); } +void World::day_tick(TickType tick) { + tick %= DAY_TIME; + m_day_tick = tick; +} +int World::per_tick_time() const { return m_per_tick_time.load(); } +void World::per_tick_time(int ms) { m_per_tick_time = ms; } } // namespace Cubed \ No newline at end of file diff --git a/src/renderer.cpp b/src/renderer.cpp index ea75290..4418c81 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -257,13 +257,44 @@ void Renderer::render_sky() { glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat)); glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_p_mat)); - + glUniform3fv(shader.loc("color"), 1, glm::value_ptr(SKY_COLOR)); glBindVertexArray(m_vao[1]); glDisable(GL_DEPTH_TEST); glDrawArrays(GL_TRIANGLES, 0, 36); glEnable(GL_DEPTH_TEST); + + // draw sun and moon + glDepthMask(GL_FALSE); + + glBindVertexArray(m_vao[0]); + // draw sum + glm::vec3 sun_pos = m_camera.get_camera_pos() + + normalize(-m_world.sunlight_dir()) * (FAR_PLANE * 0.9f); + glm::vec3 sun_view_pos = glm::vec3(m_v_mat * glm::vec4(sun_pos, 1.0f)); + m_mv_mat = glm::translate(glm::mat4(1.0f), sun_view_pos) * + glm::scale(glm::mat4(1.0f), glm::vec3(SUN_SIZE)) * + glm::translate(glm::mat4(1.0f), glm::vec3(-0.5f, -0.5f, 0.0f)); + glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat)); + glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_p_mat)); + glUniform3fv(shader.loc("color"), 1, glm::value_ptr(SUN_COLOR)); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + glm::vec3 moon_pos = m_camera.get_camera_pos() + + normalize(m_world.sunlight_dir()) * (FAR_PLANE * 0.9f); + glm::vec3 moon_view_pos = glm::vec3(m_v_mat * glm::vec4(moon_pos, 1.0f)); + m_mv_mat = glm::translate(glm::mat4(1.0f), moon_view_pos) * + glm::scale(glm::mat4(1.0f), glm::vec3(MOON_SIZE)) * + glm::translate(glm::mat4(1.0f), glm::vec3(-0.5f, -0.5f, 0.0f)); + glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat)); + glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_p_mat)); + glUniform3fv(shader.loc("color"), 1, glm::value_ptr(MOON_COLOR)); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + glDepthMask(GL_TRUE); } void Renderer::render_text() { @@ -343,7 +374,8 @@ void Renderer::update_fov(float fov) { void Renderer::update_proj_matrix(float aspect, float width, float height) { m_aspect = aspect; - m_p_mat = glm::perspective(glm::radians(m_fov), aspect, 0.1f, 1000.0f); + m_p_mat = + glm::perspective(glm::radians(m_fov), aspect, NEAR_PLANE, FAR_PLANE); m_ui_proj = glm::ortho(0.0f, width, height, 0.0f, -1.0f, 1.0f); // scale and then translate m_ui_m_matrix =