diff --git a/CMakeLists.txt b/CMakeLists.txt index 9145341..cbfc917 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,7 @@ add_executable(${PROJECT_NAME} src/gameplay/river_worm.cpp src/gameplay/river_path.cpp src/block.cpp + src/gameplay/vertex_data.cpp ) if(CMAKE_BUILD_TYPE STREQUAL "Debug") diff --git a/include/Cubed/gameplay/chunk.hpp b/include/Cubed/gameplay/chunk.hpp index 204adcc..0f51b10 100644 --- a/include/Cubed/gameplay/chunk.hpp +++ b/include/Cubed/gameplay/chunk.hpp @@ -4,7 +4,7 @@ #include "Cubed/gameplay/block.hpp" #include "Cubed/gameplay/chunk_generator.hpp" #include "Cubed/gameplay/chunk_pos.hpp" -#include "Cubed/primitive_data.hpp" +#include "Cubed/gameplay/vertex_data.hpp" #include #include @@ -21,9 +21,6 @@ private: std::atomic m_dirty{false}; std::atomic m_need_upload{true}; std::atomic m_is_on_gen_vertex_data{false}; - std::atomic m_normal_vertices_sum = 0; - std::atomic m_cross_vertices_sum = 0; - std::atomic m_transparent_vertices_sum = 0; std::atomic m_biome = BiomeType::PLAIN; std::mutex m_vertexs_data_mutex; @@ -34,12 +31,13 @@ private: HeightMapArray m_heightmap; // the index is a array of block id std::vector m_blocks; - GLuint m_normal_vbo = 0; - GLuint m_cross_plane_vbo = 0; - GLuint m_transparent_normal_vbo = 0; - std::vector m_normal_vertices; - std::vector m_cross_plane_vertices; - std::vector m_transparent_normal_vertices; + + /* + 0 - normal + 1 - cross_plane + 2 - transparent + */ + std::vector m_vertex_data; float frequency = 0.01f; float height = 80; unsigned m_seed = 0; diff --git a/include/Cubed/gameplay/vertex_data.hpp b/include/Cubed/gameplay/vertex_data.hpp new file mode 100644 index 0000000..9134197 --- /dev/null +++ b/include/Cubed/gameplay/vertex_data.hpp @@ -0,0 +1,24 @@ +#pragma once +#include "Cubed/primitive_data.hpp" + +#include +#include +#include +namespace Cubed { +class World; +struct VertexData { + std::vector m_vertices; + GLuint m_vbo = 0; + std::atomic m_sum{0}; + World& m_world; + VertexData(World& world); + ~VertexData(); + VertexData(const VertexData&) = delete; + VertexData(VertexData&&) noexcept; + VertexData& operator=(const VertexData&) = delete; + VertexData& operator=(VertexData&&) noexcept; + + void upload(); + void update_sum(); +}; +} // namespace Cubed diff --git a/src/gameplay/chunk.cpp b/src/gameplay/chunk.cpp index 6f71f58..ed3b77a 100644 --- a/src/gameplay/chunk.cpp +++ b/src/gameplay/chunk.cpp @@ -9,65 +9,36 @@ namespace Cubed { Chunk::Chunk(World& world, ChunkPos chunk_pos) - : m_chunk_pos(chunk_pos), m_world(world) {} - -Chunk::~Chunk() { - if (m_normal_vbo != 0) { - m_world.push_delete_vbo(m_normal_vbo); - } - if (m_cross_plane_vbo != 0) { - m_world.push_delete_vbo(m_cross_plane_vbo); - } - if (m_transparent_normal_vbo != 0) { - m_world.push_delete_vbo(m_transparent_normal_vbo); + : m_chunk_pos(chunk_pos), m_world(world) { + for (int i = 0; i < 3; i++) { + m_vertex_data.emplace_back(m_world); } } +Chunk::~Chunk() {} + Chunk::Chunk(Chunk&& other) noexcept : m_dirty(other.is_dirty()), m_need_upload(other.m_need_upload.load()), m_is_on_gen_vertex_data(other.m_is_on_gen_vertex_data.load()), - m_normal_vertices_sum(other.m_normal_vertices_sum.load()), - m_cross_vertices_sum(other.m_cross_vertices_sum.load()), - m_transparent_vertices_sum(other.m_transparent_vertices_sum.load()), m_biome(other.m_biome.load()), m_chunk_pos(std::move(other.m_chunk_pos)), m_world(other.m_world), m_heightmap(std::move(other.m_heightmap)), - m_blocks(std::move(other.m_blocks)), m_normal_vbo(other.m_normal_vbo), - m_cross_plane_vbo(other.m_cross_plane_vbo), - m_transparent_normal_vbo(other.m_transparent_normal_vbo), - m_normal_vertices(std::move(other.m_normal_vertices)), - m_cross_plane_vertices(std::move(other.m_cross_plane_vertices)), - m_transparent_normal_vertices( - std::move(other.m_transparent_normal_vertices)), - m_seed(other.m_seed), m_conditions(other.m_conditions) { - other.m_normal_vbo = 0; - other.m_cross_plane_vbo = 0; - other.m_transparent_normal_vbo = 0; -} + m_blocks(std::move(other.m_blocks)), + m_vertex_data(std::move(other.m_vertex_data)), m_seed(other.m_seed), + m_conditions(other.m_conditions) {} Chunk& Chunk::operator=(Chunk&& other) noexcept { // Logger::info("other Chunk pos {} {} in Chunk& Chunk::operator=(Chunk&& // other) this {}", other.m_chunk_pos.x, other.m_chunk_pos.z, // static_cast(&other)); - m_normal_vbo = other.m_normal_vbo; - other.m_normal_vbo = 0; - m_cross_plane_vbo = other.m_cross_plane_vbo; - m_transparent_normal_vbo = other.m_transparent_normal_vbo; - other.m_transparent_normal_vbo = 0; - other.m_cross_plane_vbo = 0; + m_chunk_pos = std::move(other.m_chunk_pos); m_heightmap = std::move(other.m_heightmap); m_blocks = std::move(other.m_blocks); m_dirty = other.is_dirty(); - m_normal_vertices = std::move(other.m_normal_vertices); - m_cross_plane_vertices = std::move(other.m_cross_plane_vertices); - m_transparent_normal_vertices = - std::move(other.m_transparent_normal_vertices); + m_vertex_data = std::move(other.m_vertex_data); m_biome = other.m_biome.load(); m_is_on_gen_vertex_data = other.m_is_on_gen_vertex_data.load(); m_need_upload = other.m_need_upload.load(); - m_normal_vertices_sum = other.m_normal_vertices_sum.load(); - m_cross_vertices_sum = other.m_cross_vertices_sum.load(); - m_transparent_vertices_sum = other.m_transparent_vertices_sum.load(); m_seed = other.m_seed; m_conditions = other.m_conditions; return *this; @@ -139,29 +110,37 @@ void Chunk::gen_vertex_data( } m_is_on_gen_vertex_data = true; std::lock_guard lk(m_vertexs_data_mutex); + + for (auto& data : m_vertex_data) { + data.m_vertices.clear(); + } + gen_normal_vertices(neighbor_block); gen_cross_plane_vertices(); + for (auto& data : m_vertex_data) { + data.update_sum(); + } m_need_upload = true; m_is_on_gen_vertex_data = false; } -GLuint Chunk::get_normal_vbo() const { return m_normal_vbo; } +GLuint Chunk::get_normal_vbo() const { return m_vertex_data[0].m_vbo; } size_t Chunk::get_normal_vertices_sum() const { - if (m_normal_vertices_sum == 0) { + if (m_vertex_data[0].m_sum == 0) { Logger::warn("m_normal_vertices_sum is 0"); } - return m_normal_vertices_sum.load(); + return m_vertex_data[0].m_sum.load(); } -GLuint Chunk::get_cross_vbo() const { return m_cross_plane_vbo; } +GLuint Chunk::get_cross_vbo() const { return m_vertex_data[1].m_vbo; } size_t Chunk::get_cross_vertices_sum() const { - return m_cross_vertices_sum.load(); + return m_vertex_data[1].m_sum.load(); } -GLuint Chunk::get_transparent_vbo() const { return m_transparent_normal_vbo; } +GLuint Chunk::get_transparent_vbo() const { return m_vertex_data[2].m_vbo; } size_t Chunk::get_transparent_vertices_sum() const { - return m_transparent_vertices_sum.load(); + return m_vertex_data[2].m_sum.load(); } void Chunk::gen_phase_one() { @@ -235,33 +214,12 @@ void Chunk::upload_to_gpu() { ASSERT(is_need_upload()); - if (m_normal_vbo == 0) { - glGenBuffers(1, &m_normal_vbo); + std::lock_guard lk(m_vertexs_data_mutex); + + for (auto& data : m_vertex_data) { + data.upload(); } - std::lock_guard lk(m_vertexs_data_mutex); - glBindBuffer(GL_ARRAY_BUFFER, m_normal_vbo); - glBufferData(GL_ARRAY_BUFFER, m_normal_vertices.size() * sizeof(Vertex), - m_normal_vertices.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - if (m_cross_plane_vertices.size() != 0) { - if (m_cross_plane_vbo == 0) { - glGenBuffers(1, &m_cross_plane_vbo); - } - glBindBuffer(GL_ARRAY_BUFFER, m_cross_plane_vbo); - glBufferData(GL_ARRAY_BUFFER, - m_cross_plane_vertices.size() * sizeof(Vertex), - m_cross_plane_vertices.data(), GL_DYNAMIC_DRAW); - } - if (m_transparent_normal_vertices.size() != 0) { - if (m_transparent_normal_vbo == 0) { - glGenBuffers(1, &m_transparent_normal_vbo); - } - glBindBuffer(GL_ARRAY_BUFFER, m_transparent_normal_vbo); - glBufferData(GL_ARRAY_BUFFER, - m_transparent_normal_vertices.size() * sizeof(Vertex), - m_transparent_normal_vertices.data(), GL_DYNAMIC_DRAW); - } // after fininshed it, can use clear_dirty(); m_need_upload = false; @@ -302,8 +260,6 @@ BiomeConditions& Chunk::conditions() { return m_conditions; } void Chunk::gen_normal_vertices( const std::array*, 4>& neighbor_block) { - m_normal_vertices.clear(); - m_transparent_normal_vertices.clear(); static const glm::ivec3 DIR[6] = {{0, 0, 1}, {1, 0, 0}, {0, 0, -1}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}}; @@ -410,22 +366,18 @@ void Chunk::gen_normal_vertices( }; if (BlockManager::is_transparent(cur_id)) { - m_transparent_normal_vertices.emplace_back(vex); + m_vertex_data[2].m_vertices.emplace_back(vex); } else { - m_normal_vertices.emplace_back(vex); + m_vertex_data[0].m_vertices.emplace_back(vex); } } } } } } - m_normal_vertices_sum = m_normal_vertices.size(); - m_transparent_vertices_sum = m_transparent_normal_vertices.size(); } void Chunk::gen_cross_plane_vertices() { - m_cross_plane_vertices.clear(); - for (int x = 0; x < SIZE_X; x++) { for (int y = 0; y < SIZE_Y; y++) { for (int z = 0; z < SIZE_Z; z++) { @@ -451,13 +403,12 @@ void Chunk::gen_cross_plane_vertices() { BlockManager::cross_plane_index(id)) }; - m_cross_plane_vertices.emplace_back(vex); + m_vertex_data[1].m_vertices.emplace_back(vex); } } } } } - m_cross_vertices_sum = m_cross_plane_vertices.size(); // Logger::info("Cross Sum {}", m_cross_vertices_sum.load()); } diff --git a/src/gameplay/vertex_data.cpp b/src/gameplay/vertex_data.cpp new file mode 100644 index 0000000..fd796eb --- /dev/null +++ b/src/gameplay/vertex_data.cpp @@ -0,0 +1,39 @@ +#include "Cubed/gameplay/vertex_data.hpp" + +#include "Cubed/gameplay/world.hpp" + +namespace Cubed { +VertexData::VertexData(World& world) : m_world(world) {} +VertexData::~VertexData() { + if (m_vbo != 0) { + m_world.push_delete_vbo(m_vbo); + } +} +VertexData::VertexData(VertexData&& o) noexcept + : m_vertices(std::move(o.m_vertices)), m_vbo(o.m_vbo), + m_sum(o.m_sum.load()), m_world(o.m_world) { + o.m_vbo = 0; + o.m_sum = 0; +} +VertexData& VertexData::operator=(VertexData&& o) noexcept { + m_vbo = o.m_vbo; + o.m_vbo = 0; + m_sum = o.m_sum.load(); + o.m_sum = 0; + m_vertices = std::move(o.m_vertices); + return *this; +} +void VertexData::upload() { + if (m_vertices.size() == 0) { + return; + } + if (m_vbo == 0) { + glGenBuffers(1, &m_vbo); + } + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(Vertex), + m_vertices.data(), GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} +void VertexData::update_sum() { m_sum = m_vertices.size(); } +} // namespace Cubed \ No newline at end of file