summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--draw/anim.cpp54
-rw-r--r--src/chunk-scenery.cpp37
-rw-r--r--src/chunk-scenery.hpp2
-rw-r--r--src/chunk.hpp2
4 files changed, 38 insertions, 57 deletions
diff --git a/draw/anim.cpp b/draw/anim.cpp
index c6c12a64..b99b02e3 100644
--- a/draw/anim.cpp
+++ b/draw/anim.cpp
@@ -60,64 +60,40 @@ void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, st
constexpr auto quad_index_count = 6;
auto [mesh_, es, size] = c.ensure_scenery_mesh(_draw_array);
- for (const auto& x : es)
- add_clickable(shader, win_size, x.data.in, x.data, list);
-
GL::MeshView mesh{mesh_};
- [[maybe_unused]] size_t draw_count = 0;
const auto max_index = uint32_t(size*quad_index_count - 1);
- const auto do_draw = [&](size_t from, size_t to, anim_atlas* atlas) {
+ constexpr auto do_draw = [](tile_shader& shader, GL::Mesh& mesh_, anim_atlas* atlas, uint32_t i, uint32_t max_index) {
+ GL::MeshView mesh{mesh_};
atlas->texture().bind(0);
- mesh.setCount((int)(quad_index_count * (to-from)));
- mesh.setIndexRange((int)(from*quad_index_count), 0, max_index);
+ mesh.setCount((int)(quad_index_count * 1));
+ mesh.setIndexRange((int)(i*quad_index_count), 0, max_index);
shader.draw(mesh);
- draw_count++;
};
- fm_debug_assert(size_t(mesh_.count()) <= size*quad_index_count);
-
- struct last_ {
- anim_atlas* atlas = nullptr; size_t run_from = 0;
- operator bool() const { return atlas; }
- last_& operator=(std::nullptr_t) { atlas = nullptr; return *this; }
- } last;
- size_t i = 0;
+ uint32_t i = 0;
- for (auto k = 0uz; k < size; k++)
+ for (const auto& x : es)
{
- fm_assert(es[k].e);
- auto& e = *es[k].e;
+ fm_assert(x.e);
+ add_clickable(shader, win_size, x.data.in, x.data, list);
+ auto& e = *x.e;
auto& atlas = *e.atlas;
- if (last.atlas && &atlas != last.atlas)
+ fm_assert(e.is_dynamic() == (x.mesh_idx == (uint32_t)-1));
+ if (!e.is_dynamic())
{
- //Debug{} << "draw-static" << es[last.run_from].e->atlas->name() << es[last.run_from].e->ordinal() << Vector2i(es[last.run_from].e->coord.local()) << i - last.run_from;
- do_draw(last.run_from, i, last.atlas);
- last = {};
+ fm_assert(i < size);
+ do_draw(shader, mesh_, &atlas, x.mesh_idx, max_index);
+ i++;
}
- if (e.is_dynamic())
+ else
{
const auto depth0 = e.depth_offset();
const auto depth1 = depth0[1]*TILE_MAX_DIM + depth0[0];
const auto depth = tile_shader::depth_value(e.coord.local(), depth1);
- //Debug{} << "draw-dyn" << e.atlas->name() << e.ordinal() << Vector2i(e.coord.local());
draw(shader, atlas, e.r, e.frame, e.coord.local(), e.offset, depth);
- last = {};
- }
- else
- {
- if (!last.atlas)
- last = { &atlas, i };
- i++;
}
}
- if (last.atlas && i != last.run_from)
- {
- //Debug{} << "draw-last" << last.atlas->name() << es[es.size()-1].e->ordinal() << Vector2i(es[es.size()-1].e->coord.local()) << i - last.run_from;
- do_draw(last.run_from, i, last.atlas);
- }
-
- //Debug{} << "--" << i << draw_count << "--"; std::fflush(stdout);
}
void anim_mesh::draw(tile_shader& shader, anim_atlas& atlas, rotation r, size_t frame, const Vector3& center, float depth)
diff --git a/src/chunk-scenery.cpp b/src/chunk-scenery.cpp
index 66f6a733..f2c1c80a 100644
--- a/src/chunk-scenery.cpp
+++ b/src/chunk-scenery.cpp
@@ -61,7 +61,9 @@ static void topo_dfs(Array<chunk::entity_draw_order>& array, size_t& output, siz
topo_dfs(array, output, j, size);
}
fm_assert(output < size);
- array[output++].e = data_i.in;
+ array[output].e = data_i.in;
+ array[output].mesh_idx = data_i.in_mesh_idx;
+ output++;
}
static void topological_sort(Array<chunk::entity_draw_order>& array, size_t size)
@@ -74,7 +76,7 @@ static void topological_sort(Array<chunk::entity_draw_order>& array, size_t size
fm_assert(output == size);
}
-auto chunk::make_topo_sort_data(entity& e) -> topo_sort_data
+auto chunk::make_topo_sort_data(entity& e, uint32_t mesh_idx) -> topo_sort_data
{
const auto& a = *e.atlas;
const auto& f = a.frame(e.r, e.frame);
@@ -83,8 +85,10 @@ auto chunk::make_topo_sort_data(entity& e) -> topo_sort_data
const auto px_start = pos - Vector2(e.bbox_offset) - Vector2(f.ground), px_end = px_start + Vector2(f.size);
topo_sort_data data = {
.in = &e,
- .min = Vector2i(px_start), .max = Vector2i(px_end),
+ .min = Vector2i(px_start),
+ .max = Vector2i(px_end),
.center = Vector2i(pos),
+ .in_mesh_idx = mesh_idx,
.ord = e.ordinal(),
};
if (e.type() == entity_type::scenery && !e.is_dynamic())
@@ -124,23 +128,13 @@ auto chunk::ensure_scenery_mesh(Array<entity_draw_order>& array) noexcept -> sce
{
fm_assert(_entities_sorted);
- const auto size = _entities.size();
-
- ensure_scenery_draw_array(array);
- for (auto i = 0uz; const auto& e : _entities)
- array[i++] = { e.get(), e->ordinal(), make_topo_sort_data(*e) };
- std::sort(array.begin(), array.begin() + size, [](const auto& a, const auto& b) { return a.ord < b.ord; });
- topological_sort(array, size);
-
- const auto es = ArrayView<entity_draw_order>{array, size};
-
if (_scenery_modified)
{
_scenery_modified = false;
const auto count = fm_begin(
size_t ret = 0;
- for (const auto& [e, ord, _data] : es)
+ for (const auto& e : _entities)
ret += !e->is_dynamic();
return ret;
);
@@ -150,7 +144,7 @@ auto chunk::ensure_scenery_mesh(Array<entity_draw_order>& array) noexcept -> sce
scenery_vertexes.clear();
scenery_vertexes.reserve(count);
- for (const auto& [e, ord, _data] : es)
+ for (const auto& e : _entities)
{
if (e->is_dynamic())
continue;
@@ -178,9 +172,18 @@ auto chunk::ensure_scenery_mesh(Array<entity_draw_order>& array) noexcept -> sce
scenery_mesh = Utility::move(mesh);
}
- fm_assert(!size || es);
+ const auto size = _entities.size();
+ ensure_scenery_draw_array(array);
+ uint32_t j = 0;
+ for (uint32_t i = 0; const auto& e : _entities)
+ {
+ auto index = e->is_dynamic() ? (uint32_t)-1 : j++;
+ array[i++] = { e.get(), (uint32_t)-1, e->ordinal(), make_topo_sort_data(*e, index) };
+ }
+ std::sort(array.begin(), array.begin() + size, [](const auto& a, const auto& b) { return a.ord < b.ord; });
+ topological_sort(array, size);
- return { scenery_mesh, es, size };
+ return { scenery_mesh, ArrayView<entity_draw_order>{array, size}, j };
}
void chunk::ensure_scenery_draw_array(Array<entity_draw_order>& array)
diff --git a/src/chunk-scenery.hpp b/src/chunk-scenery.hpp
index cbe2ea83..1363479b 100644
--- a/src/chunk-scenery.hpp
+++ b/src/chunk-scenery.hpp
@@ -11,6 +11,7 @@ struct chunk::topo_sort_data
entity* in = nullptr;
Vector2i min, max, center;
+ uint32_t in_mesh_idx;
float slope = 0, ord;
Vector2s bb_min = {}, bb_max = {};
m mode : 2 = mode_none;
@@ -21,6 +22,7 @@ struct chunk::topo_sort_data
struct chunk::entity_draw_order
{
entity *e;
+ uint32_t mesh_idx;
float ord;
topo_sort_data data;
};
diff --git a/src/chunk.hpp b/src/chunk.hpp
index ae19ad62..c98ae9a3 100644
--- a/src/chunk.hpp
+++ b/src/chunk.hpp
@@ -138,7 +138,7 @@ private:
_entities_sorted : 1 = true;
void ensure_scenery_draw_array(Array<entity_draw_order>& array);
- static topo_sort_data make_topo_sort_data(entity& e);
+ static topo_sort_data make_topo_sort_data(entity& e, uint32_t mesh_idx);
struct bbox final // NOLINT(cppcoreguidelines-pro-type-member-init)
{