summaryrefslogtreecommitdiffhomepage
path: root/src/chunk.cpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-11-09 18:27:32 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-11-09 18:27:32 +0100
commit5907a8902e6f01774cebbb515349a66c86a47fb3 (patch)
tree7d3f90a38e038e0f4acbaf62b328fb23446ab7c7 /src/chunk.cpp
parent1febb02d958fa4cf8c15e3ca18f9d644f9fc80fb (diff)
allow drawing walls in random order
Diffstat (limited to 'src/chunk.cpp')
-rw-r--r--src/chunk.cpp102
1 files changed, 82 insertions, 20 deletions
diff --git a/src/chunk.cpp b/src/chunk.cpp
index 0cfb4959..e736fe42 100644
--- a/src/chunk.cpp
+++ b/src/chunk.cpp
@@ -24,20 +24,25 @@ bool chunk::empty(bool force) const noexcept
return true;
}
-tile_atlas* chunk::ground_atlas_at(std::size_t i) const noexcept
-{
- return _ground_atlases[i].get();
-}
+tile_atlas* chunk::ground_atlas_at(std::size_t i) const noexcept { return _ground_atlases[i].get(); }
+tile_atlas* chunk::wall_n_atlas_at(std::size_t i) const noexcept { return _wall_north_atlases[i].get(); }
+tile_atlas* chunk::wall_w_atlas_at(std::size_t i) const noexcept { return _wall_west_atlases[i].get(); }
-static constexpr auto make_index_array()
+static auto make_index_array(std::size_t offset)
{
- std::array<std::array<UnsignedShort, 6>, TILE_COUNT> array;
+ std::array<std::array<UnsignedShort, 6>, TILE_COUNT> array; // NOLINT(cppcoreguidelines-pro-type-member-init)
for (std::size_t i = 0; i < TILE_COUNT; i++)
- array[i] = tile_atlas::indices(i);
+ array[i] = tile_atlas::indices(i + offset);
return array;
}
-auto chunk::ensure_ground_mesh() noexcept -> mesh_tuple
+struct vertex {
+ Vector3 position;
+ Vector2 texcoords;
+ float depth = -1;
+};
+
+auto chunk::ensure_ground_mesh() noexcept -> ground_mesh_tuple
{
if (!_ground_modified)
return { ground_mesh, ground_indexes };
@@ -49,11 +54,6 @@ auto chunk::ensure_ground_mesh() noexcept -> mesh_tuple
return _ground_atlases[a].get() < _ground_atlases[b].get();
});
- struct vertex {
- Vector3 position;
- Vector2 texcoords;
- float depth = -1;
- };
std::array<std::array<vertex, 4>, TILE_COUNT> vertexes;
for (std::size_t k = 0; k < TILE_COUNT; k++)
{
@@ -71,7 +71,7 @@ auto chunk::ensure_ground_mesh() noexcept -> mesh_tuple
v[j] = { quad[j], texcoords[j], depth };
}
}
- constexpr auto indexes = make_index_array();
+ const auto indexes = make_index_array(0);
GL::Mesh mesh{GL::MeshPrimitive::Triangles};
mesh.addVertexBuffer(GL::Buffer{vertexes}, 0, tile_shader::Position{}, tile_shader::TextureCoordinates{}, tile_shader::Depth{})
@@ -81,6 +81,69 @@ auto chunk::ensure_ground_mesh() noexcept -> mesh_tuple
return { ground_mesh, ground_indexes };
}
+auto chunk::ensure_wall_mesh() noexcept -> wall_mesh_tuple
+{
+ if (!_walls_modified)
+ return { wall_mesh, wall_n_indexes, wall_w_indexes };
+ _walls_modified = false;
+
+ for (std::size_t i = 0; i < TILE_COUNT; i++)
+ wall_n_indexes[i] = std::uint8_t(i);
+ for (std::size_t i = 0; i < TILE_COUNT; i++)
+ wall_w_indexes[i] = std::uint8_t(i);
+
+ std::sort(wall_n_indexes.begin(), wall_n_indexes.end(), [this](std::uint8_t a, std::uint8_t b) {
+ return _wall_north_atlases[a].get() < _wall_north_atlases[b].get();
+ });
+ std::sort(wall_w_indexes.begin(), wall_w_indexes.end(), [this](std::uint8_t a, std::uint8_t b) {
+ return _wall_west_atlases[a].get() < _wall_west_atlases[b].get();
+ });
+
+ std::array<std::array<vertex, 4>, TILE_COUNT> vertexes[2] = {};
+
+ using ids_ = std::array<std::uint8_t, TILE_COUNT>;
+ using a_ = std::array<std::shared_ptr<tile_atlas>, TILE_COUNT>;
+ using vs_ = std::array<variant_t, TILE_COUNT>;
+ using verts_ = std::array<std::array<vertex, 4>, TILE_COUNT>;
+ constexpr auto do_walls = [](const ids_& ids, const a_& as, const vs_& vs, verts_& verts, const auto& fn) {
+ for (std::size_t k = 0; k < TILE_COUNT; k++)
+ {
+ const std::uint8_t i = ids[k];
+ if (const auto& atlas = as[i]; !atlas)
+ verts[k] = {};
+ else
+ {
+ const local_coords pos{i};
+ const float depth = tile_shader::depth_value(pos);
+ const std::array<Vector3, 4> quad = fn(*atlas, pos);
+ const auto texcoords = atlas->texcoords_for_id(vs[i] % atlas->num_tiles());
+ auto& v = verts[k];
+ for (std::size_t j = 0; j < 4; j++)
+ v[j] = { quad[j], texcoords[j], depth, };
+ }
+ }
+ };
+ do_walls(wall_n_indexes, _wall_north_atlases, _wall_north_variants, vertexes[0],
+ [](const tile_atlas& a, local_coords pos) {
+ return a.wall_quad_N(Vector3(pos.x, pos.y, 0) * TILE_SIZE, TILE_SIZE);
+ });
+ do_walls(wall_w_indexes, _wall_west_atlases, _wall_west_variants, vertexes[1],
+ [](const tile_atlas& a, local_coords pos) {
+ return a.wall_quad_W(Vector3(pos.x, pos.y, 0) * TILE_SIZE, TILE_SIZE);
+ });
+
+ using index_t = std::array<std::array<UnsignedShort, 6>, TILE_COUNT>;
+ const index_t indexes[2] = { make_index_array(0), make_index_array(TILE_COUNT) };
+
+ GL::Mesh mesh{GL::MeshPrimitive::Triangles};
+ mesh.addVertexBuffer(GL::Buffer{vertexes}, 0, tile_shader::Position{}, tile_shader::TextureCoordinates{}, tile_shader::Depth{})
+ .setIndexBuffer(GL::Buffer{indexes}, 0, GL::MeshIndexType::UnsignedShort)
+ .setCount(6 * TILE_COUNT);
+ wall_mesh = Utility::move(mesh);
+ return { wall_mesh, wall_n_indexes, wall_w_indexes };
+}
+
+fm_noinline
chunk::chunk() noexcept // NOLINT(modernize-use-equals-default)
{
//fm_debug("chunk ctor");
@@ -101,14 +164,13 @@ auto chunk::end() const noexcept -> const_iterator { return cend(); }
chunk::chunk(chunk&&) noexcept = default;
chunk& chunk::operator=(chunk&&) noexcept = default;
-void chunk::mark_modified() noexcept
-{
- _ground_modified = true;
-}
+void chunk::mark_ground_modified() noexcept { _ground_modified = true; }
+void chunk::mark_walls_modified() noexcept { _walls_modified = true; }
-bool chunk::is_modified() const noexcept
+void chunk::mark_modified() noexcept
{
- return _ground_modified;
+ mark_ground_modified();
+ mark_walls_modified();
}
} // namespace floormat