diff options
-rw-r--r-- | draw/anim.cpp | 54 | ||||
-rw-r--r-- | src/chunk-scenery.cpp | 37 | ||||
-rw-r--r-- | src/chunk-scenery.hpp | 2 | ||||
-rw-r--r-- | src/chunk.hpp | 2 |
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) { |