mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-06-21 18:17:03 +08:00
Compare commits
13 Commits
main
...
refactor/c
| Author | SHA1 | Date | |
|---|---|---|---|
| 943013b83d | |||
| 47f13ca995 | |||
| 4f6c5303ec | |||
| 34d9439466 | |||
| 2386d98217 | |||
| 790f4a5aa4 | |||
| 9a7fe1bfe9 | |||
| 8929af888a | |||
| a72b0dd677 | |||
| 4b617612e8 | |||
| 5cfd663566 | |||
| d69e1895d4 | |||
| be17846c16 |
@@ -25,6 +25,10 @@ uniform float minRadius;
|
|||||||
uniform float maxRadius;
|
uniform float maxRadius;
|
||||||
uniform bool enablePBR;
|
uniform bool enablePBR;
|
||||||
uniform bool flipY;
|
uniform bool flipY;
|
||||||
|
|
||||||
|
uniform int renderDistance;
|
||||||
|
uniform vec3 skyColor;
|
||||||
|
|
||||||
const vec2 poissonDisk32[32] = vec2[](
|
const vec2 poissonDisk32[32] = vec2[](
|
||||||
vec2(-0.975402, -0.071138),
|
vec2(-0.975402, -0.071138),
|
||||||
vec2(-0.920347, -0.411420),
|
vec2(-0.920347, -0.411420),
|
||||||
@@ -341,8 +345,17 @@ void main(void) {
|
|||||||
vec3 specular = spec * sunlightColor * specularStrength;
|
vec3 specular = spec * sunlightColor * specularStrength;
|
||||||
|
|
||||||
float shadow = ShadowCalculation(FragPosLightSpace, norm, lightDir);
|
float shadow = ShadowCalculation(FragPosLightSpace, norm, lightDir);
|
||||||
|
|
||||||
|
// fog
|
||||||
|
float dist = length(cameraPos - vert_pos);
|
||||||
|
vec4 fogColor = vec4(skyColor, 1.0);
|
||||||
|
float fogStart = renderDistance * 16 * 0.9;
|
||||||
|
float fogEnd = renderDistance * 16;
|
||||||
|
|
||||||
|
float fogFactor = smoothstep(fogEnd, fogStart, dist);
|
||||||
color = vec4((ambient + (1.0 - shadow) * (diffuse)) * objectColor.rgb + (1.0-shadow) * specular * objectColor.rgb, objectColor.a);
|
color = vec4((ambient + (1.0 - shadow) * (diffuse)) * objectColor.rgb + (1.0-shadow) * specular * objectColor.rgb, objectColor.a);
|
||||||
|
|
||||||
|
color = mix(fogColor, color, fogFactor);
|
||||||
//color = vec4(normal * 0.5 + 0.5, 1.0);
|
//color = vec4(normal * 0.5 + 0.5, 1.0);
|
||||||
//color = vec4(tangent * 0.5 + 0.5, 1.0);;
|
//color = vec4(tangent * 0.5 + 0.5, 1.0);;
|
||||||
//color = vec4(norm * 0.5 + 0.5, 1.0);
|
//color = vec4(norm * 0.5 + 0.5, 1.0);
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ uniform float ambientStrength;
|
|||||||
uniform vec3 sunlightColor;
|
uniform vec3 sunlightColor;
|
||||||
uniform vec3 ambientColor;
|
uniform vec3 ambientColor;
|
||||||
uniform vec3 sunlightDir;
|
uniform vec3 sunlightDir;
|
||||||
uniform vec3 cameraPos;
|
|
||||||
uniform bool shader_on;
|
uniform bool shader_on;
|
||||||
uniform float specularStrength;
|
uniform float specularStrength;
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ constexpr float DEFAULT_G = 22.5f;
|
|||||||
constexpr int SIZE_X = CHUNK_SIZE;
|
constexpr int SIZE_X = CHUNK_SIZE;
|
||||||
constexpr int SIZE_Y = WORLD_SIZE_Y;
|
constexpr int SIZE_Y = WORLD_SIZE_Y;
|
||||||
constexpr int SIZE_Z = CHUNK_SIZE;
|
constexpr int SIZE_Z = CHUNK_SIZE;
|
||||||
|
constexpr int RESERVED_THREADS = 3;
|
||||||
constexpr ChunkPos CHUNK_DIR[]{{1, 0}, {-1, 0}, {0, 1}, {0, -1},
|
constexpr ChunkPos CHUNK_DIR[]{{1, 0}, {-1, 0}, {0, 1}, {0, -1},
|
||||||
{1, 1}, {-1, 1}, {1, -1}, {-1, -1}};
|
{1, 1}, {-1, 1}, {1, -1}, {-1, -1}};
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ private:
|
|||||||
int m_pre_set_tick_speed = 1;
|
int m_pre_set_tick_speed = 1;
|
||||||
bool m_tick_frezze = false;
|
bool m_tick_frezze = false;
|
||||||
int m_samples_idx = 1;
|
int m_samples_idx = 1;
|
||||||
|
int m_threads = 1;
|
||||||
|
int m_chunk_style = 0;
|
||||||
void show_about_table_bar();
|
void show_about_table_bar();
|
||||||
void show_biome_table_bar();
|
void show_biome_table_bar();
|
||||||
void show_time_table_bar();
|
void show_time_table_bar();
|
||||||
|
|||||||
@@ -17,11 +17,13 @@ public:
|
|||||||
|
|
||||||
int cave_sum() const;
|
int cave_sum() const;
|
||||||
float& cave_probability();
|
float& cave_probability();
|
||||||
|
std::shared_mutex& path_mutex();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CaveHashMap m_paths;
|
CaveHashMap m_paths;
|
||||||
unsigned m_seed = 0;
|
unsigned m_seed = 0;
|
||||||
Random m_random;
|
Random m_random;
|
||||||
float m_cave_probability = 0.035f;
|
float m_cave_probability = 0.035f;
|
||||||
|
std::shared_mutex m_path_mutex;
|
||||||
};
|
};
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ private:
|
|||||||
std::atomic<bool> m_dirty{false};
|
std::atomic<bool> m_dirty{false};
|
||||||
std::atomic<bool> m_need_upload{true};
|
std::atomic<bool> m_need_upload{true};
|
||||||
std::atomic<bool> m_is_on_gen_vertex_data{false};
|
std::atomic<bool> m_is_on_gen_vertex_data{false};
|
||||||
|
std::atomic<bool> m_gening{false};
|
||||||
|
std::atomic<bool> m_temp_chunk{false};
|
||||||
|
|
||||||
std::atomic<BiomeType> m_biome = BiomeType::PLAIN;
|
std::atomic<BiomeType> m_biome = BiomeType::PLAIN;
|
||||||
std::mutex m_vertexs_data_mutex;
|
std::mutex m_vertexs_data_mutex;
|
||||||
|
|
||||||
@@ -54,7 +57,7 @@ private:
|
|||||||
BlockType id);
|
BlockType id);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Chunk(World& world, ChunkPos chunk_pos);
|
Chunk(World& world, ChunkPos chunk_pos, bool temp_chunk = false);
|
||||||
~Chunk();
|
~Chunk();
|
||||||
Chunk(const Chunk&) = delete;
|
Chunk(const Chunk&) = delete;
|
||||||
Chunk& operator=(const Chunk&) = delete;
|
Chunk& operator=(const Chunk&) = delete;
|
||||||
@@ -124,7 +127,9 @@ public:
|
|||||||
void need_upload();
|
void need_upload();
|
||||||
|
|
||||||
void set_chunk_block(int index, unsigned id);
|
void set_chunk_block(int index, unsigned id);
|
||||||
|
// ensure thread safe!
|
||||||
|
void gen_chunk();
|
||||||
|
bool is_temp_chunk() const;
|
||||||
ChunkPos chunk_pos() const;
|
ChunkPos chunk_pos() const;
|
||||||
BiomeType biome() const;
|
BiomeType biome() const;
|
||||||
void biome(BiomeType b);
|
void biome(BiomeType b);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ private:
|
|||||||
|
|
||||||
float m_max_speed = m_max_walk_speed;
|
float m_max_speed = m_max_walk_speed;
|
||||||
float m_y_speed = 0.0f;
|
float m_y_speed = 0.0f;
|
||||||
|
float m_fly_y_speed = 7.5f;
|
||||||
bool can_up = true;
|
bool can_up = true;
|
||||||
|
|
||||||
float space_on_time = 0.0f;
|
float space_on_time = 0.0f;
|
||||||
@@ -99,6 +100,7 @@ public:
|
|||||||
float& acceleration();
|
float& acceleration();
|
||||||
float& deceleration();
|
float& deceleration();
|
||||||
float& g();
|
float& g();
|
||||||
|
float& fly_y_speed();
|
||||||
|
|
||||||
unsigned place_block() const;
|
unsigned place_block() const;
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class RiverWorm {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
RiverWorm();
|
RiverWorm();
|
||||||
|
~RiverWorm();
|
||||||
RiverHashMap& paths();
|
RiverHashMap& paths();
|
||||||
void init(unsigned world_seed);
|
void init(unsigned world_seed);
|
||||||
void reload(unsigned world_seed);
|
void reload(unsigned world_seed);
|
||||||
@@ -21,12 +22,14 @@ public:
|
|||||||
|
|
||||||
int river_sum() const;
|
int river_sum() const;
|
||||||
float& river_probability();
|
float& river_probability();
|
||||||
|
std::shared_mutex& paths_mutex();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RiverHashMap m_paths;
|
RiverHashMap m_paths;
|
||||||
unsigned m_seed = 0;
|
unsigned m_seed = 0;
|
||||||
Random m_random;
|
Random m_random;
|
||||||
float m_probability = 0.01f;
|
float m_probability = 0.01f;
|
||||||
|
std::shared_mutex m_paths_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace Cubed
|
}; // namespace Cubed
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "Cubed/gameplay/chunk.hpp"
|
#include "Cubed/gameplay/chunk.hpp"
|
||||||
#include "Cubed/gameplay/game_time.hpp"
|
#include "Cubed/gameplay/game_time.hpp"
|
||||||
#include "Cubed/gameplay/river_worm.hpp"
|
#include "Cubed/gameplay/river_worm.hpp"
|
||||||
|
#include "Cubed/tools/thread_pool.hpp"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@@ -34,15 +35,24 @@ class Player;
|
|||||||
class TextureManager;
|
class TextureManager;
|
||||||
class World {
|
class World {
|
||||||
private:
|
private:
|
||||||
|
enum class ChunkLoadStyle { RANDOM, CENTER };
|
||||||
|
|
||||||
|
struct PendingChunk {
|
||||||
|
Chunk chunk;
|
||||||
|
std::future<void> future;
|
||||||
|
};
|
||||||
|
|
||||||
using OptionalBlockVectorArray =
|
using OptionalBlockVectorArray =
|
||||||
std::array<std::optional<std::vector<BlockType>>, 4>;
|
std::array<std::optional<std::vector<BlockType>>, 4>;
|
||||||
using ChunkPtrUpdateList = std::vector<std::pair<ChunkPos, Chunk*>>;
|
using ChunkPtrUpdateList = std::vector<std::pair<ChunkPos, Chunk*>>;
|
||||||
using ChunkPairVector = std::vector<std::pair<ChunkPos, Chunk>>;
|
using ChunkPairVector = std::vector<std::pair<ChunkPos, Chunk>>;
|
||||||
|
using ChunkPairQueue = std::queue<std::pair<ChunkPos, Chunk>>;
|
||||||
using ConstChunkMap =
|
using ConstChunkMap =
|
||||||
std::unordered_map<ChunkPos, const Chunk*, ChunkPos::Hash>;
|
std::unordered_map<ChunkPos, const Chunk*, ChunkPos::Hash>;
|
||||||
using ChunkPosSet = std::unordered_set<ChunkPos, ChunkPos::Hash>;
|
using ChunkPosSet = std::unordered_set<ChunkPos, ChunkPos::Hash>;
|
||||||
using ChunkHashMap = std::unordered_map<ChunkPos, Chunk, ChunkPos::Hash>;
|
using ChunkHashMap = std::unordered_map<ChunkPos, Chunk, ChunkPos::Hash>;
|
||||||
|
using PendingChunkHashMap =
|
||||||
|
std::unordered_map<ChunkPos, PendingChunk, ChunkPos::Hash>;
|
||||||
glm::vec3 m_gen_player_pos{0.0f, 0.0f, 0.0f};
|
glm::vec3 m_gen_player_pos{0.0f, 0.0f, 0.0f};
|
||||||
ChunkHashMap m_chunks;
|
ChunkHashMap m_chunks;
|
||||||
std::unordered_map<std::size_t, Player> m_players;
|
std::unordered_map<std::size_t, Player> m_players;
|
||||||
@@ -50,7 +60,7 @@ private:
|
|||||||
|
|
||||||
std::thread m_gen_thread;
|
std::thread m_gen_thread;
|
||||||
std::thread m_server_thread;
|
std::thread m_server_thread;
|
||||||
|
std::atomic<std::shared_ptr<ThreadPool>> m_gen_thread_pool;
|
||||||
std::stop_source m_server_stop_source;
|
std::stop_source m_server_stop_source;
|
||||||
|
|
||||||
std::atomic<int> m_per_tick_time = DEFAULT_PER_TICK_TIME; // ms
|
std::atomic<int> m_per_tick_time = DEFAULT_PER_TICK_TIME; // ms
|
||||||
@@ -59,7 +69,7 @@ private:
|
|||||||
|
|
||||||
mutable std::mutex m_chunks_mutex;
|
mutable std::mutex m_chunks_mutex;
|
||||||
std::mutex m_gen_signal_mutex;
|
std::mutex m_gen_signal_mutex;
|
||||||
std::mutex m_new_chunk_queue_mutex;
|
std::mutex m_new_chunk_mutex;
|
||||||
std::mutex m_delete_vbo_mutex;
|
std::mutex m_delete_vbo_mutex;
|
||||||
std::mutex m_delete_vao_mutex;
|
std::mutex m_delete_vao_mutex;
|
||||||
std::mutex m_gen_player_pos_mutex;
|
std::mutex m_gen_player_pos_mutex;
|
||||||
@@ -74,13 +84,15 @@ private:
|
|||||||
std::atomic<bool> m_tick_running{true};
|
std::atomic<bool> m_tick_running{true};
|
||||||
std::atomic<int> m_rendering_distance{24};
|
std::atomic<int> m_rendering_distance{24};
|
||||||
std::atomic<float> m_chunk_gen_fraction{0.0f};
|
std::atomic<float> m_chunk_gen_fraction{0.0f};
|
||||||
|
std::atomic<int> m_pool_threads{1};
|
||||||
|
std::atomic<int> m_max_threads{1};
|
||||||
std::atomic<TickType> m_game_ticks{0};
|
std::atomic<TickType> m_game_ticks{0};
|
||||||
|
std::atomic<ChunkLoadStyle> m_chunk_load_style{ChunkLoadStyle::RANDOM};
|
||||||
std::vector<ChunkPos> m_dirty_queue;
|
std::vector<ChunkPos> m_dirty_queue;
|
||||||
std::vector<ChunkRenderSnapshot> m_render_snapshots;
|
std::vector<ChunkRenderSnapshot> m_render_snapshots;
|
||||||
std::vector<std::pair<ChunkPos, Chunk>> m_new_chunk;
|
std::vector<std::pair<ChunkPos, Chunk>> m_new_finished_chunk;
|
||||||
std::vector<std::pair<ChunkPos, Chunk>> m_new_chunk_queue;
|
// Can only be used in the gen thread
|
||||||
|
PendingChunkHashMap new_chunks;
|
||||||
|
|
||||||
CaveCarver m_cave_carcer;
|
CaveCarver m_cave_carcer;
|
||||||
RiverWorm m_river_worm;
|
RiverWorm m_river_worm;
|
||||||
@@ -88,18 +100,14 @@ private:
|
|||||||
|
|
||||||
void gen_chunks_internal();
|
void gen_chunks_internal();
|
||||||
void sync_player_pos(glm::vec3& player_pos);
|
void sync_player_pos(glm::vec3& player_pos);
|
||||||
void
|
void compute_required_chunks(ChunkPosSet& required_chunks,
|
||||||
compute_required_chunks(ChunkPosSet& required_chunks,
|
ChunkPairVector& temp_neighbor);
|
||||||
ChunkPairVector& temp_neighbor,
|
|
||||||
std::vector<ChunkPos>& need_gen_temp_chunks_pos);
|
|
||||||
void sync_and_collect_missing_chunks(std::vector<ChunkPos>&,
|
void sync_and_collect_missing_chunks(std::vector<ChunkPos>&,
|
||||||
const ChunkPosSet&);
|
const ChunkPosSet&);
|
||||||
void
|
|
||||||
build_neighbor_context_for_new_chunks(ConstChunkMap& new_chunks_neighbor,
|
void submit_new_chunks();
|
||||||
ChunkPtrUpdateList& affected_neighbor,
|
void poll_finished_chunks();
|
||||||
const ChunkPairVector& new_chunks);
|
void wait_all_chunk_tasks();
|
||||||
void build_neighbor_context_for_affected_neighbors(ChunkPtrUpdateList&,
|
|
||||||
ConstChunkMap&);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
World();
|
World();
|
||||||
@@ -118,7 +126,7 @@ public:
|
|||||||
bool is_solid(const glm::ivec3& block_pos) const;
|
bool is_solid(const glm::ivec3& block_pos) const;
|
||||||
bool can_pass_block(const glm::ivec3& block_pos) const;
|
bool can_pass_block(const glm::ivec3& block_pos) const;
|
||||||
BlockType get_block_tpye(const glm::ivec3& block_pos) const;
|
BlockType get_block_tpye(const glm::ivec3& block_pos) const;
|
||||||
static ChunkPos chunk_pos(int world_x, int world_z);
|
static ChunkPos get_chunk_pos(int world_x, int world_z);
|
||||||
|
|
||||||
void need_gen();
|
void need_gen();
|
||||||
|
|
||||||
@@ -154,6 +162,11 @@ public:
|
|||||||
|
|
||||||
bool is_tick_running() const;
|
bool is_tick_running() const;
|
||||||
void tick_running(bool run);
|
void tick_running(bool run);
|
||||||
|
int pool_threads() const;
|
||||||
|
int max_threads() const;
|
||||||
|
void change_pool_threads(int threads);
|
||||||
|
int chunk_load_style() const;
|
||||||
|
void set_chunk_load_style(int id);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
|
|||||||
123
include/Cubed/tools/thread_pool.hpp
Normal file
123
include/Cubed/tools/thread_pool.hpp
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <functional>
|
||||||
|
#include <future>
|
||||||
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
namespace Cubed {
|
||||||
|
class ThreadPool {
|
||||||
|
private:
|
||||||
|
std::vector<std::jthread> m_workers;
|
||||||
|
std::queue<std::function<void()>> m_tasks;
|
||||||
|
std::mutex m_mtx;
|
||||||
|
std::condition_variable_any m_cv;
|
||||||
|
std::atomic<bool> m_stopping{false};
|
||||||
|
std::atomic<size_t> m_thread_sum{0};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThreadPool(const ThreadPool&) = delete;
|
||||||
|
ThreadPool(ThreadPool&&) = delete;
|
||||||
|
ThreadPool& operator=(const ThreadPool&) = delete;
|
||||||
|
ThreadPool& operator=(ThreadPool&&) = delete;
|
||||||
|
explicit ThreadPool(size_t thread_sum) : m_thread_sum(thread_sum) {
|
||||||
|
for (size_t i = 0; i < thread_sum; i++) {
|
||||||
|
m_workers.emplace_back([this](std::stop_token stoken) {
|
||||||
|
while (true) {
|
||||||
|
std::function<void()> task;
|
||||||
|
{
|
||||||
|
std::unique_lock lock(m_mtx);
|
||||||
|
m_cv.wait(lock, stoken,
|
||||||
|
[this, stoken] { return !m_tasks.empty(); });
|
||||||
|
if (stoken.stop_requested() && m_tasks.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
task = std::move(m_tasks.front());
|
||||||
|
m_tasks.pop();
|
||||||
|
}
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~ThreadPool() { stop(); }
|
||||||
|
template <typename F> auto enqueue(F&& f) {
|
||||||
|
|
||||||
|
using R = std::invoke_result_t<F>;
|
||||||
|
|
||||||
|
auto task =
|
||||||
|
std::make_shared<std::packaged_task<R()>>(std::forward<F>(f));
|
||||||
|
auto fut = task->get_future();
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard lock(m_mtx);
|
||||||
|
if (m_stopping)
|
||||||
|
throw std::runtime_error("thread pool stopped");
|
||||||
|
m_tasks.emplace([task] { (*task)(); });
|
||||||
|
}
|
||||||
|
m_cv.notify_one();
|
||||||
|
return fut;
|
||||||
|
}
|
||||||
|
void stop() {
|
||||||
|
m_stopping = true;
|
||||||
|
for (auto& w : m_workers) {
|
||||||
|
w.request_stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cv.notify_all();
|
||||||
|
|
||||||
|
for (auto& w : m_workers) {
|
||||||
|
if (w.joinable()) {
|
||||||
|
w.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t thread_sum() const { return m_thread_sum.load(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <std::random_access_iterator Iter, typename F>
|
||||||
|
void parallel_do(ThreadPool& pool, Iter first, Iter last, size_t max_threads,
|
||||||
|
F&& f) {
|
||||||
|
max_threads = std::max<size_t>(1, max_threads);
|
||||||
|
max_threads = std::min(max_threads, pool.thread_sum());
|
||||||
|
std::decay_t<F> fn(std::forward<F>(f));
|
||||||
|
size_t length = std::distance(first, last);
|
||||||
|
if (!length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t MIN_PER_THREAD = 25;
|
||||||
|
size_t num_blocks =
|
||||||
|
std::min(max_threads, (length + MIN_PER_THREAD - 1) / MIN_PER_THREAD);
|
||||||
|
num_blocks = std::max<size_t>(1, num_blocks);
|
||||||
|
size_t block_size = (length + num_blocks - 1) / num_blocks;
|
||||||
|
|
||||||
|
std::vector<std::future<void>> futures;
|
||||||
|
futures.reserve(num_blocks - 1);
|
||||||
|
Iter block_start = first;
|
||||||
|
for (size_t i = 0; i < num_blocks - 1; ++i) {
|
||||||
|
Iter block_end = block_start;
|
||||||
|
auto remain = std::distance(block_start, last);
|
||||||
|
std::advance(block_end, std::min<size_t>(block_size, remain));
|
||||||
|
|
||||||
|
futures.emplace_back(pool.enqueue([block_start, block_end, &fn]() {
|
||||||
|
for (auto it = block_start; it != block_end; ++it) {
|
||||||
|
fn(*it);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
block_start = block_end;
|
||||||
|
}
|
||||||
|
for (auto it = block_start; it != last; ++it) {
|
||||||
|
fn(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& fut : futures) {
|
||||||
|
fut.get();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Cubed
|
||||||
@@ -4,4 +4,5 @@ leak:libpangocairo
|
|||||||
leak:libdecor-gtk.so
|
leak:libdecor-gtk.so
|
||||||
leak:libgtk-3.so
|
leak:libgtk-3.so
|
||||||
leak:libwayland-client.so
|
leak:libwayland-client.so
|
||||||
leak:libglfw.so
|
leak:libglfw.so
|
||||||
|
leak:libEGL_nvidia.so
|
||||||
@@ -463,6 +463,29 @@ void DevPanel::show_world_tab_item() {
|
|||||||
if (ImGui::SliderInt("Render Distance", &rendering_distance, 2, 128)) {
|
if (ImGui::SliderInt("Render Distance", &rendering_distance, 2, 128)) {
|
||||||
m_app.world().rendering_distance(rendering_distance);
|
m_app.world().rendering_distance(rendering_distance);
|
||||||
}
|
}
|
||||||
|
ImGui::Text(
|
||||||
|
"Pool Threads %d Max Support Threads %d Reserved Threads %d",
|
||||||
|
m_app.world().pool_threads(), m_app.world().max_threads(),
|
||||||
|
RESERVED_THREADS);
|
||||||
|
ImGui::SliderInt("Set Pool Threads", &m_threads, 1,
|
||||||
|
m_app.world().max_threads());
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Set")) {
|
||||||
|
m_app.world().change_pool_threads(m_threads);
|
||||||
|
}
|
||||||
|
if (m_threads > m_app.world().max_threads() - RESERVED_THREADS) {
|
||||||
|
ImGui::TextColored(
|
||||||
|
ImVec4(1.0f, 1.0f, 0.0f, 1.0f),
|
||||||
|
"Waring: When the threads in the thread pool exceed \n(maximum "
|
||||||
|
"threads minus reserved threads), \nit may cause stuttering.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* chunk_load_style[] = {"Random", "Center"};
|
||||||
|
m_chunk_style = m_app.world().chunk_load_style();
|
||||||
|
if (ImGui::Combo("ChunkLoadStyle", &m_chunk_style, chunk_load_style,
|
||||||
|
IM_ARRAYSIZE(chunk_load_style))) {
|
||||||
|
m_app.world().set_chunk_load_style(m_chunk_style);
|
||||||
|
}
|
||||||
if (ImGui::Button("Rebuild World")) {
|
if (ImGui::Button("Rebuild World")) {
|
||||||
m_app.world().rebuild_world();
|
m_app.world().rebuild_world();
|
||||||
}
|
}
|
||||||
@@ -542,6 +565,8 @@ void DevPanel::show_player_tab_item() {
|
|||||||
m_player_profile.pos[1],
|
m_player_profile.pos[1],
|
||||||
m_player_profile.pos[2]});
|
m_player_profile.pos[2]});
|
||||||
}
|
}
|
||||||
|
ImGui::SliderFloat("Fly Y Speed", &m_player->fly_y_speed(), 0.0f,
|
||||||
|
100.0f);
|
||||||
ImGui::SliderFloat("Acceleration", &m_player->acceleration(), 1.0f,
|
ImGui::SliderFloat("Acceleration", &m_player->acceleration(), 1.0f,
|
||||||
200.0f);
|
200.0f);
|
||||||
ImGui::SliderFloat("Deceleration", &m_player->deceleration(), 1.0f,
|
ImGui::SliderFloat("Deceleration", &m_player->deceleration(), 1.0f,
|
||||||
|
|||||||
@@ -49,11 +49,13 @@ void CaveCarver::try_to_add_path(const ChunkPos& chunk_pos,
|
|||||||
|
|
||||||
void CaveCarver::cleanup_finished_caves() {
|
void CaveCarver::cleanup_finished_caves() {
|
||||||
std::vector<unsigned int> finished_keys;
|
std::vector<unsigned int> finished_keys;
|
||||||
|
|
||||||
for (const auto& pair : m_paths) {
|
for (const auto& pair : m_paths) {
|
||||||
if (pair.second.is_finished()) {
|
if (pair.second.is_finished()) {
|
||||||
finished_keys.push_back(pair.first);
|
finished_keys.push_back(pair.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& key : finished_keys) {
|
for (const auto& key : finished_keys) {
|
||||||
m_paths.erase(key);
|
m_paths.erase(key);
|
||||||
}
|
}
|
||||||
@@ -61,4 +63,5 @@ void CaveCarver::cleanup_finished_caves() {
|
|||||||
|
|
||||||
int CaveCarver::cave_sum() const { return m_paths.size(); }
|
int CaveCarver::cave_sum() const { return m_paths.size(); }
|
||||||
float& CaveCarver::cave_probability() { return m_cave_probability; }
|
float& CaveCarver::cave_probability() { return m_cave_probability; }
|
||||||
|
std::shared_mutex& CaveCarver::path_mutex() { return m_path_mutex; }
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
Chunk::Chunk(World& world, ChunkPos chunk_pos)
|
Chunk::Chunk(World& world, ChunkPos chunk_pos, bool temp_chunk)
|
||||||
: m_chunk_pos(chunk_pos), m_world(world) {
|
: m_temp_chunk(temp_chunk), m_chunk_pos(chunk_pos), m_world(world) {
|
||||||
for (int i = 0; i < VERTEX_DATA_SUM; i++) {
|
for (int i = 0; i < VERTEX_DATA_SUM; i++) {
|
||||||
m_vertex_data.emplace_back(m_world);
|
m_vertex_data.emplace_back(m_world);
|
||||||
}
|
}
|
||||||
@@ -299,7 +299,7 @@ void Chunk::gen_vertices(const OptionalBlockVectorArray& neighbor_block) {
|
|||||||
int world_nz = world_z + DIR[face].z;
|
int world_nz = world_z + DIR[face].z;
|
||||||
|
|
||||||
auto [neighbor_x, neighbor_z] =
|
auto [neighbor_x, neighbor_z] =
|
||||||
World::chunk_pos(world_nx, world_nz);
|
World::get_chunk_pos(world_nx, world_nz);
|
||||||
|
|
||||||
auto is_culled =
|
auto is_culled =
|
||||||
[&](const std::optional<std::vector<BlockType>>&
|
[&](const std::optional<std::vector<BlockType>>&
|
||||||
@@ -455,6 +455,42 @@ void Chunk::gen_cross_plane_vertices(int world_x, int world_y, int world_z,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Chunk::gen_chunk() {
|
||||||
|
if (m_gening.exchange(true))
|
||||||
|
return;
|
||||||
|
m_gening = true;
|
||||||
|
if (m_blocks.size() != 0) {
|
||||||
|
Logger::warn(
|
||||||
|
"Request Generator Chunk {} {} ,but the Blocks size is Not 0",
|
||||||
|
m_chunk_pos.x, m_chunk_pos.z);
|
||||||
|
}
|
||||||
|
std::vector<Chunk> neighbor;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
neighbor.emplace_back(m_world, m_chunk_pos + CHUNK_DIR[i], true);
|
||||||
|
}
|
||||||
|
for (auto& chunk : neighbor) {
|
||||||
|
chunk.gen_phase_one();
|
||||||
|
chunk.gen_phase_three();
|
||||||
|
chunk.gen_phase_five();
|
||||||
|
chunk.gen_phase_seven();
|
||||||
|
}
|
||||||
|
gen_phase_one();
|
||||||
|
gen_phase_three();
|
||||||
|
gen_phase_five();
|
||||||
|
|
||||||
|
OptionalBlockVectorArray neightbor_blocks;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
neightbor_blocks[i] = neighbor[i].get_chunk_blocks();
|
||||||
|
}
|
||||||
|
gen_phase_six(neightbor_blocks);
|
||||||
|
gen_phase_seven();
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
neightbor_blocks[i] = neighbor[i].get_chunk_blocks();
|
||||||
|
}
|
||||||
|
gen_vertex_data(neightbor_blocks);
|
||||||
|
}
|
||||||
// Logger::info("Cross Sum {}", m_cross_vertices_sum.load());
|
// Logger::info("Cross Sum {}", m_cross_vertices_sum.load());
|
||||||
|
|
||||||
|
bool Chunk::is_temp_chunk() const { return m_temp_chunk.load(); }
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
|
|||||||
@@ -723,18 +723,24 @@ void ChunkGenerator::generate_cave() {
|
|||||||
auto& paths = cave_carver.paths();
|
auto& paths = cave_carver.paths();
|
||||||
const auto& chunk_pos = m_chunk.chunk_pos();
|
const auto& chunk_pos = m_chunk.chunk_pos();
|
||||||
auto& blocks = m_chunk.blocks();
|
auto& blocks = m_chunk.blocks();
|
||||||
|
{
|
||||||
|
std::shared_lock lock(cave_carver.path_mutex());
|
||||||
|
for (auto& [id, path] : paths) {
|
||||||
|
|
||||||
for (auto& [id, path] : paths) {
|
carve_worm(path.points(), chunk_pos,
|
||||||
|
[&](int x, int y, int z) -> void {
|
||||||
carve_worm(path.points(), chunk_pos, [&](int x, int y, int z) -> void {
|
int idx = Chunk::index(x, y, z);
|
||||||
int idx = Chunk::index(x, y, z);
|
if (blocks[idx] == 7)
|
||||||
if (blocks[idx] == 7)
|
return;
|
||||||
return;
|
if (y < WORLD_SIZE_Y - 1 &&
|
||||||
if (y < WORLD_SIZE_Y - 1 && blocks[Chunk::index(x, y + 1, z)] == 7)
|
blocks[Chunk::index(x, y + 1, z)] == 7)
|
||||||
return;
|
return;
|
||||||
blocks[idx] = 0;
|
blocks[idx] = 0;
|
||||||
});
|
});
|
||||||
path.clear_chunk(chunk_pos);
|
if (!m_chunk.is_temp_chunk()) {
|
||||||
|
path.clear_chunk(chunk_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,29 +750,36 @@ void ChunkGenerator::generate_river() {
|
|||||||
auto& paths = river_worm.paths();
|
auto& paths = river_worm.paths();
|
||||||
const auto& chunk_pos = m_chunk.chunk_pos();
|
const auto& chunk_pos = m_chunk.chunk_pos();
|
||||||
auto& blocks = m_chunk.blocks();
|
auto& blocks = m_chunk.blocks();
|
||||||
|
|
||||||
bool is_river = false;
|
bool is_river = false;
|
||||||
|
{
|
||||||
for (auto& [id, path] : paths) {
|
std::shared_lock lock(river_worm.paths_mutex());
|
||||||
if ((m_chunk.biome() == BiomeType::DESERT) ||
|
for (auto& [id, path] : paths) {
|
||||||
(m_chunk.biome() == BiomeType::OCEAN)) {
|
if ((m_chunk.biome() == BiomeType::DESERT) ||
|
||||||
path.clear_chunk(chunk_pos);
|
(m_chunk.biome() == BiomeType::OCEAN)) {
|
||||||
continue;
|
if (!m_chunk.is_temp_chunk()) {
|
||||||
|
path.clear_chunk(chunk_pos);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
carve_worm(path.points(), chunk_pos,
|
||||||
|
[&](int x, int y, int z) -> void {
|
||||||
|
int idx = Chunk::index(x, y, z);
|
||||||
|
if (y > SEA_LEVEL) {
|
||||||
|
blocks[idx] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
is_river = true;
|
||||||
|
if (blocks[idx] == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
blocks[idx] = 7;
|
||||||
|
});
|
||||||
|
if (!m_chunk.is_temp_chunk()) {
|
||||||
|
path.clear_chunk(chunk_pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
carve_worm(path.points(), chunk_pos, [&](int x, int y, int z) -> void {
|
|
||||||
int idx = Chunk::index(x, y, z);
|
|
||||||
if (y > SEA_LEVEL) {
|
|
||||||
blocks[idx] = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
is_river = true;
|
|
||||||
if (blocks[idx] == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
blocks[idx] = 7;
|
|
||||||
});
|
|
||||||
path.clear_chunk(chunk_pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_river) {
|
if (is_river) {
|
||||||
m_chunk.biome(RIVER);
|
m_chunk.biome(RIVER);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ void Player::update_front_vec(float offset_x, float offset_y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Player::check_player_chunk_transition() {
|
void Player::check_player_chunk_transition() {
|
||||||
ChunkPos cur_pos = m_world.chunk_pos(m_player_pos.x, m_player_pos.z);
|
ChunkPos cur_pos = m_world.get_chunk_pos(m_player_pos.x, m_player_pos.z);
|
||||||
if (cur_pos != m_player_chunk_pos) {
|
if (cur_pos != m_player_chunk_pos) {
|
||||||
m_world.need_gen();
|
m_world.need_gen();
|
||||||
m_player_chunk_pos = cur_pos;
|
m_player_chunk_pos = cur_pos;
|
||||||
@@ -372,11 +372,11 @@ void Player::update_move(float delta_time) {
|
|||||||
|
|
||||||
if (is_fly) {
|
if (is_fly) {
|
||||||
if (m_move_state.up) {
|
if (m_move_state.up) {
|
||||||
m_y_speed = 7.5f;
|
m_y_speed = m_fly_y_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_move_state.down) {
|
if (m_move_state.down) {
|
||||||
m_y_speed = -7.5f;
|
m_y_speed = -m_fly_y_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_move_state.down && !m_move_state.up) {
|
if (!m_move_state.down && !m_move_state.up) {
|
||||||
@@ -544,6 +544,7 @@ float& Player::max_speed() { return m_max_speed; }
|
|||||||
float& Player::acceleration() { return m_acceleration; }
|
float& Player::acceleration() { return m_acceleration; }
|
||||||
float& Player::deceleration() { return m_deceleration; }
|
float& Player::deceleration() { return m_deceleration; }
|
||||||
float& Player::g() { return m_g; }
|
float& Player::g() { return m_g; }
|
||||||
|
float& Player::fly_y_speed() { return m_fly_y_speed; }
|
||||||
unsigned Player::place_block() const { return m_place_block; };
|
unsigned Player::place_block() const { return m_place_block; };
|
||||||
Gait& Player::gait() { return m_gait; }
|
Gait& Player::gait() { return m_gait; }
|
||||||
GameMode& Player::game_mode() { return m_game_mode; }
|
GameMode& Player::game_mode() { return m_game_mode; }
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
RiverWorm::RiverWorm() {}
|
RiverWorm::RiverWorm() {}
|
||||||
|
RiverWorm::~RiverWorm() {}
|
||||||
RiverWorm::RiverHashMap& RiverWorm::paths() { return m_paths; }
|
RiverWorm::RiverHashMap& RiverWorm::paths() { return m_paths; }
|
||||||
|
|
||||||
void RiverWorm::init(unsigned world_seed) {
|
void RiverWorm::init(unsigned world_seed) {
|
||||||
@@ -46,11 +46,13 @@ void RiverWorm::try_to_add_path(const ChunkPos& chunk_pos,
|
|||||||
|
|
||||||
void RiverWorm::cleanup_finished_rivers() {
|
void RiverWorm::cleanup_finished_rivers() {
|
||||||
std::vector<unsigned> finished_keys;
|
std::vector<unsigned> finished_keys;
|
||||||
|
|
||||||
for (const auto& pair : m_paths) {
|
for (const auto& pair : m_paths) {
|
||||||
if (pair.second.is_finished()) {
|
if (pair.second.is_finished()) {
|
||||||
finished_keys.push_back(pair.first);
|
finished_keys.push_back(pair.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& key : finished_keys) {
|
for (const auto& key : finished_keys) {
|
||||||
m_paths.erase(key);
|
m_paths.erase(key);
|
||||||
}
|
}
|
||||||
@@ -58,4 +60,6 @@ void RiverWorm::cleanup_finished_rivers() {
|
|||||||
|
|
||||||
int RiverWorm::river_sum() const { return m_paths.size(); }
|
int RiverWorm::river_sum() const { return m_paths.size(); }
|
||||||
float& RiverWorm::river_probability() { return m_probability; }
|
float& RiverWorm::river_probability() { return m_probability; }
|
||||||
|
std::shared_mutex& RiverWorm::paths_mutex() { return m_paths_mutex; }
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -5,10 +5,10 @@
|
|||||||
#include "Cubed/tools/cubed_assert.hpp"
|
#include "Cubed/tools/cubed_assert.hpp"
|
||||||
#include "Cubed/tools/cubed_hash.hpp"
|
#include "Cubed/tools/cubed_hash.hpp"
|
||||||
|
|
||||||
#include <execution>
|
|
||||||
#include <glm/gtc/constants.hpp>
|
#include <glm/gtc/constants.hpp>
|
||||||
#include <numbers>
|
#include <numbers>
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
@@ -22,6 +22,13 @@ World::World() {}
|
|||||||
World::~World() {
|
World::~World() {
|
||||||
stop_gen_thread();
|
stop_gen_thread();
|
||||||
stop_server_thread();
|
stop_server_thread();
|
||||||
|
wait_all_chunk_tasks();
|
||||||
|
auto pool_ptr = m_gen_thread_pool.load();
|
||||||
|
if (pool_ptr) {
|
||||||
|
pool_ptr->stop();
|
||||||
|
}
|
||||||
|
m_gen_thread_pool.store(nullptr);
|
||||||
|
|
||||||
m_chunks.clear();
|
m_chunks.clear();
|
||||||
{
|
{
|
||||||
std::lock_guard lk(m_delete_vbo_mutex);
|
std::lock_guard lk(m_delete_vbo_mutex);
|
||||||
@@ -39,6 +46,12 @@ World::~World() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::wait_all_chunk_tasks() {
|
||||||
|
for (auto& [pos, task] : new_chunks) {
|
||||||
|
task.future.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool World::can_move(const AABB& player_box) const { return true; }
|
bool World::can_move(const AABB& player_box) const { return true; }
|
||||||
|
|
||||||
const std::optional<LookBlock>&
|
const std::optional<LookBlock>&
|
||||||
@@ -77,10 +90,11 @@ void World::init_world() {
|
|||||||
m_cave_carcer.init(ChunkGenerator::seed());
|
m_cave_carcer.init(ChunkGenerator::seed());
|
||||||
m_river_worm.init(ChunkGenerator::seed());
|
m_river_worm.init(ChunkGenerator::seed());
|
||||||
m_chunks.reserve(MAX_DISTANCE * MAX_DISTANCE * 4);
|
m_chunks.reserve(MAX_DISTANCE * MAX_DISTANCE * 4);
|
||||||
|
int max_thread = std::thread::hardware_concurrency();
|
||||||
|
change_pool_threads(max_thread - RESERVED_THREADS);
|
||||||
|
|
||||||
auto t1 = std::chrono::system_clock::now();
|
auto t1 = std::chrono::system_clock::now();
|
||||||
|
|
||||||
Logger::info("Max Support Thread is {}",
|
|
||||||
std::thread::hardware_concurrency());
|
|
||||||
// init players
|
// init players
|
||||||
m_players.emplace(HASH::str("TestPlayer"), Player(*this, "TestPlayer"));
|
m_players.emplace(HASH::str("TestPlayer"), Player(*this, "TestPlayer"));
|
||||||
|
|
||||||
@@ -102,210 +116,7 @@ void World::init_chunks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
ChunkPos World::get_chunk_pos(int world_x, int world_z) {
|
||||||
void World::init_chunks() {
|
|
||||||
|
|
||||||
int dis_x = PRE_LOAD_DISTANCE;
|
|
||||||
int dis_z = PRE_LOAD_DISTANCE;
|
|
||||||
for (int x = 0; x < dis_x; x++) {
|
|
||||||
for (int z = 0; z < dis_z; z++) {
|
|
||||||
int nx = x - dis_x / 2;
|
|
||||||
int nz = z - dis_z / 2;
|
|
||||||
ChunkPos pos{nx, nz};
|
|
||||||
auto it = m_chunks.find(pos);
|
|
||||||
if (it == m_chunks.end()) {
|
|
||||||
m_chunks.emplace(pos, Chunk(*this, pos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ChunkHashMap temp_neighbor;
|
|
||||||
for (int x = 0; x < dis_x + 2; x++) {
|
|
||||||
for (int z = 0; z < dis_z + 2; z++) {
|
|
||||||
int nx = x - (dis_x + 2) / 2;
|
|
||||||
int nz = z - (dis_z + 2) / 2;
|
|
||||||
ChunkPos pos{nx, nz};
|
|
||||||
auto it = m_chunks.find(pos);
|
|
||||||
if (it == m_chunks.end()) {
|
|
||||||
auto it = temp_neighbor.find(pos);
|
|
||||||
if (it == temp_neighbor.end()) {
|
|
||||||
temp_neighbor.emplace(pos, Chunk(*this, pos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto& [pos, chunk] : m_chunks) {
|
|
||||||
chunk.gen_phase_one();
|
|
||||||
m_cave_carcer.try_to_add_path(pos, chunk.seed());
|
|
||||||
}
|
|
||||||
for (auto& [pos, chunk] : temp_neighbor) {
|
|
||||||
chunk.gen_phase_one();
|
|
||||||
m_cave_carcer.try_to_add_path(pos, chunk.seed());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::array<const Chunk*, 8> neighbor_chunks;
|
|
||||||
for (auto& [pos, chunks] : m_chunks) {
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
auto neighbor_pos = pos + CHUNK_DIR[i];
|
|
||||||
auto it = m_chunks.find(neighbor_pos);
|
|
||||||
if (it == m_chunks.end()) {
|
|
||||||
auto it = temp_neighbor.find(neighbor_pos);
|
|
||||||
if (it == temp_neighbor.end()) {
|
|
||||||
neighbor_chunks[i] = nullptr;
|
|
||||||
ASSERT_MSG(false, "Neighbor Chunk is nullptr");
|
|
||||||
} else {
|
|
||||||
neighbor_chunks[i] = &it->second;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
neighbor_chunks[i] = &it->second;
|
|
||||||
}
|
|
||||||
chunks.gen_phase_two(neighbor_chunks);
|
|
||||||
}
|
|
||||||
for (auto& [pos, chunks] : temp_neighbor) {
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
auto neighbor_pos = pos + CHUNK_DIR[i];
|
|
||||||
auto it = m_chunks.find(neighbor_pos);
|
|
||||||
if (it == m_chunks.end()) {
|
|
||||||
auto it = temp_neighbor.find(neighbor_pos);
|
|
||||||
if (it == temp_neighbor.end()) {
|
|
||||||
neighbor_chunks[i] = nullptr;
|
|
||||||
} else {
|
|
||||||
neighbor_chunks[i] = &it->second;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
neighbor_chunks[i] = &it->second;
|
|
||||||
}
|
|
||||||
chunks.gen_phase_two(neighbor_chunks);
|
|
||||||
}
|
|
||||||
for (auto& [pos, chunks] : m_chunks) {
|
|
||||||
chunks.gen_phase_three();
|
|
||||||
}
|
|
||||||
for (auto& [pos, chunks] : temp_neighbor) {
|
|
||||||
chunks.gen_phase_three();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
for (auto& [pos, chunks] : temp_neighbor) {
|
|
||||||
std::array<std::optional<HeightMapArray>, 8>
|
|
||||||
neighbor_chunk_heightmap;
|
|
||||||
std::array<BiomeType, 8> neighbor_biome;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
auto neighbor_pos = pos + CHUNK_DIR[i];
|
|
||||||
auto it = m_chunks.find(neighbor_pos);
|
|
||||||
if (it == m_chunks.end()) {
|
|
||||||
auto it = temp_neighbor.find(neighbor_pos);
|
|
||||||
if (it == temp_neighbor.end()) {
|
|
||||||
neighbor_chunk_heightmap[i] = std::nullopt;
|
|
||||||
neighbor_biome[i] = BiomeType::NONE;
|
|
||||||
} else {
|
|
||||||
neighbor_chunk_heightmap[i] =
|
|
||||||
it->second.get_heightmap();
|
|
||||||
neighbor_biome[i] = it->second.biome();
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
neighbor_chunk_heightmap[i] = it->second.get_heightmap();
|
|
||||||
neighbor_biome[i] = it->second.biome();
|
|
||||||
}
|
|
||||||
chunks.gen_phase_four(neighbor_chunk_heightmap, neighbor_biome);
|
|
||||||
}
|
|
||||||
for (auto& [pos, chunks] : m_chunks) {
|
|
||||||
std::array<std::optional<HeightMapArray>, 8>
|
|
||||||
neighbor_chunk_heightmap;
|
|
||||||
std::array<BiomeType, 8> neighbor_biome;
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
|
|
||||||
auto neighbor_pos = pos + CHUNK_DIR[i];
|
|
||||||
auto it = m_chunks.find(neighbor_pos);
|
|
||||||
if (it == m_chunks.end()) {
|
|
||||||
auto it = temp_neighbor.find(neighbor_pos);
|
|
||||||
if (it == temp_neighbor.end()) {
|
|
||||||
neighbor_chunk_heightmap[i] = std::nullopt;
|
|
||||||
neighbor_biome[i] = BiomeType::NONE;
|
|
||||||
ASSERT_MSG(false, "Neighbor Chunk is nullptr");
|
|
||||||
} else {
|
|
||||||
neighbor_chunk_heightmap[i] =
|
|
||||||
it->second.get_heightmap();
|
|
||||||
neighbor_biome[i] = it->second.biome();
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
neighbor_chunk_heightmap[i] = it->second.get_heightmap();
|
|
||||||
neighbor_biome[i] = it->second.biome();
|
|
||||||
}
|
|
||||||
chunks.gen_phase_four(neighbor_chunk_heightmap, neighbor_biome);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& [pos, chunks] : m_chunks) {
|
|
||||||
chunks.gen_phase_five();
|
|
||||||
}
|
|
||||||
for (auto& [pos, chunks] : temp_neighbor) {
|
|
||||||
chunks.gen_phase_five();
|
|
||||||
}
|
|
||||||
std::array<std::optional<std::vector<BlockType>>, 4> neighbor_block;
|
|
||||||
for (auto& [pos, chunks] : m_chunks) {
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
auto neighbor_pos = pos + CHUNK_DIR[i];
|
|
||||||
auto it = m_chunks.find(neighbor_pos);
|
|
||||||
if (it == m_chunks.end()) {
|
|
||||||
auto it = temp_neighbor.find(neighbor_pos);
|
|
||||||
if (it == temp_neighbor.end()) {
|
|
||||||
neighbor_block[i] = std::nullopt;
|
|
||||||
ASSERT_MSG(false, "Neighbor Chunk is nullptr");
|
|
||||||
} else {
|
|
||||||
neighbor_block[i] = it->second.get_chunk_blocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
neighbor_block[i] = it->second.get_chunk_blocks();
|
|
||||||
}
|
|
||||||
chunks.gen_phase_six(neighbor_block);
|
|
||||||
}
|
|
||||||
for (auto& [pos, chunks] : m_chunks) {
|
|
||||||
chunks.gen_phase_seven();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::atomic<int> sync{0};
|
|
||||||
sync.store(1, std::memory_order_release);
|
|
||||||
sync.load(std::memory_order_acquire);
|
|
||||||
|
|
||||||
m_cave_carcer.cleanup_finished_caves();
|
|
||||||
|
|
||||||
std::vector<ChunkRenderData> pending_gen_data;
|
|
||||||
pending_gen_data.reserve(m_chunks.size());
|
|
||||||
for (auto& [pos, chunk] : m_chunks) {
|
|
||||||
ChunkRenderData data;
|
|
||||||
data.chunk = &chunk;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
auto it = m_chunks.find(pos + CHUNK_DIR[i]);
|
|
||||||
if (it != m_chunks.end()) {
|
|
||||||
data.neighbor_block[i] = &(it->second.get_chunk_blocks());
|
|
||||||
} else {
|
|
||||||
data.neighbor_block[i] = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pending_gen_data.emplace_back(std::move(data));
|
|
||||||
}
|
|
||||||
std::for_each(std::execution::par, pending_gen_data.begin(),
|
|
||||||
pending_gen_data.end(), [](ChunkRenderData& data) {
|
|
||||||
if (!data.chunk) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
data.chunk->gen_vertex_data(data.neighbor_block);
|
|
||||||
});
|
|
||||||
for (auto& chunk_map : m_chunks) {
|
|
||||||
auto& [chunk_pos, chunk] = chunk_map;
|
|
||||||
chunk.upload_to_gpu();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
ChunkPos World::chunk_pos(int world_x, int world_z) {
|
|
||||||
int chunk_x, chunk_z;
|
int chunk_x, chunk_z;
|
||||||
if (world_x < 0) {
|
if (world_x < 0) {
|
||||||
chunk_x = (world_x + 1) / CHUNK_SIZE - 1;
|
chunk_x = (world_x + 1) / CHUNK_SIZE - 1;
|
||||||
@@ -325,13 +136,19 @@ ChunkPos World::chunk_pos(int world_x, int world_z) {
|
|||||||
#pragma region ChunkGenerate
|
#pragma region ChunkGenerate
|
||||||
|
|
||||||
void World::gen_chunks_internal() {
|
void World::gen_chunks_internal() {
|
||||||
|
// Logger::info("gen_chunks_internal");
|
||||||
m_chunk_gen_fraction = 0.0f;
|
m_chunk_gen_fraction = 0.0f;
|
||||||
m_chunk_gen_finished = false;
|
m_chunk_gen_finished = false;
|
||||||
|
/*
|
||||||
|
if (!new_chunks.empty()) {
|
||||||
|
submit_new_chunks();
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
ChunkPosSet required_chunks;
|
ChunkPosSet required_chunks;
|
||||||
ChunkPairVector temp_neighbor;
|
ChunkPairVector temp_neighbor;
|
||||||
std::vector<ChunkPos> need_gen_temp_chunks_pos;
|
|
||||||
compute_required_chunks(required_chunks, temp_neighbor,
|
compute_required_chunks(required_chunks, temp_neighbor);
|
||||||
need_gen_temp_chunks_pos);
|
|
||||||
|
|
||||||
ASSERT_MSG(!required_chunks.empty(), "required chunks is empty!!");
|
ASSERT_MSG(!required_chunks.empty(), "required chunks is empty!!");
|
||||||
|
|
||||||
@@ -348,256 +165,36 @@ void World::gen_chunks_internal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_chunk_gen_fraction = 0.1f;
|
m_chunk_gen_fraction = 0.1f;
|
||||||
|
|
||||||
ChunkPairVector new_chunks;
|
|
||||||
ChunkHashMap new_temp_chunks;
|
|
||||||
for (auto& pos : need_gen_chunks_pos) {
|
for (auto& pos : need_gen_chunks_pos) {
|
||||||
new_chunks.push_back({pos, Chunk(*this, pos)});
|
new_chunks.emplace(pos, Chunk(*this, pos));
|
||||||
}
|
}
|
||||||
for (auto& pos : need_gen_temp_chunks_pos) {
|
auto t1 = system_clock::now();
|
||||||
new_temp_chunks.emplace(pos, Chunk(*this, pos));
|
{
|
||||||
}
|
std::scoped_lock lock{m_cave_carcer.path_mutex(),
|
||||||
ConstChunkMap new_chunks_neighbor;
|
m_river_worm.paths_mutex()};
|
||||||
// affected neighbor
|
auto pool_ptr = m_gen_thread_pool.load();
|
||||||
ChunkPtrUpdateList affected_neighbor;
|
if (!pool_ptr) {
|
||||||
|
return;
|
||||||
build_neighbor_context_for_new_chunks(new_chunks_neighbor,
|
|
||||||
affected_neighbor, new_chunks);
|
|
||||||
|
|
||||||
// build new chunk, but the neighbor in m_chunks also need to re-build
|
|
||||||
|
|
||||||
std::for_each(std::execution::par, new_chunks.begin(), new_chunks.end(),
|
|
||||||
[this](std::pair<ChunkPos, Chunk>& new_chunk) {
|
|
||||||
auto& [pos, chunk] = new_chunk;
|
|
||||||
chunk.gen_phase_one();
|
|
||||||
m_cave_carcer.try_to_add_path(pos, chunk.seed());
|
|
||||||
m_river_worm.try_to_add_path(pos, chunk.seed());
|
|
||||||
});
|
|
||||||
|
|
||||||
std::for_each(new_temp_chunks.begin(), new_temp_chunks.end(),
|
|
||||||
[](std::pair<const ChunkPos, Chunk>& new_chunk) {
|
|
||||||
auto& [pos, chunk] = new_chunk;
|
|
||||||
chunk.gen_phase_one();
|
|
||||||
});
|
|
||||||
// precompute path to ensure the continuity of the path
|
|
||||||
std::for_each(std::execution::par, temp_neighbor.begin(),
|
|
||||||
temp_neighbor.end(),
|
|
||||||
[this](std::pair<ChunkPos, Chunk>& new_chunk) {
|
|
||||||
auto& [pos, chunk] = new_chunk;
|
|
||||||
chunk.gen_phase_one();
|
|
||||||
m_cave_carcer.try_to_add_path(pos, chunk.seed());
|
|
||||||
m_river_worm.try_to_add_path(pos, chunk.seed());
|
|
||||||
});
|
|
||||||
|
|
||||||
m_chunk_gen_fraction = 0.2f;
|
|
||||||
|
|
||||||
/*
|
|
||||||
std::array<const Chunk*, 8> neighbor_chunks;
|
|
||||||
for (auto& [pos, chunks] : new_chunks) {
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
auto neighbor_pos = pos + CHUNK_DIR[i];
|
|
||||||
auto it = new_chunks_neighbor.find(neighbor_pos);
|
|
||||||
if (it == new_chunks_neighbor.end()) {
|
|
||||||
neighbor_chunks[i] = nullptr;
|
|
||||||
// ASSERT_MSG(false, "Cant Find Neighbot");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
neighbor_chunks[i] = it->second;
|
|
||||||
}
|
|
||||||
chunks.gen_phase_two(neighbor_chunks);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
for (auto& [pos, chunks] : temp_neighbor) {
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
auto neighbor_pos = pos + CHUNK_DIR[i];
|
|
||||||
auto it = new_chunks_neighbor.find(neighbor_pos);
|
|
||||||
if (it == new_chunks_neighbor.end()) {
|
|
||||||
neighbor_chunks[i] = nullptr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
neighbor_chunks[i] = it->second;
|
|
||||||
}
|
|
||||||
chunks.gen_phase_two(neighbor_chunks);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
m_chunk_gen_fraction = 0.3f;
|
|
||||||
|
|
||||||
std::for_each(std::execution::par, new_chunks.begin(), new_chunks.end(),
|
|
||||||
[](std::pair<ChunkPos, Chunk>& pair) {
|
|
||||||
auto& [pos, chunks] = pair;
|
|
||||||
chunks.gen_phase_three();
|
|
||||||
});
|
|
||||||
|
|
||||||
for (auto& [pos, chunk] : new_temp_chunks) {
|
|
||||||
chunk.gen_phase_three();
|
|
||||||
}
|
|
||||||
// for (auto& [pos, chunks] : temp_neighbor) {
|
|
||||||
// chunks.gen_phase_three();
|
|
||||||
// }
|
|
||||||
|
|
||||||
/*
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
for (auto& [pos, chunks] : temp_neighbor) {
|
|
||||||
std::array<std::optional<HeightMapArray>, 8>
|
|
||||||
neighbor_chunk_heightmap;
|
|
||||||
// std::lock_guard lk(m_chunks_mutex);
|
|
||||||
std::array<BiomeType, 8> neighbor_biome;
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
auto neighbor_pos = pos + CHUNK_DIR[i];
|
|
||||||
auto it = new_chunks_neighbor.find(neighbor_pos);
|
|
||||||
if (it == new_chunks_neighbor.end()) {
|
|
||||||
neighbor_chunk_heightmap[i] = std::nullopt;
|
|
||||||
neighbor_biome[i] = BiomeType::NONE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
neighbor_chunk_heightmap[i] = it->second->get_heightmap();
|
|
||||||
neighbor_biome[i] = it->second->biome();
|
|
||||||
}
|
|
||||||
|
|
||||||
chunks.gen_phase_four(neighbor_chunk_heightmap, neighbor_biome);
|
|
||||||
}
|
|
||||||
for (auto& [pos, chunks] : new_chunks) {
|
|
||||||
std::array<std::optional<HeightMapArray>, 8>
|
|
||||||
neighbor_chunk_heightmap;
|
|
||||||
// std::lock_guard lk(m_chunks_mutex);
|
|
||||||
std::array<BiomeType, 8> neighbor_biome;
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
auto neighbor_pos = pos + CHUNK_DIR[i];
|
|
||||||
auto it = new_chunks_neighbor.find(neighbor_pos);
|
|
||||||
if (it == new_chunks_neighbor.end()) {
|
|
||||||
neighbor_chunk_heightmap[i] = std::nullopt;
|
|
||||||
neighbor_biome[i] = BiomeType::NONE;
|
|
||||||
ASSERT_MSG(false, "Cant Find Neighbot");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
neighbor_chunk_heightmap[i] = it->second->get_heightmap();
|
|
||||||
neighbor_biome[i] = it->second->biome();
|
|
||||||
}
|
|
||||||
|
|
||||||
chunks.gen_phase_four(neighbor_chunk_heightmap, neighbor_biome);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
m_chunk_gen_fraction = 0.4f;
|
|
||||||
|
|
||||||
for (auto& [pos, chunks] : new_chunks) {
|
|
||||||
chunks.gen_phase_five();
|
|
||||||
}
|
|
||||||
m_chunk_gen_fraction = 0.45f;
|
|
||||||
for (auto& [pos, chunk] : new_temp_chunks) {
|
|
||||||
chunk.gen_phase_five();
|
|
||||||
}
|
|
||||||
m_chunk_gen_fraction = 0.5f;
|
|
||||||
/*
|
|
||||||
for (auto& [pos, chunks] : temp_neighbor) {
|
|
||||||
chunks.gen_phase_five();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
std::vector<std::pair<Chunk*, OptionalBlockVectorArray>>
|
|
||||||
new_chunks_surface_blend_data(new_chunks.size());
|
|
||||||
for (size_t idx = 0; idx < new_chunks.size(); idx++) {
|
|
||||||
auto& [pos, chunk] = new_chunks[idx];
|
|
||||||
new_chunks_surface_blend_data[idx].first = &chunk;
|
|
||||||
{
|
|
||||||
// std::lock_guard lk(m_chunks_mutex);
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
auto neighbor_pos = pos + CHUNK_DIR[i];
|
|
||||||
auto it = new_chunks_neighbor.find(neighbor_pos);
|
|
||||||
if (it == new_chunks_neighbor.end()) {
|
|
||||||
auto it = new_temp_chunks.find(neighbor_pos);
|
|
||||||
if (it == new_temp_chunks.end()) {
|
|
||||||
new_chunks_surface_blend_data[idx].second[i] =
|
|
||||||
std::nullopt;
|
|
||||||
Logger::warn(
|
|
||||||
"Can't find neighbor for chunk surface blend");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
new_chunks_surface_blend_data[idx].second[i] =
|
|
||||||
it->second.get_chunk_blocks();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
new_chunks_surface_blend_data[idx].second[i] =
|
|
||||||
it->second->get_chunk_blocks();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
parallel_do(*pool_ptr, temp_neighbor.begin(), temp_neighbor.end(),
|
||||||
|
pool_ptr->thread_sum(),
|
||||||
|
[this](std::pair<ChunkPos, Chunk>& new_chunk) {
|
||||||
|
auto& [pos, chunk] = new_chunk;
|
||||||
|
chunk.gen_phase_one();
|
||||||
|
m_cave_carcer.try_to_add_path(pos, chunk.seed());
|
||||||
|
m_river_worm.try_to_add_path(pos, chunk.seed());
|
||||||
|
});
|
||||||
|
m_cave_carcer.cleanup_finished_caves();
|
||||||
|
m_river_worm.cleanup_finished_rivers();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::for_each(
|
auto t2 = system_clock::now();
|
||||||
std::execution::par, new_chunks_surface_blend_data.begin(),
|
Logger::info("Temp Neighbor Add Path Consum {}",
|
||||||
new_chunks_surface_blend_data.end(),
|
duration_cast<milliseconds>(t2 - t1));
|
||||||
[](std::pair<Chunk*, OptionalBlockVectorArray>& new_chunk_data) {
|
|
||||||
auto& [chunk, neighbor_data] = new_chunk_data;
|
|
||||||
chunk->gen_phase_six(neighbor_data);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_chunk_gen_fraction = 0.55f;
|
|
||||||
std::for_each(std::execution::par, new_chunks.begin(), new_chunks.end(),
|
|
||||||
[](std::pair<ChunkPos, Chunk>& new_chunk) {
|
|
||||||
auto& [pos, chunk] = new_chunk;
|
|
||||||
chunk.gen_phase_seven();
|
|
||||||
});
|
|
||||||
|
|
||||||
m_chunk_gen_fraction = 0.6f;
|
|
||||||
|
|
||||||
std::vector<std::pair<Chunk*, OptionalBlockVectorArray>>
|
|
||||||
new_chunk_vertices_data(new_chunks.size());
|
|
||||||
for (size_t idx = 0; idx < new_chunks.size(); idx++) {
|
|
||||||
auto& [pos, chunk] = new_chunks[idx];
|
|
||||||
new_chunk_vertices_data[idx].first = &chunk;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
auto it = new_chunks_neighbor.find(pos + CHUNK_DIR[i]);
|
|
||||||
if (it != new_chunks_neighbor.end()) {
|
|
||||||
new_chunk_vertices_data[idx].second[i] =
|
|
||||||
(it->second->get_chunk_blocks());
|
|
||||||
} else {
|
|
||||||
new_chunk_vertices_data[idx].second[i] = std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::for_each(
|
|
||||||
std::execution::par, new_chunk_vertices_data.begin(),
|
|
||||||
new_chunk_vertices_data.end(),
|
|
||||||
[](std::pair<Chunk*, OptionalBlockVectorArray>& new_chunk_data) {
|
|
||||||
auto& [chunk, neighbor_data] = new_chunk_data;
|
|
||||||
chunk->gen_vertex_data(neighbor_data);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_chunk_gen_fraction = 0.7f;
|
|
||||||
|
|
||||||
build_neighbor_context_for_affected_neighbors(affected_neighbor,
|
|
||||||
new_chunks_neighbor);
|
|
||||||
|
|
||||||
m_chunk_gen_fraction = 0.8f;
|
|
||||||
OptionalBlockVectorArray neighbor_block;
|
|
||||||
for (auto& [pos, chunk] : affected_neighbor) {
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
auto it = new_chunks_neighbor.find(pos + CHUNK_DIR[i]);
|
|
||||||
if (it != new_chunks_neighbor.end()) {
|
|
||||||
neighbor_block[i] = (it->second->get_chunk_blocks());
|
|
||||||
} else {
|
|
||||||
neighbor_block[i] = std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chunk->gen_vertex_data(neighbor_block);
|
|
||||||
chunk->need_upload();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_chunk_gen_fraction = 0.9f;
|
m_chunk_gen_fraction = 0.9f;
|
||||||
|
|
||||||
{
|
|
||||||
std::lock_guard lk(m_new_chunk_queue_mutex);
|
|
||||||
for (auto& x : new_chunks) {
|
|
||||||
m_new_chunk_queue.emplace_back(std::move(x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_cave_carcer.cleanup_finished_caves();
|
|
||||||
m_river_worm.cleanup_finished_rivers();
|
|
||||||
m_chunk_gen_fraction = 1.0f;
|
m_chunk_gen_fraction = 1.0f;
|
||||||
|
submit_new_chunks();
|
||||||
m_chunk_gen_finished = true;
|
m_chunk_gen_finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -606,15 +203,14 @@ void World::sync_player_pos(glm::vec3& player_pos) {
|
|||||||
player_pos = m_gen_player_pos;
|
player_pos = m_gen_player_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::compute_required_chunks(
|
void World::compute_required_chunks(ChunkPosSet& required_chunks,
|
||||||
ChunkPosSet& required_chunks, ChunkPairVector& temp_neighbor,
|
ChunkPairVector& temp_neighbor) {
|
||||||
std::vector<ChunkPos>& need_gen_temp_chunks_pos) {
|
|
||||||
glm::vec3 player_pos;
|
glm::vec3 player_pos;
|
||||||
sync_player_pos(player_pos);
|
sync_player_pos(player_pos);
|
||||||
|
|
||||||
int x = std::floor(player_pos.x);
|
int x = std::floor(player_pos.x);
|
||||||
int z = std::floor(player_pos.z);
|
int z = std::floor(player_pos.z);
|
||||||
auto [chunk_x, chunk_z] = chunk_pos(x, z);
|
auto [chunk_x, chunk_z] = get_chunk_pos(x, z);
|
||||||
int radius = m_rendering_distance;
|
int radius = m_rendering_distance;
|
||||||
int r2 = radius * radius;
|
int r2 = radius * radius;
|
||||||
required_chunks.reserve(radius * radius);
|
required_chunks.reserve(radius * radius);
|
||||||
@@ -626,20 +222,6 @@ void World::compute_required_chunks(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int new_radius = radius + 1;
|
|
||||||
int new_r2 = new_radius * new_radius;
|
|
||||||
for (int dx = -new_radius; dx <= new_radius; ++dx) {
|
|
||||||
for (int dz = -new_radius; dz <= new_radius; ++dz) {
|
|
||||||
if (dx * dx + dz * dz <= new_r2) {
|
|
||||||
int nx = chunk_x + dx;
|
|
||||||
int nz = chunk_z + dz;
|
|
||||||
auto it = required_chunks.find({nx, nz});
|
|
||||||
if (it == required_chunks.end()) {
|
|
||||||
need_gen_temp_chunks_pos.push_back({nx, nz});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int max_path_len = std::max(CavePath::step_max(), RiverPath::step_max());
|
int max_path_len = std::max(CavePath::step_max(), RiverPath::step_max());
|
||||||
radius = max_path_len / 2;
|
radius = max_path_len / 2;
|
||||||
r2 = radius * radius;
|
r2 = radius * radius;
|
||||||
@@ -647,10 +229,6 @@ void World::compute_required_chunks(
|
|||||||
for (int dz = -radius; dz <= radius; ++dz) {
|
for (int dz = -radius; dz <= radius; ++dz) {
|
||||||
if (dx * dx + dz * dz <= r2) {
|
if (dx * dx + dz * dz <= r2) {
|
||||||
ChunkPos pos{chunk_x + dx, chunk_z + dz};
|
ChunkPos pos{chunk_x + dx, chunk_z + dz};
|
||||||
auto it = required_chunks.find(pos);
|
|
||||||
if (it != required_chunks.end()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
temp_neighbor.emplace_back(pos, Chunk(*this, pos));
|
temp_neighbor.emplace_back(pos, Chunk(*this, pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -677,37 +255,71 @@ void World::sync_and_collect_missing_chunks(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::build_neighbor_context_for_new_chunks(
|
void World::submit_new_chunks() {
|
||||||
ConstChunkMap& new_chunks_neighbor, ChunkPtrUpdateList& affected_neighbor,
|
using enum ChunkLoadStyle;
|
||||||
const ChunkPairVector& new_chunks) {
|
std::lock_guard lock(m_new_chunk_mutex);
|
||||||
{
|
auto pool_ptr = m_gen_thread_pool.load();
|
||||||
std::lock_guard lk(m_chunks_mutex);
|
if (!pool_ptr) {
|
||||||
for (auto& [pos, chunk] : new_chunks) {
|
return;
|
||||||
for (auto& dir : CHUNK_DIR) {
|
}
|
||||||
auto it = m_chunks.find(pos + dir);
|
switch (m_chunk_load_style) {
|
||||||
if (it != m_chunks.end()) {
|
case RANDOM:
|
||||||
new_chunks_neighbor.insert({it->first, &(it->second)});
|
for (auto& [pos, task] : new_chunks) {
|
||||||
affected_neighbor.push_back({it->first, &(it->second)});
|
if (!task.future.valid()) {
|
||||||
}
|
task.future =
|
||||||
|
pool_ptr->enqueue([&task]() { task.chunk.gen_chunk(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CENTER: {
|
||||||
|
std::vector<std::pair<ChunkPos, PendingChunk*>> tasks;
|
||||||
|
for (auto& [pos, task] : new_chunks) {
|
||||||
|
if (!task.future.valid()) {
|
||||||
|
tasks.emplace_back(pos, &task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glm::vec3 player_pos;
|
||||||
|
sync_player_pos(player_pos);
|
||||||
|
auto dist2 = [player_pos](ChunkPos chunk_pos) {
|
||||||
|
ChunkPos player_chunk_pos =
|
||||||
|
get_chunk_pos(player_pos.x, player_pos.z);
|
||||||
|
float dx = player_chunk_pos.x - chunk_pos.x;
|
||||||
|
float dz = player_chunk_pos.z - chunk_pos.z;
|
||||||
|
return dx * dx + dz * dz;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::sort(tasks.begin(), tasks.end(),
|
||||||
|
[&dist2](const auto& a, const auto& b) {
|
||||||
|
return dist2(a.first) < dist2(b.first);
|
||||||
|
});
|
||||||
|
for (auto& [pos, task] : tasks) {
|
||||||
|
if (!task->future.valid()) {
|
||||||
|
task->future =
|
||||||
|
pool_ptr->enqueue([task]() { task->chunk.gen_chunk(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto& [pos, chunk] : new_chunks) {
|
|
||||||
new_chunks_neighbor.insert({pos, &chunk});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::build_neighbor_context_for_affected_neighbors(
|
void World::poll_finished_chunks() {
|
||||||
ChunkPtrUpdateList& affected_neighbor, ConstChunkMap& new_chunks_neighbor) {
|
m_new_finished_chunk.clear();
|
||||||
std::lock_guard lk(m_chunks_mutex);
|
std::lock_guard lock(m_new_chunk_mutex);
|
||||||
for (auto& [pos, chunk] : affected_neighbor) {
|
std::erase_if(
|
||||||
for (auto& dir : CHUNK_DIR) {
|
new_chunks, [&](std::pair<const ChunkPos, PendingChunk>& pair) {
|
||||||
auto it = m_chunks.find(pos + dir);
|
auto& pending = pair.second;
|
||||||
if (it != m_chunks.end()) {
|
if (!pending.future.valid()) {
|
||||||
new_chunks_neighbor.insert({it->first, &(it->second)});
|
return false;
|
||||||
}
|
}
|
||||||
}
|
if (pending.future.wait_for(0ms) != std::future_status::ready) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
pending.future.get();
|
||||||
|
|
||||||
|
m_new_finished_chunk.emplace_back(pair.first,
|
||||||
|
std::move(pending.chunk));
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
@@ -767,10 +379,12 @@ void World::serever_run(std::stop_token stoken) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void World::need_gen() {
|
void World::need_gen() {
|
||||||
|
|
||||||
if (!m_could_gen) {
|
if (!m_could_gen) {
|
||||||
Logger::warn("It is generating or consuming new chunks");
|
Logger::warn("It is generating or consuming new chunks");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_could_gen = false;
|
m_could_gen = false;
|
||||||
{
|
{
|
||||||
std::lock_guard lk(m_gen_player_pos_mutex);
|
std::lock_guard lk(m_gen_player_pos_mutex);
|
||||||
@@ -778,11 +392,12 @@ void World::need_gen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_need_gen_chunk = true;
|
m_need_gen_chunk = true;
|
||||||
|
|
||||||
m_gen_cv.notify_one();
|
m_gen_cv.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
int World::get_block(const glm::ivec3& block_pos) const {
|
int World::get_block(const glm::ivec3& block_pos) const {
|
||||||
auto [chunk_x, chunk_z] = chunk_pos(block_pos.x, block_pos.z);
|
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
||||||
std::lock_guard lk(m_chunks_mutex);
|
std::lock_guard lk(m_chunks_mutex);
|
||||||
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
||||||
|
|
||||||
@@ -800,7 +415,7 @@ int World::get_block(const glm::ivec3& block_pos) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool World::is_solid(const glm::ivec3& block_pos) const {
|
bool World::is_solid(const glm::ivec3& block_pos) const {
|
||||||
auto [chunk_x, chunk_z] = chunk_pos(block_pos.x, block_pos.z);
|
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
||||||
std::lock_guard lk(m_chunks_mutex);
|
std::lock_guard lk(m_chunks_mutex);
|
||||||
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
||||||
|
|
||||||
@@ -822,7 +437,7 @@ bool World::is_solid(const glm::ivec3& block_pos) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool World::can_pass_block(const glm::ivec3& block_pos) const {
|
bool World::can_pass_block(const glm::ivec3& block_pos) const {
|
||||||
auto [chunk_x, chunk_z] = chunk_pos(block_pos.x, block_pos.z);
|
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
||||||
std::lock_guard lk(m_chunks_mutex);
|
std::lock_guard lk(m_chunks_mutex);
|
||||||
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
||||||
|
|
||||||
@@ -840,21 +455,21 @@ bool World::can_pass_block(const glm::ivec3& block_pos) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BlockType World::get_block_tpye(const glm::ivec3& block_pos) const {
|
BlockType World::get_block_tpye(const glm::ivec3& block_pos) const {
|
||||||
auto [chunk_x, chunk_z] = chunk_pos(block_pos.x, block_pos.z);
|
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
||||||
std::lock_guard lk(m_chunks_mutex);
|
std::lock_guard lk(m_chunks_mutex);
|
||||||
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
||||||
|
|
||||||
if (it == m_chunks.end()) {
|
if (it == m_chunks.end()) {
|
||||||
Logger::error("Can't Find Block {} {} {}", block_pos.x, block_pos.y,
|
// Logger::error("Can't Find Block {} {} {}", block_pos.x, block_pos.y,
|
||||||
block_pos.z);
|
// block_pos.z);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const auto& chunk_blocks = it->second.get_chunk_blocks();
|
const auto& chunk_blocks = it->second.get_chunk_blocks();
|
||||||
auto [x, y, z] = Chunk::world_to_block(block_pos, {chunk_x, chunk_z});
|
auto [x, y, z] = Chunk::world_to_block(block_pos, {chunk_x, chunk_z});
|
||||||
if (x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_SIZE_Y ||
|
if (x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_SIZE_Y ||
|
||||||
z >= CHUNK_SIZE) {
|
z >= CHUNK_SIZE) {
|
||||||
Logger::error("Can't Find Block {} {} {}", block_pos.x, block_pos.y,
|
// Logger::error("Can't Find Block {} {} {}", block_pos.x, block_pos.y,
|
||||||
block_pos.z);
|
// block_pos.z);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return chunk_blocks[Chunk::index(x, y, z)];
|
return chunk_blocks[Chunk::index(x, y, z)];
|
||||||
@@ -867,7 +482,7 @@ void World::set_block(const glm::ivec3& block_pos, unsigned id) {
|
|||||||
world_y = block_pos.y;
|
world_y = block_pos.y;
|
||||||
world_z = block_pos.z;
|
world_z = block_pos.z;
|
||||||
|
|
||||||
auto [chunk_x, chunk_z] = chunk_pos(world_x, world_z);
|
auto [chunk_x, chunk_z] = get_chunk_pos(world_x, world_z);
|
||||||
std::lock_guard lk(m_chunks_mutex);
|
std::lock_guard lk(m_chunks_mutex);
|
||||||
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
||||||
|
|
||||||
@@ -890,7 +505,7 @@ void World::set_block(const glm::ivec3& block_pos, unsigned id) {
|
|||||||
for (const auto& dir : NEIGHBOR_DIRS) {
|
for (const auto& dir : NEIGHBOR_DIRS) {
|
||||||
glm::ivec3 neighbor = block_pos + dir;
|
glm::ivec3 neighbor = block_pos + dir;
|
||||||
|
|
||||||
auto [cx, cz] = chunk_pos(neighbor.x, neighbor.z);
|
auto [cx, cz] = get_chunk_pos(neighbor.x, neighbor.z);
|
||||||
auto it = m_chunks.find({cx, cz});
|
auto it = m_chunks.find({cx, cz});
|
||||||
if (it != m_chunks.end()) {
|
if (it != m_chunks.end()) {
|
||||||
it->second.mark_dirty();
|
it->second.mark_dirty();
|
||||||
@@ -918,16 +533,9 @@ void World::update(float delta_time) {
|
|||||||
m_pending_delete_vao.clear();
|
m_pending_delete_vao.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
poll_finished_chunks();
|
||||||
std::scoped_lock lk(m_chunks_mutex, m_new_chunk_queue_mutex);
|
|
||||||
m_new_chunk.clear();
|
|
||||||
for (auto& x : m_new_chunk_queue) {
|
|
||||||
m_new_chunk.emplace_back(std::move(x));
|
|
||||||
}
|
|
||||||
m_new_chunk_queue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& x : m_new_chunk) {
|
for (auto& x : m_new_finished_chunk) {
|
||||||
x.second.upload_to_gpu();
|
x.second.upload_to_gpu();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -936,7 +544,7 @@ void World::update(float delta_time) {
|
|||||||
std::lock_guard lk(m_chunks_mutex);
|
std::lock_guard lk(m_chunks_mutex);
|
||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
|
|
||||||
for (auto& x : m_new_chunk) {
|
for (auto& x : m_new_finished_chunk) {
|
||||||
m_chunks.insert_or_assign(x.first, std::move(x.second));
|
m_chunks.insert_or_assign(x.first, std::move(x.second));
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
}
|
||||||
@@ -1011,9 +619,9 @@ void World::rebuild_world() {
|
|||||||
m_cave_carcer.reload(ChunkGenerator::seed());
|
m_cave_carcer.reload(ChunkGenerator::seed());
|
||||||
m_river_worm.reload(ChunkGenerator::seed());
|
m_river_worm.reload(ChunkGenerator::seed());
|
||||||
{
|
{
|
||||||
std::scoped_lock lk(m_chunks_mutex, m_new_chunk_queue_mutex);
|
std::scoped_lock lk(m_chunks_mutex);
|
||||||
m_chunks.clear();
|
m_chunks.clear();
|
||||||
m_new_chunk_queue.clear();
|
m_new_finished_chunk.clear();
|
||||||
}
|
}
|
||||||
m_could_gen = true;
|
m_could_gen = true;
|
||||||
ChunkGenerator::reload();
|
ChunkGenerator::reload();
|
||||||
@@ -1023,20 +631,6 @@ void World::rebuild_world() {
|
|||||||
m_is_rebuilding = false;
|
m_is_rebuilding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float World::chunk_gen_fraction() const { return m_chunk_gen_fraction.load(); }
|
|
||||||
|
|
||||||
int World::rendering_distance() const { return m_rendering_distance.load(); }
|
|
||||||
|
|
||||||
void World::rendering_distance(int rendering_distance) {
|
|
||||||
m_rendering_distance = rendering_distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
CaveCarver& World::cave_carcer() { return m_cave_carcer; }
|
|
||||||
RiverWorm& World::river_worm() { return m_river_worm; }
|
|
||||||
std::vector<glm::vec4>& World::planes() { return m_planes; }
|
|
||||||
std::vector<ChunkRenderSnapshot>& World::render_snapshots() {
|
|
||||||
return m_render_snapshots;
|
|
||||||
};
|
|
||||||
/*
|
/*
|
||||||
glm::vec3 World::sunlight_dir() const {
|
glm::vec3 World::sunlight_dir() const {
|
||||||
float t = static_cast<float>(m_day_tick) / DAY_TIME;
|
float t = static_cast<float>(m_day_tick) / DAY_TIME;
|
||||||
@@ -1071,6 +665,21 @@ glm::vec3 World::sunlight_dir() const {
|
|||||||
return glm::normalize(-dir);
|
return glm::normalize(-dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float World::chunk_gen_fraction() const { return m_chunk_gen_fraction.load(); }
|
||||||
|
|
||||||
|
int World::rendering_distance() const { return m_rendering_distance.load(); }
|
||||||
|
|
||||||
|
void World::rendering_distance(int rendering_distance) {
|
||||||
|
m_rendering_distance = rendering_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
CaveCarver& World::cave_carcer() { return m_cave_carcer; }
|
||||||
|
RiverWorm& World::river_worm() { return m_river_worm; }
|
||||||
|
std::vector<glm::vec4>& World::planes() { return m_planes; }
|
||||||
|
std::vector<ChunkRenderSnapshot>& World::render_snapshots() {
|
||||||
|
return m_render_snapshots;
|
||||||
|
};
|
||||||
|
|
||||||
TickType World::game_tick() const { return m_game_ticks.load(); }
|
TickType World::game_tick() const { return m_game_ticks.load(); }
|
||||||
TickType World::day_tick() const { return m_day_tick.load(); }
|
TickType World::day_tick() const { return m_day_tick.load(); }
|
||||||
void World::day_tick(TickType tick) {
|
void World::day_tick(TickType tick) {
|
||||||
@@ -1082,4 +691,38 @@ void World::per_tick_time(int ms) { m_per_tick_time = ms; }
|
|||||||
|
|
||||||
bool World::is_tick_running() const { return m_tick_running.load(); }
|
bool World::is_tick_running() const { return m_tick_running.load(); }
|
||||||
void World::tick_running(bool run) { m_tick_running = run; }
|
void World::tick_running(bool run) { m_tick_running = run; }
|
||||||
|
int World::pool_threads() const { return m_pool_threads.load(); }
|
||||||
|
int World::max_threads() const { return m_max_threads.load(); }
|
||||||
|
void World::change_pool_threads(int threads) {
|
||||||
|
m_max_threads = std::thread::hardware_concurrency();
|
||||||
|
if (m_max_threads < 1) {
|
||||||
|
Logger::warn("Can't Get Max Support Threads, Set Max Threads to 4");
|
||||||
|
m_max_threads = 4;
|
||||||
|
}
|
||||||
|
int used_thread = std::clamp(threads, 1, m_max_threads.load());
|
||||||
|
Logger::info("Create New Thread Pool Use {} Threads", used_thread);
|
||||||
|
m_gen_thread_pool.store(std::make_shared<ThreadPool>(used_thread));
|
||||||
|
m_pool_threads = used_thread;
|
||||||
|
}
|
||||||
|
int World::chunk_load_style() const {
|
||||||
|
return std::to_underlying(m_chunk_load_style.load());
|
||||||
|
}
|
||||||
|
void World::set_chunk_load_style(int id) {
|
||||||
|
using enum ChunkLoadStyle;
|
||||||
|
using std::to_underlying;
|
||||||
|
switch (m_chunk_load_style.load()) {
|
||||||
|
case RANDOM:
|
||||||
|
if (id == to_underlying(RANDOM)) {
|
||||||
|
m_chunk_load_style = RANDOM;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case CENTER:
|
||||||
|
if (id == to_underlying(CENTER)) {
|
||||||
|
m_chunk_load_style = CENTER;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Logger::error("Can,t Find Chunk Load Style Id {}, Nothing Will Do", id);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -419,7 +419,7 @@ void Renderer::render_ui() {
|
|||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
shader.set_loc("mv_matrix", m_ui_m_matrix);
|
shader.set_loc("m_matrix", m_ui_m_matrix);
|
||||||
shader.set_loc("proj_matrix", m_ui_proj);
|
shader.set_loc("proj_matrix", m_ui_proj);
|
||||||
|
|
||||||
glBindVertexArray(m_vao[3]);
|
glBindVertexArray(m_vao[3]);
|
||||||
@@ -719,7 +719,6 @@ void Renderer::render_world() {
|
|||||||
normal_block_shader.set_loc("sunlightDir", light_dir_view);
|
normal_block_shader.set_loc("sunlightDir", light_dir_view);
|
||||||
normal_block_shader.set_loc("shadowMode", m_shadow_mode);
|
normal_block_shader.set_loc("shadowMode", m_shadow_mode);
|
||||||
normal_block_shader.set_loc("shader_on", m_shader_on);
|
normal_block_shader.set_loc("shader_on", m_shader_on);
|
||||||
normal_block_shader.set_loc("texelsPerUnit", texels_per_unit);
|
|
||||||
normal_block_shader.set_loc("lightSizeUV",
|
normal_block_shader.set_loc("lightSizeUV",
|
||||||
static_cast<float>(m_light_size_uv));
|
static_cast<float>(m_light_size_uv));
|
||||||
normal_block_shader.set_loc("minRadius", m_min_radius);
|
normal_block_shader.set_loc("minRadius", m_min_radius);
|
||||||
@@ -728,6 +727,8 @@ void Renderer::render_world() {
|
|||||||
normal_block_shader.set_loc("specularStrength", m_specular_strength);
|
normal_block_shader.set_loc("specularStrength", m_specular_strength);
|
||||||
normal_block_shader.set_loc("cameraPos", m_camera.get_camera_pos());
|
normal_block_shader.set_loc("cameraPos", m_camera.get_camera_pos());
|
||||||
normal_block_shader.set_loc("flipY", m_flip_y);
|
normal_block_shader.set_loc("flipY", m_flip_y);
|
||||||
|
normal_block_shader.set_loc("renderDistance", m_world.rendering_distance());
|
||||||
|
normal_block_shader.set_loc("skyColor", m_sky_uniform.sky_top);
|
||||||
m_mvp_mat = m_p_mat * m_mv_mat;
|
m_mvp_mat = m_p_mat * m_mv_mat;
|
||||||
|
|
||||||
auto& m_planes = m_world.planes();
|
auto& m_planes = m_world.planes();
|
||||||
@@ -818,7 +819,6 @@ void Renderer::render_world() {
|
|||||||
accum_shader.set_loc("mv_matrix", m_mv_mat);
|
accum_shader.set_loc("mv_matrix", m_mv_mat);
|
||||||
accum_shader.set_loc("proj_matrix", m_p_mat);
|
accum_shader.set_loc("proj_matrix", m_p_mat);
|
||||||
accum_shader.set_loc("norm_matrix", m_norm_mat);
|
accum_shader.set_loc("norm_matrix", m_norm_mat);
|
||||||
accum_shader.set_loc("lightSpaceMatrix", light_space_matrix);
|
|
||||||
accum_shader.set_loc("ambientStrength", m_ambient_strength);
|
accum_shader.set_loc("ambientStrength", m_ambient_strength);
|
||||||
accum_shader.set_loc("sunlightColor",
|
accum_shader.set_loc("sunlightColor",
|
||||||
m_parallel_light.directional_light_color);
|
m_parallel_light.directional_light_color);
|
||||||
@@ -827,14 +827,13 @@ void Renderer::render_world() {
|
|||||||
accum_shader.set_loc("sunlightDir", light_dir_view);
|
accum_shader.set_loc("sunlightDir", light_dir_view);
|
||||||
accum_shader.set_loc("shader_on", m_shader_on);
|
accum_shader.set_loc("shader_on", m_shader_on);
|
||||||
accum_shader.set_loc("specularStrength", m_specular_strength);
|
accum_shader.set_loc("specularStrength", m_specular_strength);
|
||||||
accum_shader.set_loc("cameraPos", m_camera.get_camera_pos());
|
|
||||||
};
|
};
|
||||||
|
|
||||||
auto& accum_shader = get_shader("accum");
|
auto& accum_shader = get_shader("accum");
|
||||||
accum_shader.use();
|
accum_shader.use();
|
||||||
|
|
||||||
set_accum_loc(accum_shader);
|
set_accum_loc(accum_shader);
|
||||||
|
accum_shader.set_loc("cameraPos", m_camera.get_camera_pos());
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_manager.get_texture_array());
|
glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_manager.get_texture_array());
|
||||||
for (const auto& snapshot : m_render_snapshots) {
|
for (const auto& snapshot : m_render_snapshots) {
|
||||||
|
|||||||
Reference in New Issue
Block a user