diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-09 18:27:32 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-09 18:27:32 +0100 |
commit | 5907a8902e6f01774cebbb515349a66c86a47fb3 (patch) | |
tree | 7d3f90a38e038e0f4acbaf62b328fb23446ab7c7 /draw | |
parent | 1febb02d958fa4cf8c15e3ca18f9d644f9fc80fb (diff) |
allow drawing walls in random order
Diffstat (limited to 'draw')
-rw-r--r-- | draw/anim.cpp | 2 | ||||
-rw-r--r-- | draw/floor.hpp | 3 | ||||
-rw-r--r-- | draw/wall.cpp | 127 | ||||
-rw-r--r-- | draw/wall.hpp | 39 |
4 files changed, 35 insertions, 136 deletions
diff --git a/draw/anim.cpp b/draw/anim.cpp index dac23566..a096711c 100644 --- a/draw/anim.cpp +++ b/draw/anim.cpp @@ -27,7 +27,7 @@ void anim_mesh::draw(tile_shader& shader, const anim_atlas& atlas, rotation r, s const auto center = Vector3(xy.x, xy.y, 0.f) * TILE_SIZE; const auto pos = atlas.frame_quad(center, r, frame); const auto texcoords = atlas.texcoords_for_frame(r, frame); - const float depth = tile_shader::depth_value(xy); + const float depth = tile_shader::depth_value(xy, .25f); quad_data array; for (std::size_t i = 0; i < 4; i++) array[i] = { pos[i], texcoords[i], depth }; diff --git a/draw/floor.hpp b/draw/floor.hpp index bfff7948..74547857 100644 --- a/draw/floor.hpp +++ b/draw/floor.hpp @@ -2,15 +2,12 @@ namespace floormat { -struct tile_ref; struct tile_shader; struct chunk; struct floor_mesh final { floor_mesh(); - floor_mesh(floor_mesh&&) = delete; - floor_mesh(const floor_mesh&) = delete; void draw(tile_shader& shader, chunk& c); }; 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 diff --git a/draw/wall.hpp b/draw/wall.hpp index d65744fd..ace24904 100644 --- a/draw/wall.hpp +++ b/draw/wall.hpp @@ -1,53 +1,16 @@ #pragma once -#include "tile-defs.hpp" -#include "anim.hpp" -#include <array> -#include <Corrade/Containers/ArrayViewStl.h> -#include <Magnum/Math/Vector2.h> -#include <Magnum/Math/Vector3.h> -#include <Magnum/GL/Mesh.h> -#include <Magnum/GL/Buffer.h> - namespace floormat { struct tile_shader; struct chunk; -struct tile_ref; -struct tile_image_ref; struct wall_mesh final { wall_mesh(); - void draw(tile_shader& shader, chunk& c); - -private: - static constexpr auto COUNT1 = TILE_MAX_DIM*2, COUNT = COUNT1 * COUNT1; - - struct vertex final { - Vector2 texcoords; - }; - struct constant final { - Vector3 position; - float depth = -1; - }; - - using quad = std::array<vertex, 4>; - using vertex_array = std::array<quad, COUNT>; - using texture_array = std::array<GL::Texture2D*, COUNT>; - - anim_mesh _anim_mesh; - - static void maybe_add_tile(vertex_array& data, texture_array& textures, tile_ref x, std::size_t pos); - static void add_wall(vertex_array& data, texture_array& textures, const tile_image_ref& img, std::size_t pos); + void draw(tile_shader& shader, chunk& c); - GL::Mesh _mesh; - GL::Buffer _vertex_buffer{vertex_array{}, Magnum::GL::BufferUsage::DynamicDraw}, - _index_buffer{make_index_array()}, - _constant_buffer{make_constant_array()}; - static std::array<std::array<UnsignedShort, 6>, COUNT> make_index_array(); - static std::array<std::array<constant, 4>, COUNT> make_constant_array(); }; } // namespace floormat |