1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Add a setting to group transparency sorted triangles by buffer (#15115)

This commit is contained in:
DS 2024-11-28 14:22:53 +01:00 committed by GitHub
parent c175046d30
commit df4e70b2c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 66 additions and 14 deletions

View file

@ -3,6 +3,7 @@
// Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
#include "mapblock_mesh.h"
#include "CMeshBuffer.h"
#include "client.h"
#include "mapblock.h"
#include "map.h"
@ -818,7 +819,8 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack,
return true;
}
void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos)
void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos,
bool group_by_buffers)
{
// nothing to do if the entire block is opaque
if (m_transparent_triangles.empty())
@ -834,24 +836,56 @@ void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos)
m_transparent_buffers_consolidated = false;
m_transparent_buffers.clear();
std::vector<std::pair<scene::SMeshBuffer *, std::vector<u16>>> ordered_strains;
std::unordered_map<scene::SMeshBuffer *, size_t> strain_idxs;
if (group_by_buffers) {
// find (reversed) order for strains, by iterating front-to-back
// (if a buffer A has a triangle nearer than all triangles of another
// buffer B, A should be drawn in front of (=after) B)
scene::SMeshBuffer *current_buffer = nullptr;
for (auto it = triangle_refs.rbegin(); it != triangle_refs.rend(); ++it) {
const auto &t = m_transparent_triangles[*it];
if (current_buffer == t.buffer)
continue;
current_buffer = t.buffer;
auto [_it2, is_new] =
strain_idxs.emplace(current_buffer, ordered_strains.size());
if (is_new)
ordered_strains.emplace_back(current_buffer, std::vector<u16>{});
}
}
// find order for triangles, by iterating back-to-front
scene::SMeshBuffer *current_buffer = nullptr;
std::vector<u16> current_strain;
std::vector<u16> *current_strain = nullptr;
for (auto i : triangle_refs) {
const auto &t = m_transparent_triangles[i];
if (current_buffer != t.buffer) {
if (current_buffer) {
m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain));
current_strain.clear();
}
current_buffer = t.buffer;
if (group_by_buffers) {
auto it = strain_idxs.find(current_buffer);
assert(it != strain_idxs.end());
current_strain = &ordered_strains[it->second].second;
} else {
ordered_strains.emplace_back(current_buffer, std::vector<u16>{});
current_strain = &ordered_strains.back().second;
}
}
current_strain.push_back(t.p1);
current_strain.push_back(t.p2);
current_strain.push_back(t.p3);
current_strain->push_back(t.p1);
current_strain->push_back(t.p2);
current_strain->push_back(t.p3);
}
if (!current_strain.empty())
m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain));
m_transparent_buffers.reserve(ordered_strains.size());
if (group_by_buffers) {
// the order was reversed
for (auto it = ordered_strains.rbegin(); it != ordered_strains.rend(); ++it)
m_transparent_buffers.emplace_back(it->first, std::move(it->second));
} else {
for (auto it = ordered_strains.begin(); it != ordered_strains.end(); ++it)
m_transparent_buffers.emplace_back(it->first, std::move(it->second));
}
}
void MapBlockMesh::consolidateTransparentBuffers()