mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-06-17 16:17:02 +08:00
feat(rendering): separate transparent blocks into discard and blend modes
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
id = 0
|
id = 0
|
||||||
|
is_blend = false
|
||||||
is_cross_plane = false
|
is_cross_plane = false
|
||||||
|
is_discard = true
|
||||||
is_gas = true
|
is_gas = true
|
||||||
is_liquid = false
|
is_liquid = false
|
||||||
is_passable = true
|
is_passable = true
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
id = 2
|
id = 2
|
||||||
|
is_blend = false
|
||||||
is_cross_plane = false
|
is_cross_plane = false
|
||||||
|
is_discard = false
|
||||||
is_gas = false
|
is_gas = false
|
||||||
is_liquid = false
|
is_liquid = false
|
||||||
is_passable = false
|
is_passable = false
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
id = 9
|
id = 9
|
||||||
|
is_blend = false
|
||||||
is_cross_plane = true
|
is_cross_plane = true
|
||||||
|
is_discard = true
|
||||||
is_gas = false
|
is_gas = false
|
||||||
is_liquid = false
|
is_liquid = false
|
||||||
is_passable = true
|
is_passable = true
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
id = 1
|
id = 1
|
||||||
|
is_blend = false
|
||||||
is_cross_plane = false
|
is_cross_plane = false
|
||||||
|
is_discard = false
|
||||||
is_gas = false
|
is_gas = false
|
||||||
is_liquid = false
|
is_liquid = false
|
||||||
is_passable = false
|
is_passable = false
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
id = 6
|
id = 6
|
||||||
|
is_blend = false
|
||||||
is_cross_plane = false
|
is_cross_plane = false
|
||||||
|
is_discard = true
|
||||||
is_gas = false
|
is_gas = false
|
||||||
is_liquid = false
|
is_liquid = false
|
||||||
is_passable = false
|
is_passable = false
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
id = 5
|
id = 5
|
||||||
|
is_blend = false
|
||||||
is_cross_plane = false
|
is_cross_plane = false
|
||||||
|
is_discard = false
|
||||||
is_gas = false
|
is_gas = false
|
||||||
is_liquid = false
|
is_liquid = false
|
||||||
is_passable = false
|
is_passable = false
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
id = 4
|
id = 4
|
||||||
|
is_blend = false
|
||||||
is_cross_plane = false
|
is_cross_plane = false
|
||||||
|
is_discard = false
|
||||||
is_gas = false
|
is_gas = false
|
||||||
is_liquid = false
|
is_liquid = false
|
||||||
is_passable = false
|
is_passable = false
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
id = 8
|
id = 8
|
||||||
|
is_blend = false
|
||||||
is_cross_plane = false
|
is_cross_plane = false
|
||||||
|
is_discard = false
|
||||||
is_gas = false
|
is_gas = false
|
||||||
is_liquid = false
|
is_liquid = false
|
||||||
is_passable = false
|
is_passable = false
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
id = 3
|
id = 3
|
||||||
|
is_blend = false
|
||||||
is_cross_plane = false
|
is_cross_plane = false
|
||||||
|
is_discard = false
|
||||||
is_gas = false
|
is_gas = false
|
||||||
is_liquid = false
|
is_liquid = false
|
||||||
is_passable = false
|
is_passable = false
|
||||||
|
|||||||
@@ -5,3 +5,5 @@ is_gas = false
|
|||||||
is_passable = false
|
is_passable = false
|
||||||
is_cross_plane = false
|
is_cross_plane = false
|
||||||
is_transparent = false
|
is_transparent = false
|
||||||
|
is_discard = false
|
||||||
|
is_blend = false
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
id = 7
|
id = 7
|
||||||
|
is_blend = true
|
||||||
is_cross_plane = false
|
is_cross_plane = false
|
||||||
|
is_discard = false
|
||||||
is_gas = false
|
is_gas = false
|
||||||
is_liquid = true
|
is_liquid = true
|
||||||
is_passable = true
|
is_passable = true
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ layout (binding = 0) uniform sampler2DArray samp;
|
|||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
color = texture(samp, vec3(tc, tex_layer));
|
color = texture(samp, vec3(tc, tex_layer));
|
||||||
if (color.a < 0.1) {
|
if (color.a < 0.45) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
//color = varyingColor;
|
//color = varyingColor;
|
||||||
|
|||||||
@@ -47,11 +47,16 @@ struct BlockData {
|
|||||||
bool is_passable = false;
|
bool is_passable = false;
|
||||||
bool is_cross_plane = false;
|
bool is_cross_plane = false;
|
||||||
bool is_transparent = false;
|
bool is_transparent = false;
|
||||||
|
|
||||||
|
bool is_discard = false;
|
||||||
|
bool is_blend = false;
|
||||||
|
|
||||||
BlockData(BlockType b_id, std::string_view b_name, bool liquid,
|
BlockData(BlockType b_id, std::string_view b_name, bool liquid,
|
||||||
bool passable, bool cross_plane, bool transparent, bool gas)
|
bool passable, bool cross_plane, bool transparent, bool gas,
|
||||||
|
bool discard, bool blend)
|
||||||
: name(b_name), id(b_id), is_liquid(liquid), is_gas(gas),
|
: name(b_name), id(b_id), is_liquid(liquid), is_gas(gas),
|
||||||
is_passable(passable), is_cross_plane(cross_plane),
|
is_passable(passable), is_cross_plane(cross_plane),
|
||||||
is_transparent(transparent) {}
|
is_transparent(transparent), is_discard(discard), is_blend(blend) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockManager {
|
class BlockManager {
|
||||||
@@ -69,6 +74,10 @@ public:
|
|||||||
static bool is_cross_plane(BlockType id);
|
static bool is_cross_plane(BlockType id);
|
||||||
static bool is_transparent(BlockType id);
|
static bool is_transparent(BlockType id);
|
||||||
static bool is_passable(BlockType id);
|
static bool is_passable(BlockType id);
|
||||||
|
|
||||||
|
static bool is_discard(BlockType id);
|
||||||
|
static bool is_blend(BlockType id);
|
||||||
|
|
||||||
static BlockType cross_plane_index(BlockType id);
|
static BlockType cross_plane_index(BlockType id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ private:
|
|||||||
static constexpr int SIZE_X = CHUNK_SIZE;
|
static constexpr int SIZE_X = CHUNK_SIZE;
|
||||||
static constexpr int SIZE_Y = WORLD_SIZE_Y;
|
static constexpr int SIZE_Y = WORLD_SIZE_Y;
|
||||||
static constexpr int SIZE_Z = CHUNK_SIZE;
|
static constexpr int SIZE_Z = CHUNK_SIZE;
|
||||||
|
static constexpr int VERTEX_DATA_SUM = 4;
|
||||||
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};
|
||||||
@@ -35,7 +35,8 @@ private:
|
|||||||
/*
|
/*
|
||||||
0 - normal
|
0 - normal
|
||||||
1 - cross_plane
|
1 - cross_plane
|
||||||
2 - transparent
|
2 - normal_discard
|
||||||
|
3 - transparent and blend
|
||||||
*/
|
*/
|
||||||
std::vector<VertexData> m_vertex_data;
|
std::vector<VertexData> m_vertex_data;
|
||||||
float frequency = 0.01f;
|
float frequency = 0.01f;
|
||||||
@@ -45,9 +46,10 @@ private:
|
|||||||
BiomeConditions m_conditions;
|
BiomeConditions m_conditions;
|
||||||
|
|
||||||
void clear_dirty();
|
void clear_dirty();
|
||||||
void gen_normal_vertices(
|
void gen_vertices(
|
||||||
const std::array<const std::vector<BlockType>*, 4>& neighbor_block);
|
const std::array<const std::vector<BlockType>*, 4>& neighbor_block);
|
||||||
void gen_cross_plane_vertices();
|
void gen_cross_plane_vertices(int world_x, int world_y, int world_z,
|
||||||
|
BlockType id);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Chunk(World& world, ChunkPos chunk_pos);
|
Chunk(World& world, ChunkPos chunk_pos);
|
||||||
@@ -105,8 +107,11 @@ public:
|
|||||||
GLuint get_cross_vbo() const;
|
GLuint get_cross_vbo() const;
|
||||||
size_t get_cross_vertices_sum() const;
|
size_t get_cross_vertices_sum() const;
|
||||||
|
|
||||||
GLuint get_transparent_vbo() const;
|
GLuint get_normal_discard_vbo() const;
|
||||||
size_t get_transparent_vertices_sum() const;
|
size_t get_normal_discard_vertices_sum() const;
|
||||||
|
|
||||||
|
GLuint get_normal_blend_vbo() const;
|
||||||
|
size_t get_normal_blend_vertices_sum() const;
|
||||||
|
|
||||||
bool is_dirty() const;
|
bool is_dirty() const;
|
||||||
void mark_dirty();
|
void mark_dirty();
|
||||||
|
|||||||
@@ -19,8 +19,10 @@ struct ChunkRenderSnapshot {
|
|||||||
size_t normal_vertices_count;
|
size_t normal_vertices_count;
|
||||||
GLuint cross_vbo;
|
GLuint cross_vbo;
|
||||||
size_t cross_vertices_count;
|
size_t cross_vertices_count;
|
||||||
GLuint transparent_vbo;
|
GLuint normal_discard_vbo;
|
||||||
size_t transparent_vertices_count;
|
size_t normal_discard_vertices_count;
|
||||||
|
GLuint normal_blend_vbo;
|
||||||
|
size_t normal_blend_vertices_count;
|
||||||
glm::vec3 center;
|
glm::vec3 center;
|
||||||
glm::vec3 half_extents;
|
glm::vec3 half_extents;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -90,6 +90,21 @@ bool BlockManager::is_passable(BlockType id) {
|
|||||||
return m_datas[id].is_passable;
|
return m_datas[id].is_passable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BlockManager::is_discard(BlockType id) {
|
||||||
|
if (id >= sums()) {
|
||||||
|
Logger::error("Id {}, is Over The Max Id", id, sums() - 1);
|
||||||
|
return m_datas[0].is_discard;
|
||||||
|
}
|
||||||
|
return m_datas[id].is_discard;
|
||||||
|
}
|
||||||
|
bool BlockManager::is_blend(BlockType id) {
|
||||||
|
if (id >= sums()) {
|
||||||
|
Logger::error("Id {}, is Over The Max Id", id, sums() - 1);
|
||||||
|
return m_datas[0].is_blend;
|
||||||
|
}
|
||||||
|
return m_datas[id].is_blend;
|
||||||
|
}
|
||||||
|
|
||||||
void BlockManager::init() {
|
void BlockManager::init() {
|
||||||
fs::path data_path{block_data_dir};
|
fs::path data_path{block_data_dir};
|
||||||
|
|
||||||
@@ -125,8 +140,11 @@ void BlockManager::init() {
|
|||||||
auto is_cross_plane = safe_get_value(block, "is_cross_plane", false);
|
auto is_cross_plane = safe_get_value(block, "is_cross_plane", false);
|
||||||
auto is_transparent = safe_get_value(block, "is_transparent", false);
|
auto is_transparent = safe_get_value(block, "is_transparent", false);
|
||||||
auto is_gas = safe_get_value(block, "is_gas", false);
|
auto is_gas = safe_get_value(block, "is_gas", false);
|
||||||
|
auto is_discard = safe_get_value(block, "is_discard", false);
|
||||||
|
auto is_blend = safe_get_value(block, "is_blend", false);
|
||||||
m_datas.emplace_back(*id, *name, *is_liquid, *is_passable,
|
m_datas.emplace_back(*id, *name, *is_liquid, *is_passable,
|
||||||
*is_cross_plane, *is_transparent, *is_gas);
|
*is_cross_plane, *is_transparent, *is_gas,
|
||||||
|
*is_discard, *is_blend);
|
||||||
}
|
}
|
||||||
std::sort(
|
std::sort(
|
||||||
m_datas.begin(), m_datas.end(),
|
m_datas.begin(), m_datas.end(),
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ 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++) {
|
for (int i = 0; i < VERTEX_DATA_SUM; i++) {
|
||||||
m_vertex_data.emplace_back(m_world);
|
m_vertex_data.emplace_back(m_world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,8 +115,7 @@ void Chunk::gen_vertex_data(
|
|||||||
data.m_vertices.clear();
|
data.m_vertices.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_normal_vertices(neighbor_block);
|
gen_vertices(neighbor_block);
|
||||||
gen_cross_plane_vertices();
|
|
||||||
for (auto& data : m_vertex_data) {
|
for (auto& data : m_vertex_data) {
|
||||||
data.update_sum();
|
data.update_sum();
|
||||||
}
|
}
|
||||||
@@ -138,11 +137,16 @@ size_t Chunk::get_cross_vertices_sum() const {
|
|||||||
return m_vertex_data[1].m_sum.load();
|
return m_vertex_data[1].m_sum.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint Chunk::get_transparent_vbo() const { return m_vertex_data[2].m_vbo; }
|
GLuint Chunk::get_normal_discard_vbo() const { return m_vertex_data[2].m_vbo; }
|
||||||
size_t Chunk::get_transparent_vertices_sum() const {
|
size_t Chunk::get_normal_discard_vertices_sum() const {
|
||||||
return m_vertex_data[2].m_sum.load();
|
return m_vertex_data[2].m_sum.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint Chunk::get_normal_blend_vbo() const { return m_vertex_data[3].m_vbo; }
|
||||||
|
size_t Chunk::get_normal_blend_vertices_sum() const {
|
||||||
|
return m_vertex_data[3].m_sum.load();
|
||||||
|
}
|
||||||
|
|
||||||
void Chunk::gen_phase_one() {
|
void Chunk::gen_phase_one() {
|
||||||
m_generator = std::make_unique<ChunkGenerator>(*this);
|
m_generator = std::make_unique<ChunkGenerator>(*this);
|
||||||
if (!m_generator) {
|
if (!m_generator) {
|
||||||
@@ -258,7 +262,7 @@ unsigned Chunk::seed() const {
|
|||||||
|
|
||||||
BiomeConditions& Chunk::conditions() { return m_conditions; }
|
BiomeConditions& Chunk::conditions() { return m_conditions; }
|
||||||
|
|
||||||
void Chunk::gen_normal_vertices(
|
void Chunk::gen_vertices(
|
||||||
const std::array<const std::vector<BlockType>*, 4>& neighbor_block) {
|
const std::array<const std::vector<BlockType>*, 4>& neighbor_block) {
|
||||||
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}};
|
||||||
@@ -355,6 +359,10 @@ void Chunk::gen_normal_vertices(
|
|||||||
if (neighbor_culled) {
|
if (neighbor_culled) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (BlockManager::is_cross_plane(cur_id)) {
|
||||||
|
gen_cross_plane_vertices(world_x, world_y, world_z,
|
||||||
|
cur_id);
|
||||||
|
}
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
Vertex vex = {
|
Vertex vex = {
|
||||||
VERTICES_POS[face][i][0] + (float)world_x * 1.0f,
|
VERTICES_POS[face][i][0] + (float)world_x * 1.0f,
|
||||||
@@ -366,7 +374,17 @@ void Chunk::gen_normal_vertices(
|
|||||||
|
|
||||||
};
|
};
|
||||||
if (BlockManager::is_transparent(cur_id)) {
|
if (BlockManager::is_transparent(cur_id)) {
|
||||||
m_vertex_data[2].m_vertices.emplace_back(vex);
|
if (BlockManager::is_discard(cur_id)) {
|
||||||
|
m_vertex_data[2].m_vertices.emplace_back(vex);
|
||||||
|
} else if (BlockManager::is_blend(cur_id)) {
|
||||||
|
m_vertex_data[3].m_vertices.emplace_back(vex);
|
||||||
|
} else {
|
||||||
|
Logger::warn("Id {} is transparent but not "
|
||||||
|
"discard or blend",
|
||||||
|
cur_id);
|
||||||
|
m_vertex_data[3].m_vertices.emplace_back(vex);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
m_vertex_data[0].m_vertices.emplace_back(vex);
|
m_vertex_data[0].m_vertices.emplace_back(vex);
|
||||||
}
|
}
|
||||||
@@ -376,40 +394,30 @@ void Chunk::gen_normal_vertices(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Chunk::gen_cross_plane_vertices() {
|
void Chunk::gen_cross_plane_vertices(int world_x, int world_y, int world_z,
|
||||||
|
BlockType id) {
|
||||||
|
|
||||||
for (int x = 0; x < SIZE_X; x++) {
|
if (!BlockManager::is_cross_plane(id)) {
|
||||||
for (int y = 0; y < SIZE_Y; y++) {
|
Logger::warn("Block {} {} {} id {} is not cross plane", world_x,
|
||||||
for (int z = 0; z < SIZE_Z; z++) {
|
world_y, world_z, id);
|
||||||
int world_x = x + m_chunk_pos.x * CHUNK_SIZE;
|
return;
|
||||||
int world_z = z + m_chunk_pos.z * CHUNK_SIZE;
|
}
|
||||||
int world_y = y;
|
for (int face = 0; face < 2; face++) {
|
||||||
int id = m_blocks[index(x, y, z)];
|
for (int i = 0; i < 6; i++) {
|
||||||
|
Vertex vex = {
|
||||||
|
CROSS_VERTICES_POS[face][i][0] + (float)world_x * 1.0f,
|
||||||
|
CROSS_VERTICES_POS[face][i][1] + (float)world_y * 1.0f,
|
||||||
|
CROSS_VERTICES_POS[face][i][2] + (float)world_z * 1.0f,
|
||||||
|
CROSS_TEX_COORDS[face][i][0],
|
||||||
|
CROSS_TEX_COORDS[face][i][1],
|
||||||
|
static_cast<float>(BlockManager::cross_plane_index(id))
|
||||||
|
|
||||||
if (!BlockManager::is_cross_plane(id)) {
|
};
|
||||||
continue;
|
m_vertex_data[1].m_vertices.emplace_back(vex);
|
||||||
}
|
|
||||||
for (int face = 0; face < 2; face++) {
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
Vertex vex = {CROSS_VERTICES_POS[face][i][0] +
|
|
||||||
(float)world_x * 1.0f,
|
|
||||||
CROSS_VERTICES_POS[face][i][1] +
|
|
||||||
(float)world_y * 1.0f,
|
|
||||||
CROSS_VERTICES_POS[face][i][2] +
|
|
||||||
(float)world_z * 1.0f,
|
|
||||||
CROSS_TEX_COORDS[face][i][0],
|
|
||||||
CROSS_TEX_COORDS[face][i][1],
|
|
||||||
static_cast<float>(
|
|
||||||
BlockManager::cross_plane_index(id))
|
|
||||||
|
|
||||||
};
|
|
||||||
m_vertex_data[1].m_vertices.emplace_back(vex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Logger::info("Cross Sum {}", m_cross_vertices_sum.load());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logger::info("Cross Sum {}", m_cross_vertices_sum.load());
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
|
|||||||
@@ -319,6 +319,58 @@ void World::render(const glm::mat4& mvp_matrix,
|
|||||||
rendered_sum++;
|
rendered_sum++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// cross_plane and normal discard
|
||||||
|
|
||||||
|
for (const auto& snapshot : m_render_snapshots) {
|
||||||
|
if (!is_aabb_in_frustum(snapshot.center, snapshot.half_extents)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
glm::vec2 camera_pos_xz{camera_pos.x, camera_pos.z};
|
||||||
|
if (snapshot.cross_vertices_count != 0) {
|
||||||
|
glm::vec2 center_xz{snapshot.center.x, snapshot.center.z};
|
||||||
|
float dist2d = glm::distance(camera_pos_xz, center_xz);
|
||||||
|
if (dist2d <= CROSS_PLANE_DISTANCE * 16) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY,
|
||||||
|
texture_manager.get_cross_plane_array());
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, snapshot.cross_vbo);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||||
|
(void*)0);
|
||||||
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||||
|
(void*)offsetof(Vertex, s));
|
||||||
|
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||||
|
(void*)offsetof(Vertex, layer));
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, snapshot.cross_vertices_count);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (snapshot.normal_discard_vertices_count != 0) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY,
|
||||||
|
texture_manager.get_texture_array());
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, snapshot.normal_discard_vbo);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||||
|
(void*)0);
|
||||||
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||||
|
(void*)offsetof(Vertex, s));
|
||||||
|
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||||
|
(void*)offsetof(Vertex, layer));
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0,
|
||||||
|
snapshot.normal_discard_vertices_count);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// blend block
|
||||||
|
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
|
|
||||||
struct SortableSnapshot {
|
struct SortableSnapshot {
|
||||||
@@ -326,8 +378,7 @@ void World::render(const glm::mat4& mvp_matrix,
|
|||||||
float distance;
|
float distance;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<SortableSnapshot> cross_list;
|
std::vector<SortableSnapshot> blend_list;
|
||||||
std::vector<SortableSnapshot> transparent_list;
|
|
||||||
|
|
||||||
for (const auto& snapshot : m_render_snapshots) {
|
for (const auto& snapshot : m_render_snapshots) {
|
||||||
|
|
||||||
@@ -336,51 +387,19 @@ void World::render(const glm::mat4& mvp_matrix,
|
|||||||
}
|
}
|
||||||
|
|
||||||
float dist = glm::distance(camera_pos, snapshot.center);
|
float dist = glm::distance(camera_pos, snapshot.center);
|
||||||
glm::vec2 camera_pos_xz{camera_pos.x, camera_pos.z};
|
if (snapshot.normal_blend_vertices_count != 0) {
|
||||||
if (snapshot.cross_vertices_count != 0) {
|
blend_list.push_back({&snapshot, dist});
|
||||||
glm::vec2 center_xz{snapshot.center.x, snapshot.center.z};
|
|
||||||
float dist2d = glm::distance(camera_pos_xz, center_xz);
|
|
||||||
if (dist2d <= CROSS_PLANE_DISTANCE * 16) {
|
|
||||||
cross_list.push_back({&snapshot, dist});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (snapshot.transparent_vertices_count != 0) {
|
|
||||||
transparent_list.push_back({&snapshot, dist});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::sort(transparent_list.begin(), transparent_list.end(),
|
std::sort(blend_list.begin(), blend_list.end(),
|
||||||
[](const SortableSnapshot& a, const SortableSnapshot& b) {
|
|
||||||
return a.distance > b.distance;
|
|
||||||
});
|
|
||||||
std::sort(cross_list.begin(), cross_list.end(),
|
|
||||||
[](const SortableSnapshot& a, const SortableSnapshot& b) {
|
[](const SortableSnapshot& a, const SortableSnapshot& b) {
|
||||||
return a.distance > b.distance;
|
return a.distance > b.distance;
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const auto& item : cross_list) {
|
for (const auto& item : blend_list) {
|
||||||
const auto& snapshot = *item.snapshot;
|
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY,
|
|
||||||
texture_manager.get_cross_plane_array());
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, snapshot.cross_vbo);
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
|
||||||
(void*)0);
|
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
|
||||||
(void*)offsetof(Vertex, s));
|
|
||||||
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
|
||||||
(void*)offsetof(Vertex, layer));
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glEnableVertexAttribArray(2);
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, snapshot.cross_vertices_count);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& item : transparent_list) {
|
|
||||||
const auto& snapshot = *item.snapshot;
|
const auto& snapshot = *item.snapshot;
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, texture_manager.get_texture_array());
|
glBindTexture(GL_TEXTURE_2D_ARRAY, texture_manager.get_texture_array());
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, snapshot.transparent_vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, snapshot.normal_blend_vbo);
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||||
(void*)0);
|
(void*)0);
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||||
@@ -392,7 +411,7 @@ void World::render(const glm::mat4& mvp_matrix,
|
|||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, snapshot.transparent_vertices_count);
|
glDrawArrays(GL_TRIANGLES, 0, snapshot.normal_blend_vertices_count);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -966,8 +985,10 @@ void World::update(float delta_time) {
|
|||||||
m_render_snapshots.push_back(
|
m_render_snapshots.push_back(
|
||||||
{chunk.get_normal_vbo(), chunk.get_normal_vertices_sum(),
|
{chunk.get_normal_vbo(), chunk.get_normal_vertices_sum(),
|
||||||
chunk.get_cross_vbo(), chunk.get_cross_vertices_sum(),
|
chunk.get_cross_vbo(), chunk.get_cross_vertices_sum(),
|
||||||
chunk.get_transparent_vbo(),
|
chunk.get_normal_discard_vbo(),
|
||||||
chunk.get_transparent_vertices_sum(),
|
chunk.get_normal_discard_vertices_sum(),
|
||||||
|
chunk.get_normal_blend_vbo(),
|
||||||
|
chunk.get_normal_blend_vertices_sum(),
|
||||||
glm::vec3(static_cast<float>(pos.x * CHUNK_SIZE) +
|
glm::vec3(static_cast<float>(pos.x * CHUNK_SIZE) +
|
||||||
static_cast<float>(CHUNK_SIZE / 2),
|
static_cast<float>(CHUNK_SIZE / 2),
|
||||||
static_cast<float>(WORLD_SIZE_Y / 2),
|
static_cast<float>(WORLD_SIZE_Y / 2),
|
||||||
|
|||||||
Reference in New Issue
Block a user