diff --git a/CMakeLists.txt b/CMakeLists.txt index 7946714..4b0f96e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,12 +85,14 @@ add_executable(${PROJECT_NAME} src/gameplay/biome.cpp src/gameplay/chunk.cpp src/gameplay/player.cpp + src/gameplay/tree.cpp src/gameplay/world.cpp src/input.cpp src/map_table.cpp src/renderer.cpp src/shader.cpp src/texture_manager.cpp + src/tools/cubed_random.cpp src/tools/math_tools.cpp src/tools/shader_tools.cpp src/tools/font.cpp diff --git a/assets/texture/block/leaf/back.png b/assets/texture/block/leaf/back.png new file mode 100644 index 0000000..16d8426 Binary files /dev/null and b/assets/texture/block/leaf/back.png differ diff --git a/assets/texture/block/leaf/base.png b/assets/texture/block/leaf/base.png new file mode 100644 index 0000000..16d8426 Binary files /dev/null and b/assets/texture/block/leaf/base.png differ diff --git a/assets/texture/block/leaf/front.png b/assets/texture/block/leaf/front.png new file mode 100644 index 0000000..16d8426 Binary files /dev/null and b/assets/texture/block/leaf/front.png differ diff --git a/assets/texture/block/leaf/left.png b/assets/texture/block/leaf/left.png new file mode 100644 index 0000000..16d8426 Binary files /dev/null and b/assets/texture/block/leaf/left.png differ diff --git a/assets/texture/block/leaf/right.png b/assets/texture/block/leaf/right.png new file mode 100644 index 0000000..16d8426 Binary files /dev/null and b/assets/texture/block/leaf/right.png differ diff --git a/assets/texture/block/leaf/top.png b/assets/texture/block/leaf/top.png new file mode 100644 index 0000000..16d8426 Binary files /dev/null and b/assets/texture/block/leaf/top.png differ diff --git a/assets/texture/block/log/back.png b/assets/texture/block/log/back.png new file mode 100644 index 0000000..d05532c Binary files /dev/null and b/assets/texture/block/log/back.png differ diff --git a/assets/texture/block/log/base.png b/assets/texture/block/log/base.png new file mode 100644 index 0000000..d05532c Binary files /dev/null and b/assets/texture/block/log/base.png differ diff --git a/assets/texture/block/log/front.png b/assets/texture/block/log/front.png new file mode 100644 index 0000000..d05532c Binary files /dev/null and b/assets/texture/block/log/front.png differ diff --git a/assets/texture/block/log/left.png b/assets/texture/block/log/left.png new file mode 100644 index 0000000..d05532c Binary files /dev/null and b/assets/texture/block/log/left.png differ diff --git a/assets/texture/block/log/right.png b/assets/texture/block/log/right.png new file mode 100644 index 0000000..d05532c Binary files /dev/null and b/assets/texture/block/log/right.png differ diff --git a/assets/texture/block/log/top.png b/assets/texture/block/log/top.png new file mode 100644 index 0000000..d05532c Binary files /dev/null and b/assets/texture/block/log/top.png differ diff --git a/include/Cubed/app.hpp b/include/Cubed/app.hpp index 0dae470..3df83f2 100644 --- a/include/Cubed/app.hpp +++ b/include/Cubed/app.hpp @@ -6,6 +6,7 @@ #include #include #include +namespace Cubed { class App { public: @@ -35,7 +36,6 @@ private: inline static double fps_time_count = 0.0f; inline static int frame_count = 0; inline static int fps = 0; - inline static unsigned int m_seed = 0; void init(); @@ -46,4 +46,6 @@ private: void render(); void run(); void update(); -}; \ No newline at end of file +}; + +} \ No newline at end of file diff --git a/include/Cubed/config.hpp b/include/Cubed/config.hpp index 03dbb5a..2e8e32d 100644 --- a/include/Cubed/config.hpp +++ b/include/Cubed/config.hpp @@ -1,6 +1,6 @@ #pragma once constexpr int WORLD_SIZE_Y = 256; -constexpr int MAX_BLOCK_NUM = 5; +constexpr int MAX_BLOCK_NUM = 7; constexpr int MAX_UI_NUM = 1; constexpr int CHUCK_SIZE = 16; diff --git a/include/Cubed/gameplay/biome.hpp b/include/Cubed/gameplay/biome.hpp index 3492852..54ee2c4 100644 --- a/include/Cubed/gameplay/biome.hpp +++ b/include/Cubed/gameplay/biome.hpp @@ -4,9 +4,9 @@ constexpr float BIOME_NOISE_FREQUENCY = 0.003f; -constexpr float PLAIN_FREQ = 0.5f; -constexpr float FOREST_FREQ = 1.0f; -constexpr float DESERT_FREQ = 1.0f; +constexpr float PLAIN_FREQ = 0.4f; +constexpr float FOREST_FREQ = 1.2f; +constexpr float DESERT_FREQ = 1.2f; constexpr float MOUNTAIN_FREQ = 2.0f; enum class Biome { diff --git a/include/Cubed/gameplay/chunk.hpp b/include/Cubed/gameplay/chunk.hpp index 19944cb..cbe2844 100644 --- a/include/Cubed/gameplay/chunk.hpp +++ b/include/Cubed/gameplay/chunk.hpp @@ -47,7 +47,7 @@ public: const std::vector& get_chunk_blocks() const; static int get_index(int x, int y, int z); - + static int get_index(const glm::vec3& pos); void init_chunk(); void gen_vertex_data(); // 0 : (1, 0) diff --git a/include/Cubed/gameplay/tree.hpp b/include/Cubed/gameplay/tree.hpp new file mode 100644 index 0000000..051e0b5 --- /dev/null +++ b/include/Cubed/gameplay/tree.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include + +class Chunk; + +struct TreeStructNode { + glm::ivec3 offset{0, 0, 0}; + unsigned id = 0; +}; + +bool build_tree(Chunk& chunk, const glm::ivec3& pos); \ No newline at end of file diff --git a/include/Cubed/tools/cubed_random.hpp b/include/Cubed/tools/cubed_random.hpp new file mode 100644 index 0000000..68f3ba3 --- /dev/null +++ b/include/Cubed/tools/cubed_random.hpp @@ -0,0 +1,21 @@ +#pragma once +#include +namespace Cubed { + +class Random { +public: + Random(); + + static Random& get(); + + bool random_bool(double probability); + std::mt19937& engine(); + unsigned seed(); + +private: + unsigned int m_seed = 0; + std::mt19937 m_engine; +}; + + +} diff --git a/include/Cubed/tools/perlin_noise.hpp b/include/Cubed/tools/perlin_noise.hpp index 5faafa2..578d9f3 100644 --- a/include/Cubed/tools/perlin_noise.hpp +++ b/include/Cubed/tools/perlin_noise.hpp @@ -4,7 +4,7 @@ class PerlinNoise { public: - static void init(unsigned int seed); + static void init(); static float noise(float x, float y, float z); private: static inline bool is_init = false; diff --git a/src/app.cpp b/src/app.cpp index 4cf5cd0..1a3c9e9 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -4,11 +4,14 @@ #include #include #include +#include #include #include #include -#include + +namespace Cubed { + App::App() { @@ -36,10 +39,8 @@ void App::init() { glfwSetWindowFocusCallback(m_window.get_glfw_window(), window_focus_callback); glfwSetWindowSizeCallback(m_window.get_glfw_window(), window_reshape_callback); glfwSetKeyCallback(m_window.get_glfw_window(), key_callback); - std::random_device d; - m_seed = d(); - Logger::info("Seed: {}", m_seed); - PerlinNoise::init(m_seed); + + PerlinNoise::init(); m_renderer.init(); Logger::info("Renderer Init Success"); @@ -204,14 +205,12 @@ int App::start_cubed_application(int argc, char** argv) { return 1; } -unsigned int App::seed() { - return m_seed; -} - float App::delte_time() { return delta_time; } float App::get_fps() { return fps; +} + } \ No newline at end of file diff --git a/src/gameplay/chunk.cpp b/src/gameplay/chunk.cpp index 0edfe1f..d21e8c3 100644 --- a/src/gameplay/chunk.cpp +++ b/src/gameplay/chunk.cpp @@ -1,6 +1,8 @@ #include +#include #include #include +#include #include #include #include @@ -59,6 +61,11 @@ int Chunk::get_index(int x, int y, int z) { } return (x * WORLD_SIZE_Y + y) * CHUCK_SIZE + z; } + +int Chunk::get_index(const glm::vec3& pos) { + return Chunk::get_index(pos.x, pos.y, pos.z); +} + // this is thread-unsafe! void Chunk::gen_vertex_data() { m_vertexs_data.clear(); @@ -274,7 +281,7 @@ void Chunk::resolve_blocks() { } } } - + std::array, SIZE_X> heights; for (int x = 0; x < CHUCK_SIZE; x++) { for (int z = 0; z < CHUCK_SIZE; z++) { @@ -284,12 +291,13 @@ void Chunk::resolve_blocks() { float temp = PerlinNoise::noise(world_x * BIOME_NOISE_FREQUENCY, 0.0f, world_z * BIOME_NOISE_FREQUENCY); float humid = PerlinNoise::noise(world_x * BIOME_NOISE_FREQUENCY, 1.0f, world_z * BIOME_NOISE_FREQUENCY); int height = get_interpolated_height(world_x, world_z, temp, humid); + heights[x][z] = height; auto biome = get_biome_from_noise(temp, humid); for (int y = 5; y < height - 5; y++) { m_blocks[get_index(x, y, z)] = 3; } if (biome == Biome::MOUNTAIN) { - for (int y = height - 5; y < height - 1; y++) { + for (int y = height - 5; y <= height - 1; y++) { if (y > 101) { m_blocks[get_index(x, y, z)] = 3; } else { @@ -297,26 +305,43 @@ void Chunk::resolve_blocks() { } } - if (height - 1 > 101) { + if (height > 101) { m_blocks[get_index(x, height - 1, z)] = 3; } else { m_blocks[get_index(x, height - 1, z)] = 1; } } else if (biome == Biome::DESERT) { - for (int y = height - 5; y < height; y++) { + for (int y = height - 5; y <= height; y++) { m_blocks[get_index(x, y, z)] = 4; } } else { - for (int y = height - 5; y < height - 1; y++) { + for (int y = height - 5; y <= height - 1; y++) { m_blocks[get_index(x, y, z)] = 2; } - for (int y = height - 1; y < height; y++) { + for (int y = height; y <= height; y++) { m_blocks[get_index(x, y, z)] = 1; } } } } + if (m_biome == Biome::FOREST) { + std::array x_arr; + std::ranges::iota(x_arr, 0); + std::shuffle(x_arr.begin(), x_arr.end(), Cubed::Random::get().engine()); + std::array z_arr; + std::ranges::iota(z_arr, 0); + std::shuffle(z_arr.begin(), z_arr.end(), Cubed::Random::get().engine()); + for (auto x : x_arr) { + for (auto z : z_arr) { + if (Cubed::Random::get().random_bool(0.8)) { + build_tree(*this, {x, heights[x][z], z}); + } + + } + } + } + mark_dirty(); } diff --git a/src/gameplay/tree.cpp b/src/gameplay/tree.cpp new file mode 100644 index 0000000..23b361b --- /dev/null +++ b/src/gameplay/tree.cpp @@ -0,0 +1,98 @@ +#include + +#include + +#include + +using glm::ivec3; + +static constexpr std::array TREE {{ + {{0, 1, 0}, 5}, + {{0, 2, 0}, 5}, + {{0, 3, 0}, 5}, + {{0, 4, 0}, 5}, + {{0, 5, 0}, 5}, + {{0, 6, 0}, 6}, + {{0, 5, 1}, 6}, + {{1, 5, 0}, 6}, + {{0, 5, -1}, 6}, + {{-1, 5, 0}, 6}, + {{1, 5, 1}, 6}, + {{1, 5, -1}, 6}, + {{-1, 5, -1}, 6}, + {{-1, 5, 1}, 6}, + {{0, 4, 1}, 6}, + {{1, 4, 0}, 6}, + {{0, 4, -1}, 6}, + {{-1, 4, 0}, 6}, + {{1, 4, 1}, 6}, + {{1, 4, -1}, 6}, + {{-1, 4, -1}, 6}, + {{-1, 4, 1}, 6}, + {{0, 4, 2}, 6}, + {{2, 4, 0}, 6}, + {{0, 4, -2}, 6}, + {{-2, 4, 0}, 6}, + {{2, 4, 2}, 6}, + {{2, 4, -2}, 6}, + {{-2, 4, -2}, 6}, + {{-2, 4, 2}, 6}, + {{1, 4, 2}, 6}, + {{2, 4, 1}, 6}, + {{-1, 4, 2}, 6}, + {{2, 4, -1}, 6}, + {{1, 4, -2}, 6}, + {{-2, 4, 1}, 6}, + {{-1, 4, -2}, 6}, + {{-2, 4, -1}, 6}, + {{0, 3, 1}, 6}, + {{1, 3, 0}, 6}, + {{0, 3, -1}, 6}, + {{-1, 3, 0}, 6}, + {{1, 3, 1}, 6}, + {{1, 3, -1}, 6}, + {{-1, 3, -1}, 6}, + {{-1, 3, 1}, 6}, + {{0, 3, 2}, 6}, + {{2, 3, 0}, 6}, + {{0, 3, -2}, 6}, + {{-2, 3, 0}, 6}, + {{2, 3, 2}, 6}, + {{2, 3, -2}, 6}, + {{-2, 3, -2}, 6}, + {{-2, 3, 2}, 6}, + {{1, 3, 2}, 6}, + {{2, 3, 1}, 6}, + {{-1, 3, 2}, 6}, + {{2, 3, -1}, 6}, + {{1, 3, -2}, 6}, + {{-2, 3, 1}, 6}, + {{-1, 3, -2}, 6}, + {{-2, 3, -1}, 6}, +}}; + +bool build_tree(Chunk& chunk, const glm::ivec3& pos) { + auto& block = chunk.get_chunk_blocks(); + + if (block[Chunk::get_index(pos)] != 1) { + Logger::info("Root is not Grass Block"); + return false; + } + for (const auto& d : TREE) { + auto tree_node = pos + d.offset; + int x = tree_node.x; + int y = tree_node.y; + int z = tree_node.z; + if (x < 0 || y < 0 || z < 0 || x >= CHUCK_SIZE || y >= WORLD_SIZE_Y || z >= CHUCK_SIZE) { + return false; + } + if (block[Chunk::get_index(tree_node)] != 0) { + return false; + } + } + for (const auto& d : TREE) { + auto tree_node = pos + d.offset; + chunk.set_chunk_block(Chunk::get_index(tree_node), d.id); + } + return true; +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 4aed757..8d70a54 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,7 @@ #include int main(int argc, char** argv) { - return App::start_cubed_application(argc, argv); + return Cubed::App::start_cubed_application(argc, argv); } diff --git a/src/map_table.cpp b/src/map_table.cpp index 52ffdfd..3448b59 100644 --- a/src/map_table.cpp +++ b/src/map_table.cpp @@ -13,7 +13,9 @@ constexpr std::array BLOCK_REISTER{ "grass_block", "dirt", "stone", - "sand" + "sand", + "log", + "leaf" }; diff --git a/src/tools/cubed_random.cpp b/src/tools/cubed_random.cpp new file mode 100644 index 0000000..7a346e1 --- /dev/null +++ b/src/tools/cubed_random.cpp @@ -0,0 +1,34 @@ +#include + +#include + +namespace Cubed { + +Random::Random() { + std::random_device d; + m_seed = d(); + Logger::info("Seed: {}", m_seed); + m_engine.seed(m_seed); +} + +Random& Random::get() { + static Random instance; + return instance; +} + +bool Random::random_bool(double probability) { + std::bernoulli_distribution dist(probability); + return dist(m_engine); +} + +std::mt19937& Random::engine() { + return m_engine; +} + +unsigned Random::seed() { + return m_seed; +} + + + +} \ No newline at end of file diff --git a/src/tools/perlin_noise.cpp b/src/tools/perlin_noise.cpp index a73d273..66ac858 100644 --- a/src/tools/perlin_noise.cpp +++ b/src/tools/perlin_noise.cpp @@ -2,17 +2,16 @@ #include #include - +#include #include #include -#include -void PerlinNoise::init(unsigned int seed) { + +void PerlinNoise::init() { p.resize(256); std::iota(p.begin(), p.end(), 0); - std::mt19937 engine(seed); - std::shuffle(p.begin(), p.end(), engine); + std::shuffle(p.begin(), p.end(), Cubed::Random::get().engine()); p.insert(p.end(), p.begin(), p.end()); is_init = true;