summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-08-26 20:52:50 +0200
committerStanislaw Halik <sthalik@misaki.pl>2024-09-20 16:08:46 +0200
commitb0e86fb89d8ea94601b0244f918df07a3fa82a9e (patch)
tree9dd02047e1fbc93c83193a9921c8dd99e0407a16
parent8eabcf8277657020907ca8b3d71bbf64baf48f71 (diff)
src/chunk: allow arbitrary amount of wall quads for rendering
It's required for drawing holes on walls.
-rw-r--r--src/chunk-walls.cpp72
-rw-r--r--src/chunk.hpp6
2 files changed, 44 insertions, 34 deletions
diff --git a/src/chunk-walls.cpp b/src/chunk-walls.cpp
index fd59bd24..17aac134 100644
--- a/src/chunk-walls.cpp
+++ b/src/chunk-walls.cpp
@@ -3,9 +3,10 @@
#include "quads.hpp"
#include "wall-atlas.hpp"
#include "shaders/shader.hpp"
-#include <Corrade/Containers/ArrayViewStl.h>
-#include <Corrade/Containers/Pair.h>
-#include <Corrade/Containers/Optional.h>
+#include <cr/ArrayViewStl.h>
+#include <cr/GrowableArray.h>
+#include <cr/Pair.h>
+#include <cr/Optional.h>
#include <algorithm>
#include <ranges>
@@ -115,19 +116,31 @@ constexpr Quads::quad get_quad(float depth)
std::unreachable();
}
-Array<Quads::indexes> make_indexes_()
+ArrayView<const Quads::indexes> make_indexes(uint32_t count)
{
- auto array = Array<Quads::indexes>{NoInit, chunk::max_wall_quad_count };
- for (auto i = 0uz; i < chunk::max_wall_quad_count; i++)
- array[i] = Quads::quad_indexes(i);
- return array;
+ static auto array = [] {
+ auto array = Array<Quads::indexes>{};
+ arrayReserve(array, 64);
+ return array;
+ }();
+ auto i = (uint32_t)array.size();
+ if (count > i) [[unlikely]]
+ {
+ arrayResize(array, NoInit, count);
+ for (; i < count; i++)
+ array.data()[i] = Quads::quad_indexes(i);
+ }
+ return array.prefix(count);
}
-ArrayView<const Quads::indexes> make_indexes(size_t max)
+Array<std::array<chunk::vertex, 4>>& make_vertexes()
{
- static const auto indexes = make_indexes_();
- fm_assert(max <= chunk::max_wall_quad_count);
- return indexes.prefix(max);
+ static auto array = [] {
+ Array<std::array<chunk::vertex, 4>> array;
+ arrayReserve(array, 32);
+ return array;
+ }();
+ return array;
}
template<Group_ G, bool IsWest>
@@ -154,6 +167,17 @@ Frame variant_from_frame(ArrayView<const Frame> frames, global_coords coord, var
return frames[variant];
}
+constexpr std::array<chunk::vertex, 4>& alloc_wall_vertexes(uint32_t& N, auto& V, auto& M, uint32_t k)
+{
+ constexpr uint32_t reserve = 15, mask = ~reserve;
+ const auto i = N, sz = ++N + reserve & mask;
+ fm_assert(uint32_t{(UnsignedShort)sz} == sz);
+ arrayResize(V, NoInit, sz);
+ arrayResize(M, NoInit, sz);
+ M[i] = (uint16_t)k;
+ return V[i];
+};
+
template<Group_ G, bool IsWest>
void do_wall_part(const Group& group, wall_atlas& A, chunk& c, chunk::wall_stuff& W,
Array<std::array<chunk::vertex, 4>>& vertexes,
@@ -220,14 +244,11 @@ void do_wall_part(const Group& group, wall_atlas& A, chunk& c, chunk::wall_stuff
fm_assert(frame.size.y() >= Depth);
auto start = frame.offset + Vector2ui{0, frame.size.y()} - Vector2ui{0, Depth};
const auto texcoords = Quads::texcoords_at(start, Vector2ui{Depth, Depth}, A.image_size());
- const auto i = N++;
- fm_assert(i < vertexes.size());
- W.mesh_indexes[i] = (uint16_t)k;
const auto depth_offset = depth_offset_for_group<Group_::top, IsWest>();
const auto depth = tile_shader::depth_value(pos, depth_offset);
for (auto& v : quad)
v += center;
- auto& v = vertexes[i];
+ auto& v = alloc_wall_vertexes(N, vertexes, W.mesh_indexes, k);
for (uint8_t j = 0; j < 4; j++)
v[j] = {quad[j], texcoords[j], depth};
}
@@ -242,13 +263,10 @@ void do_wall_part(const Group& group, wall_atlas& A, chunk& c, chunk::wall_stuff
const auto depth = tile_shader::depth_value(pos_x, pos.y, depth_offset);
const auto& frame = variant_from_frame(frames, coord, variant_2, IsWest);
const auto texcoords = Quads::texcoords_at(frame.offset, frame.size, A.image_size());
- const auto i = N++;
- fm_assert(i < vertexes.size());
- W.mesh_indexes[i] = (uint16_t)k;
auto quad = get_quad<Group_::corner, IsWest>((float)Depth);
for (auto& v : quad)
v += center;
- auto& v = vertexes[i];
+ auto& v = alloc_wall_vertexes(N, vertexes, W.mesh_indexes, k);
for (uint8_t j = 0; j < 4; j++)
v[j] = {quad[j], texcoords[j], depth};
}
@@ -261,13 +279,10 @@ void do_wall_part(const Group& group, wall_atlas& A, chunk& c, chunk::wall_stuff
fm_assert(frame.size.x() > Depth);
auto start = frame.offset + Vector2ui{frame.size.x(), 0} - Vector2ui{Depth, 0};
const auto texcoords = Quads::texcoords_at(start, {Depth, frame.size.y()}, A.image_size());
- const auto i = N++;
- fm_assert(i < vertexes.size());
- W.mesh_indexes[i] = (uint16_t)k;
auto quad = get_quad<Group_::corner, IsWest>((float)Depth);
for (auto& v : quad)
v += center;
- auto& v = vertexes[i];
+ auto& v = alloc_wall_vertexes(N, vertexes, W.mesh_indexes, k);
for (uint8_t j = 0; j < 4; j++)
v[j] = {quad[j], texcoords[j], depth};
}
@@ -277,9 +292,6 @@ void do_wall_part(const Group& group, wall_atlas& A, chunk& c, chunk::wall_stuff
if (G == Group_::side || side_ok)
{
const auto frames = A.frames(group);
- const auto i = N++;
- fm_assert(i < vertexes.size());
- W.mesh_indexes[i] = (uint16_t)k;
const auto frame = variant_from_frame(frames, coord, variant_2, IsWest);
const auto texcoords = Quads::texcoords_at(frame.offset, frame.size, A.image_size());
const auto depth_offset = depth_offset_for_group<G, IsWest>();
@@ -287,7 +299,7 @@ void do_wall_part(const Group& group, wall_atlas& A, chunk& c, chunk::wall_stuff
auto quad = get_quad<G, IsWest>((float)Depth);
for (auto& v : quad)
v += center;
- auto& v = vertexes[i];
+ auto& v = alloc_wall_vertexes(N, vertexes, W.mesh_indexes, k);
for (uint8_t j = 0; j < 4; j++)
v[j] = {quad[j], texcoords[j], depth};
}
@@ -300,9 +312,11 @@ GL::Mesh chunk::make_wall_mesh()
fm_debug_assert(_walls);
uint32_t N = 0;
- static auto vertexes = Array<std::array<vertex, 4>>{NoInit, max_wall_quad_count };
+ auto& vertexes = make_vertexes();
auto& W = *_walls;
+ arrayResize(vertexes, 0);
+
for (uint32_t k = 0; k < TILE_COUNT; k++)
{
const auto coord = global_coords{_coord, local_coords{k}};
diff --git a/src/chunk.hpp b/src/chunk.hpp
index e6379507..335d3440 100644
--- a/src/chunk.hpp
+++ b/src/chunk.hpp
@@ -107,10 +107,6 @@ public:
void remove_object(size_t i);
void sort_objects();
- // for drawing only
- static constexpr size_t max_wall_quad_count =
- TILE_COUNT*Wall::Direction_COUNT*(Wall::Group_COUNT+4);
-
pass_region make_pass_region(bool debug = false, ArrayView<const Vector2i> positions = {});
pass_region make_pass_region(const Search::pred& f, bool debug = false, ArrayView<const Vector2i> positions = {});
@@ -125,7 +121,7 @@ public:
{
std::array<bptr<wall_atlas>, 2*TILE_COUNT> atlases;
std::array<variant_t, 2*TILE_COUNT> variants;
- std::array<uint_fast16_t, max_wall_quad_count> mesh_indexes;
+ Array<uint_fast16_t> mesh_indexes;
};
private: