summaryrefslogtreecommitdiffhomepage
path: root/draw
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-11-09 18:27:32 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-11-09 18:27:32 +0100
commit5907a8902e6f01774cebbb515349a66c86a47fb3 (patch)
tree7d3f90a38e038e0f4acbaf62b328fb23446ab7c7 /draw
parent1febb02d958fa4cf8c15e3ca18f9d644f9fc80fb (diff)
allow drawing walls in random order
Diffstat (limited to 'draw')
-rw-r--r--draw/anim.cpp2
-rw-r--r--draw/floor.hpp3
-rw-r--r--draw/wall.cpp127
-rw-r--r--draw/wall.hpp39
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