summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--draw/anim.cpp93
-rw-r--r--draw/anim.hpp2
2 files changed, 78 insertions, 17 deletions
diff --git a/draw/anim.cpp b/draw/anim.cpp
index a5dddebe..d840c8c6 100644
--- a/draw/anim.cpp
+++ b/draw/anim.cpp
@@ -14,6 +14,68 @@
namespace floormat {
+namespace {
+
+std::array<UnsignedShort, 6> make_index_array()
+{
+ return {{
+ 0, 1, 2,
+ 2, 1, 3,
+ }};
+}
+
+struct minmax_s { uint32_t len, min; };
+
+bool check_contig_draw(ArrayView<const chunk::object_draw_order> array, uint32_t start, uint32_t end, minmax_s& ret)
+{
+ const auto& e0 = array[start];
+ uint32_t min = e0.mesh_idx, max = min;
+
+ for (auto i = start+1; i < end; i++)
+ {
+ const auto& e = array[i];
+ min = Math::min(min, e.mesh_idx);
+ max = Math::max(max, e.mesh_idx);
+ }
+
+ auto len = max - min;
+ auto sz = end - start;
+ ret = {
+ .len = sz,
+ .min = min,
+ };
+ return len+1 == sz;
+}
+
+uint32_t get_contig_draw_max_len(ArrayView<const chunk::object_draw_order> array, uint32_t start)
+{
+ const auto size = (uint32_t)array.size();
+ uint32_t len = 1;
+ const auto* a0 = array[start].e->atlas.get();
+ for (auto i = start+1; i < size; i++)
+ {
+ const auto& e = array[i];
+ if (e.e->atlas.get() != a0)
+ break;
+ if (e.mesh_idx == (uint32_t)-1)
+ break;
+ len++;
+ }
+ return len;
+}
+
+minmax_s get_contig_draw_len(ArrayView<const chunk::object_draw_order> array, uint32_t start)
+{
+ auto r = minmax_s { .len = 1, .min = array[start].mesh_idx, };
+ auto len = get_contig_draw_max_len(array, start);
+ for (auto i = len; i > 1; i--)
+ if (check_contig_draw(array, start, start + i, r))
+ return r;
+ return r;
+}
+
+} // namespace
+
anim_mesh::anim_mesh() :
_vertex_buffer{quad_data{}, Magnum::GL::BufferUsage::DynamicDraw},
_index_buffer{make_index_array()}
@@ -24,14 +86,6 @@ anim_mesh::anim_mesh() :
CORRADE_INTERNAL_ASSERT(_mesh.isIndexed());
}
-std::array<UnsignedShort, 6> anim_mesh::make_index_array()
-{
- return {{
- 0, 1, 2,
- 2, 1, 3,
- }};
-}
-
void anim_mesh::add_clickable(tile_shader& shader, const Vector2i& win_size,
object* sʹ, const chunk::topo_sort_data& data,
Array<clickable>& list)
@@ -64,13 +118,14 @@ void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, Ar
{
constexpr auto quad_index_count = 6;
- auto [mesh_, es, size] = c.ensure_scenery_mesh({ _draw_array, _draw_vertexes, _draw_indexes });
+ auto [mesh_, es, size] = c.ensure_scenery_mesh({ _draw_array, _draw_vertexes, _draw_indexes, });
const auto max_index = uint32_t(size*quad_index_count - 1);
- uint32_t i = 0;
+ uint32_t k = 0;
- for (const auto& x : es)
+ while (k < es.size())
{
+ const auto& x = es[k];
fm_assert(x.e);
add_clickable(shader, win_size, x.data.in, x.data, list);
auto& e = *x.e;
@@ -79,12 +134,18 @@ void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, Ar
fm_assert(e.is_dynamic() == (x.mesh_idx == (uint32_t)-1));
if (!e.is_dynamic())
{
- fm_assert(i < size);
+#if 1
+ auto r = get_contig_draw_len(es, k);
+#else
+ auto r = minmax_s{1, x.mesh_idx};
+#endif
+ uint32_t count = r.len;
GL::MeshView mesh{mesh_};
- mesh.setCount(quad_index_count * 1);
- mesh.setIndexOffset((int)(x.mesh_idx*quad_index_count), 0, max_index);
+ mesh.setCount(quad_index_count * (Int)count);
+ mesh.setIndexOffset((int)(r.min*quad_index_count), 0, max_index);
shader.draw(atlas.texture(), mesh);
- i++;
+ //if (count > 1) Debug{} << "foo" << atlas.name() << count;
+ k += count;
}
else
{
@@ -95,8 +156,10 @@ void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, Ar
const auto depth0 = e.depth_offset();
const auto depth = tile_shader::depth_value(e.coord.local(), depth0);
draw(shader, atlas, e.r, e.frame, e.coord.local(), e.offset, depth);
+ k++;
}
}
+ fm_assert(k == es.size());
}
void anim_mesh::draw(tile_shader& shader, anim_atlas& atlas, rotation r, size_t frame, const Vector3& center, float depth)
diff --git a/draw/anim.hpp b/draw/anim.hpp
index a9fd6011..9a49289a 100644
--- a/draw/anim.hpp
+++ b/draw/anim.hpp
@@ -34,8 +34,6 @@ struct anim_mesh
Array<clickable>& list);
private:
- static std::array<UnsignedShort, 6> make_index_array();
-
struct vertex_data
{
Vector3 position;