diff options
Diffstat (limited to 'draw/wall.cpp')
-rw-r--r-- | draw/wall.cpp | 127 |
1 files changed, 33 insertions, 94 deletions
diff --git a/draw/wall.cpp b/draw/wall.cpp index 0096946e..2008fe05 100644 --- a/draw/wall.cpp +++ b/draw/wall.cpp @@ -9,110 +9,49 @@ namespace floormat { -constexpr auto quad_index_count = 6; +#define FM_DEBUG_DRAW_COUNT -wall_mesh::wall_mesh() -{ - _mesh.setCount((int)(quad_index_count * COUNT)) - .addVertexBuffer(_vertex_buffer, 0, tile_shader::TextureCoordinates{}) - .addVertexBuffer(_constant_buffer, 0, tile_shader::Position{}, tile_shader::Depth{}) - .setIndexBuffer(_index_buffer, 0, GL::MeshIndexType::UnsignedShort); - CORRADE_INTERNAL_ASSERT(_mesh.isIndexed()); -} - -void wall_mesh::add_wall(vertex_array& data, texture_array& textures, const tile_image_ref& img, std::size_t pos) -{ - CORRADE_INTERNAL_ASSERT(pos < data.size()); - auto texcoords = img.atlas->texcoords_for_id(img.variant); - for (std::size_t i = 0; i < 4; i++) - { - data[pos][i] = { texcoords[i] }; - textures[pos] = &img.atlas->texture(); - } -} +constexpr auto quad_index_count = 6; -void wall_mesh::maybe_add_tile(vertex_array& data, texture_array& textures, tile_ref x, std::size_t pos) -{ - if (auto wall = x.wall_north(); wall.atlas) - add_wall(data, textures, wall, pos * 2 + 0); - if (auto wall = x.wall_west(); wall.atlas) - add_wall(data, textures, wall, pos * 2 + 1); -} +wall_mesh::wall_mesh() = default; void wall_mesh::draw(tile_shader& shader, chunk& c) { - //_texcoord_buffer.setData({nullptr, sizeof(vertex_array)}, Magnum::GL::BufferUsage::DynamicDraw); // orphan the buffer - texture_array textures = {}; - { - vertex_array data; - for (auto [x, idx, pt] : c) { - maybe_add_tile(data, textures, x, idx); - } - _vertex_buffer.setSubData(0, data); - } + auto [mesh_, ids_n, ids_w] = c.ensure_wall_mesh(); - const GL::Texture2D* last_texture = nullptr; - Magnum::GL::MeshView mesh{_mesh}; - for (std::size_t idx = 0; idx < TILE_COUNT; idx++) - { - for (std::size_t i = idx*2; i <= idx*2+1; i++) - if (auto* const tex = textures[i]; tex) - { - mesh.setCount(quad_index_count); - mesh.setIndexRange((int)(i*quad_index_count), 0, quad_index_count*COUNT - 1); - if (tex != last_texture) - tex->bind(0); - last_texture = tex; - shader.draw(mesh); - } - if (auto a = c[idx].scenery(); a.atlas) - { - auto& tex = a.atlas->texture(); - if (&tex != last_texture) - tex.bind(0); - last_texture = &a.atlas->texture(); - auto frame = a.frame; -#if 1 - static std::size_t f = 0; - f++; - if (f > a.atlas->info().nframes * 3) - f = 0; - frame.frame = (scenery::frame_t)std::min(f, a.atlas->info().nframes - 1); -#endif - _anim_mesh.draw(shader, *a.atlas, a.frame.r, frame.frame, local_coords{idx}); - } - } -} + tile_atlas* last_atlas = nullptr; + std::size_t last_pos = 0; + GL::MeshView mesh{mesh_}; -std::array<std::array<UnsignedShort, 6>, wall_mesh::COUNT> wall_mesh::make_index_array() -{ - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) - std::array<std::array<UnsignedShort, 6>, COUNT> array; + [[maybe_unused]] std::size_t draw_count = 0; - for (std::size_t i = 0; i < std::size(array); i++) - array[i] = tile_atlas::indices(i); - return array; -} - -auto wall_mesh::make_constant_array() -> std::array<std::array<constant, 4>, wall_mesh::COUNT> -{ - std::array<std::array<constant, 4>, COUNT> array; - for (std::uint8_t j = 0; j < TILE_MAX_DIM; j++) - for (std::uint8_t i = 0; i < TILE_MAX_DIM; i++) + const auto do_draw = [&](std::size_t i, tile_atlas* atlas) { + if (atlas == last_atlas) + return; + if (auto len = i - last_pos; last_atlas && len > 0) { - const local_coords coord{i, j}; - const std::size_t idx = coord.to_index() * 2u; - const auto center = Vector3(i, j, 0) * TILE_SIZE; - auto wall_n_pos = tile_atlas::wall_quad_N(center, TILE_SIZE); - auto wall_w_pos = tile_atlas::wall_quad_W(center, TILE_SIZE); - auto depth = tile_shader::depth_value(coord); - for (std::size_t k = 0; k < 4; k++) - { - array[idx + 0][k] = { wall_n_pos[k], depth, }; - array[idx + 1][k] = { wall_w_pos[k], depth, }; - } + last_atlas->texture().bind(0); + mesh.setCount((int)(quad_index_count * len)); + mesh.setIndexRange((int)(last_pos*quad_index_count), 0, quad_index_count*TILE_COUNT - 1); + shader.draw(mesh); + draw_count++; } - return array; + last_atlas = atlas; + last_pos = i; + }; + + for (std::size_t k = 0; k < TILE_COUNT; k++) + if (auto* atlas = c.wall_n_atlas_at(ids_n[k])) + do_draw(k, atlas); + for (std::size_t k = 0; k < TILE_COUNT; k++) + if (auto* atlas = c.wall_w_atlas_at(ids_w[k])) + do_draw(k + TILE_COUNT, atlas); + do_draw(TILE_COUNT*2, nullptr); + +#ifdef FM_DEBUG_DRAW_COUNT + if (draw_count) + fm_debug("wall draws: %zu", draw_count); +#endif } } // namespace floormat |