mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-06-18 00:27:02 +08:00
refactor(gameplay): encapsulate per-type vertex data into VertexData struct
This commit is contained in:
@@ -123,6 +123,7 @@ add_executable(${PROJECT_NAME}
|
|||||||
src/gameplay/river_worm.cpp
|
src/gameplay/river_worm.cpp
|
||||||
src/gameplay/river_path.cpp
|
src/gameplay/river_path.cpp
|
||||||
src/block.cpp
|
src/block.cpp
|
||||||
|
src/gameplay/vertex_data.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "Cubed/gameplay/block.hpp"
|
#include "Cubed/gameplay/block.hpp"
|
||||||
#include "Cubed/gameplay/chunk_generator.hpp"
|
#include "Cubed/gameplay/chunk_generator.hpp"
|
||||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||||
#include "Cubed/primitive_data.hpp"
|
#include "Cubed/gameplay/vertex_data.hpp"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
@@ -21,9 +21,6 @@ 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<size_t> m_normal_vertices_sum = 0;
|
|
||||||
std::atomic<size_t> m_cross_vertices_sum = 0;
|
|
||||||
std::atomic<size_t> m_transparent_vertices_sum = 0;
|
|
||||||
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;
|
||||||
|
|
||||||
@@ -34,12 +31,13 @@ private:
|
|||||||
HeightMapArray m_heightmap;
|
HeightMapArray m_heightmap;
|
||||||
// the index is a array of block id
|
// the index is a array of block id
|
||||||
std::vector<BlockType> m_blocks;
|
std::vector<BlockType> m_blocks;
|
||||||
GLuint m_normal_vbo = 0;
|
|
||||||
GLuint m_cross_plane_vbo = 0;
|
/*
|
||||||
GLuint m_transparent_normal_vbo = 0;
|
0 - normal
|
||||||
std::vector<Vertex> m_normal_vertices;
|
1 - cross_plane
|
||||||
std::vector<Vertex> m_cross_plane_vertices;
|
2 - transparent
|
||||||
std::vector<Vertex> m_transparent_normal_vertices;
|
*/
|
||||||
|
std::vector<VertexData> m_vertex_data;
|
||||||
float frequency = 0.01f;
|
float frequency = 0.01f;
|
||||||
float height = 80;
|
float height = 80;
|
||||||
unsigned m_seed = 0;
|
unsigned m_seed = 0;
|
||||||
|
|||||||
24
include/Cubed/gameplay/vertex_data.hpp
Normal file
24
include/Cubed/gameplay/vertex_data.hpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Cubed/primitive_data.hpp"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <vector>
|
||||||
|
namespace Cubed {
|
||||||
|
class World;
|
||||||
|
struct VertexData {
|
||||||
|
std::vector<Vertex> m_vertices;
|
||||||
|
GLuint m_vbo = 0;
|
||||||
|
std::atomic<std::size_t> 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
|
||||||
@@ -9,65 +9,36 @@
|
|||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
Chunk::Chunk(World& world, ChunkPos chunk_pos)
|
Chunk::Chunk(World& world, ChunkPos chunk_pos)
|
||||||
: m_chunk_pos(chunk_pos), m_world(world) {}
|
: m_chunk_pos(chunk_pos), m_world(world) {
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
Chunk::~Chunk() {
|
m_vertex_data.emplace_back(m_world);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Chunk::~Chunk() {}
|
||||||
|
|
||||||
Chunk::Chunk(Chunk&& other) noexcept
|
Chunk::Chunk(Chunk&& other) noexcept
|
||||||
: m_dirty(other.is_dirty()), m_need_upload(other.m_need_upload.load()),
|
: 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_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_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_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_blocks(std::move(other.m_blocks)),
|
||||||
m_cross_plane_vbo(other.m_cross_plane_vbo),
|
m_vertex_data(std::move(other.m_vertex_data)), m_seed(other.m_seed),
|
||||||
m_transparent_normal_vbo(other.m_transparent_normal_vbo),
|
m_conditions(other.m_conditions) {}
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Chunk& Chunk::operator=(Chunk&& other) noexcept {
|
Chunk& Chunk::operator=(Chunk&& other) noexcept {
|
||||||
// Logger::info("other Chunk pos {} {} in Chunk& Chunk::operator=(Chunk&&
|
// Logger::info("other Chunk pos {} {} in Chunk& Chunk::operator=(Chunk&&
|
||||||
// other) this {}", other.m_chunk_pos.x, other.m_chunk_pos.z,
|
// other) this {}", other.m_chunk_pos.x, other.m_chunk_pos.z,
|
||||||
// static_cast<const void*>(&other));
|
// static_cast<const void*>(&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_chunk_pos = std::move(other.m_chunk_pos);
|
||||||
m_heightmap = std::move(other.m_heightmap);
|
m_heightmap = std::move(other.m_heightmap);
|
||||||
m_blocks = std::move(other.m_blocks);
|
m_blocks = std::move(other.m_blocks);
|
||||||
m_dirty = other.is_dirty();
|
m_dirty = other.is_dirty();
|
||||||
m_normal_vertices = std::move(other.m_normal_vertices);
|
m_vertex_data = std::move(other.m_vertex_data);
|
||||||
m_cross_plane_vertices = std::move(other.m_cross_plane_vertices);
|
|
||||||
m_transparent_normal_vertices =
|
|
||||||
std::move(other.m_transparent_normal_vertices);
|
|
||||||
m_biome = other.m_biome.load();
|
m_biome = other.m_biome.load();
|
||||||
m_is_on_gen_vertex_data = other.m_is_on_gen_vertex_data.load();
|
m_is_on_gen_vertex_data = other.m_is_on_gen_vertex_data.load();
|
||||||
m_need_upload = other.m_need_upload.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_seed = other.m_seed;
|
||||||
m_conditions = other.m_conditions;
|
m_conditions = other.m_conditions;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -139,29 +110,37 @@ void Chunk::gen_vertex_data(
|
|||||||
}
|
}
|
||||||
m_is_on_gen_vertex_data = true;
|
m_is_on_gen_vertex_data = true;
|
||||||
std::lock_guard lk(m_vertexs_data_mutex);
|
std::lock_guard lk(m_vertexs_data_mutex);
|
||||||
|
|
||||||
|
for (auto& data : m_vertex_data) {
|
||||||
|
data.m_vertices.clear();
|
||||||
|
}
|
||||||
|
|
||||||
gen_normal_vertices(neighbor_block);
|
gen_normal_vertices(neighbor_block);
|
||||||
gen_cross_plane_vertices();
|
gen_cross_plane_vertices();
|
||||||
|
for (auto& data : m_vertex_data) {
|
||||||
|
data.update_sum();
|
||||||
|
}
|
||||||
m_need_upload = true;
|
m_need_upload = true;
|
||||||
m_is_on_gen_vertex_data = false;
|
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 {
|
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");
|
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 {
|
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 {
|
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() {
|
void Chunk::gen_phase_one() {
|
||||||
@@ -235,33 +214,12 @@ void Chunk::upload_to_gpu() {
|
|||||||
|
|
||||||
ASSERT(is_need_upload());
|
ASSERT(is_need_upload());
|
||||||
|
|
||||||
if (m_normal_vbo == 0) {
|
std::lock_guard lk(m_vertexs_data_mutex);
|
||||||
glGenBuffers(1, &m_normal_vbo);
|
|
||||||
|
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
|
// after fininshed it, can use
|
||||||
clear_dirty();
|
clear_dirty();
|
||||||
m_need_upload = false;
|
m_need_upload = false;
|
||||||
@@ -302,8 +260,6 @@ BiomeConditions& Chunk::conditions() { return m_conditions; }
|
|||||||
|
|
||||||
void Chunk::gen_normal_vertices(
|
void Chunk::gen_normal_vertices(
|
||||||
const std::array<const std::vector<BlockType>*, 4>& neighbor_block) {
|
const std::array<const std::vector<BlockType>*, 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},
|
static const glm::ivec3 DIR[6] = {{0, 0, 1}, {1, 0, 0}, {0, 0, -1},
|
||||||
{-1, 0, 0}, {0, 1, 0}, {0, -1, 0}};
|
{-1, 0, 0}, {0, 1, 0}, {0, -1, 0}};
|
||||||
|
|
||||||
@@ -410,22 +366,18 @@ void Chunk::gen_normal_vertices(
|
|||||||
|
|
||||||
};
|
};
|
||||||
if (BlockManager::is_transparent(cur_id)) {
|
if (BlockManager::is_transparent(cur_id)) {
|
||||||
m_transparent_normal_vertices.emplace_back(vex);
|
m_vertex_data[2].m_vertices.emplace_back(vex);
|
||||||
} else {
|
} 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() {
|
void Chunk::gen_cross_plane_vertices() {
|
||||||
|
|
||||||
m_cross_plane_vertices.clear();
|
|
||||||
|
|
||||||
for (int x = 0; x < SIZE_X; x++) {
|
for (int x = 0; x < SIZE_X; x++) {
|
||||||
for (int y = 0; y < SIZE_Y; y++) {
|
for (int y = 0; y < SIZE_Y; y++) {
|
||||||
for (int z = 0; z < SIZE_Z; z++) {
|
for (int z = 0; z < SIZE_Z; z++) {
|
||||||
@@ -451,13 +403,12 @@ void Chunk::gen_cross_plane_vertices() {
|
|||||||
BlockManager::cross_plane_index(id))
|
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());
|
// Logger::info("Cross Sum {}", m_cross_vertices_sum.load());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
39
src/gameplay/vertex_data.cpp
Normal file
39
src/gameplay/vertex_data.cpp
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user