From 5eb4ae08d5cd81f7315998394054aa50e52b6870 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 21 Feb 2022 14:29:22 +0100 Subject: buffer flush --- atlas.cpp | 4 +- atlas.hpp | 2 + defs.hpp | 43 +++++++++++++++++++-- hash.hpp | 24 ++++++++++++ loader-impl.cpp | 1 - main.cpp | 3 -- tile.cpp | 16 ++++++++ tile.hpp | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 201 insertions(+), 9 deletions(-) create mode 100644 hash.hpp create mode 100644 tile.cpp create mode 100644 tile.hpp diff --git a/atlas.cpp b/atlas.cpp index 4e384540..1463c26a 100644 --- a/atlas.cpp +++ b/atlas.cpp @@ -1,4 +1,5 @@ #include "atlas.hpp" +#include "defs.hpp" #include #include @@ -12,10 +13,11 @@ atlas_texture::atlas_texture(const Trade::ImageData2D& image, Vector2i dims) : CORRADE_INTERNAL_ASSERT(dims_[0] > 0 && dims_[1] > 0); CORRADE_INTERNAL_ASSERT(tile_size_ * dims_ == size_); CORRADE_INTERNAL_ASSERT(size_ % dims_ == Vector2i{}); + CORRADE_INTERNAL_ASSERT(dims.product() < 256); tex_.setWrapping(GL::SamplerWrapping::ClampToEdge) .setMagnificationFilter(GL::SamplerFilter::Linear) .setMinificationFilter(GL::SamplerFilter::Linear) - .setStorage(1, GL::textureFormat(image.format()), image.size()) + .setStorage(MIPMAP_LEVEL, GL::textureFormat(image.format()), image.size()) .setSubImage(0, {}, image); } diff --git a/atlas.hpp b/atlas.hpp index 1b2a4e15..5e45a1fc 100644 --- a/atlas.hpp +++ b/atlas.hpp @@ -21,6 +21,8 @@ struct atlas_texture final private: GL::Texture2D tex_; Vector2i size_, dims_, tile_size_; + + static constexpr int MIPMAP_LEVEL = 1; }; } // namespace Magnum::Examples diff --git a/defs.hpp b/defs.hpp index a2f5d240..f680c4b9 100644 --- a/defs.hpp +++ b/defs.hpp @@ -1,24 +1,59 @@ #pragma once +#include #include -#include +#include +#include + +#ifdef _MSC_VER +# define FUNCTION_NAME __FUNCSIG__ +#else +# define FUNCTION_NAME __PRETTY_FUNCTION__ +#endif namespace Magnum::Examples { -struct assertion_failure final : std::exception -{ +using size_t = std::size_t; +using ssize_t = std::make_signed_t; + +struct exception { const char* file = nullptr; + const char* function = nullptr; int line = -1; +}; + +struct assertion_failure final : exception +{ char msg[128 - sizeof(int) - sizeof(char*)]; +}; + +struct out_of_range final : exception { + ssize_t value = 0; + ssize_t min = std::numeric_limits::min(); + ssize_t max = std::numeric_limits::max(); +}; - const char* what() const noexcept override { return msg; } +struct key_error final : exception { + ssize_t value = 0; }; } // namespace Magnum::Examples +#define KEY_ERROR(value) \ + ::Magnum::Examples::key_error{{__FILE__, FUNCTION_NAME, __LINE__}, (value)} + +#define OUT_OF_RANGE(value, min, max) \ + ::Magnum::Examples::out_of_range{ \ + {__FILE__, FUNCTION_NAME, __LINE__}, \ + ::Magnum::Examples::ssize_t((value)), \ + ::Magnum::Examples::ssize_t((min)), \ + ::Magnum::Examples::ssize_t((max)) \ + } + #define ABORT_WITH(exc_type, ...) ([&]() { \ exc_type _e; \ _e.line = __LINE__; \ _e.file = __FILE__; \ + _e.function = FUNCTION_NAME; \ std::snprintf(_e.msg, sizeof(_e.msg), __VA_ARGS__); \ throw _e; \ }()) diff --git a/hash.hpp b/hash.hpp new file mode 100644 index 00000000..c6d74444 --- /dev/null +++ b/hash.hpp @@ -0,0 +1,24 @@ +#pragma once +#include + +namespace Magnum::Examples { + +template struct hash; + +template<> +struct hash<32> final { + [[maybe_unused]] + constexpr std::uint32_t operator()(std::uint32_t x) const noexcept { + return (std::uint32_t)x*0x9e3779b1u; + } +}; + +template<> +struct hash<64> final { + [[maybe_unused]] + constexpr std::uint64_t operator()(std::uint64_t x) const noexcept { + return x*0x9e3779b97f4a7c15ull; + } +}; + +} // namespace Magnum::Examples diff --git a/loader-impl.cpp b/loader-impl.cpp index 96f5930b..63b16a10 100644 --- a/loader-impl.cpp +++ b/loader-impl.cpp @@ -9,7 +9,6 @@ #include #include #include -#include namespace Magnum::Examples { diff --git a/main.cpp b/main.cpp index e134134a..6af9dd7f 100644 --- a/main.cpp +++ b/main.cpp @@ -2,10 +2,8 @@ #include "loader.hpp" #include "tile-shader.hpp" -#include #include #include -#include #include #include #include @@ -16,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/tile.cpp b/tile.cpp new file mode 100644 index 00000000..3fe28959 --- /dev/null +++ b/tile.cpp @@ -0,0 +1,16 @@ +#include "tile.hpp" +#include + +namespace Magnum::Examples { + +chunk::tile_index_type chunk::make_tile_indices() noexcept +{ + tile_index_type array; + for (unsigned i = 0; i < N*N; i++) + array[i] = (UnsignedByte)i; + return array; +} + +world::world() = default; + +} // namespace Magnum::Examples diff --git a/tile.hpp b/tile.hpp new file mode 100644 index 00000000..f47f9077 --- /dev/null +++ b/tile.hpp @@ -0,0 +1,117 @@ +#pragma once +#include "loader.hpp" +#include "atlas.hpp" +#include "hash.hpp" +#include "defs.hpp" + +#include +#include +#include +#include +#include +#include + +namespace Magnum::Examples { + +struct tile_image final : std::tuple +{ + constexpr int variant() const noexcept { return std::get<1>(*this); } + atlas_ptr atlas() const noexcept { return std::get<0>(*this); } +}; + +struct tile final +{ + enum class pass_mode : std::uint8_t { pass_blocked, pass_yes, pass_shoot_through, pass_obscured }; + using enum pass_mode; + + tile_image ground_image_; + pass_mode passability_ = pass_obscured; + + explicit operator bool() const noexcept { return !!std::get<0>(ground_image_); } +}; + +struct local_coords final : std::pair { + constexpr std::size_t to_index() const noexcept; +}; + +struct chunk_coords final : std::pair { + constexpr std::size_t to_index() const noexcept; +}; + +struct global_coords final : std::pair {}; + +struct chunk final +{ + static constexpr std::size_t N = 16; + static constexpr std::size_t TILE_COUNT = N*N; + using tile_index_type = std::array; + static tile_index_type make_tile_indices() noexcept; + + tile_index_type indices = make_tile_indices(); + + constexpr struct tile& tile(local_coords xy); + constexpr struct tile& tile(local_coords xy) const { return const_cast(*this).tile(xy); } + constexpr struct tile& operator[](std::size_t i); + + template constexpr inline void foreach_tile(F&& fun) { foreach_tile_(fun); } + template constexpr inline void foreach_tile(F&& fun) const { foreach_tile_(fun); } + +private: + template constexpr void foreach_tile_(F&& fun); + std::array tiles = {}; +}; + +constexpr std::size_t local_coords::to_index() const noexcept { + return second*chunk::N + first; +} + +constexpr struct tile& chunk::operator[](std::size_t i) { + if (i >= TILE_COUNT) + throw OUT_OF_RANGE(i, 0, TILE_COUNT); + return tiles[i]; +} + +constexpr tile& chunk::tile(local_coords xy) +{ + auto idx = xy.to_index(); + if (idx >= TILE_COUNT) + throw OUT_OF_RANGE(idx, 0, TILE_COUNT); + return tiles[idx]; +} + +template +constexpr void chunk::foreach_tile_(F&& fun) +{ + for (unsigned j = 0; j < N; j++) + for (unsigned i = 0; i < N; i++) + { + unsigned idx = j*N + i; + if (tiles[idx]) + fun(*static_cast(*this).tiles[idx]); + } +} + +constexpr std::size_t chunk_coords::to_index() const noexcept +{ + using unsigned_type = std::make_unsigned_t; + using limits = std::numeric_limits; + constexpr auto N = limits::max() + std::size_t{1}; + static_assert(sizeof(unsigned_type) <= sizeof(std::size_t)/2); + return (std::size_t)(unsigned_type)second * N + (std::size_t)(unsigned_type)first; +} + +struct hash_chunk final { + constexpr std::size_t operator()(chunk_coords xy) const noexcept { + return hash{}(xy.to_index()); + } +}; + +struct world final +{ + explicit world(); + +private: + std::unordered_map, hash_chunk> chunks; +}; + +} //namespace Magnum::Examples -- cgit v1.2.3