diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2022-02-21 14:29:22 +0100 |
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-02-21 14:29:22 +0100 |
| commit | 5eb4ae08d5cd81f7315998394054aa50e52b6870 (patch) | |
| tree | 1174490ccb5cbcb4167d715a30d385e796beb25d | |
| parent | b8aa39d289c605b13bb550b786cba3f646fa5b48 (diff) | |
buffer flush
| -rw-r--r-- | atlas.cpp | 4 | ||||
| -rw-r--r-- | atlas.hpp | 2 | ||||
| -rw-r--r-- | defs.hpp | 43 | ||||
| -rw-r--r-- | hash.hpp | 24 | ||||
| -rw-r--r-- | loader-impl.cpp | 1 | ||||
| -rw-r--r-- | main.cpp | 3 | ||||
| -rw-r--r-- | tile.cpp | 16 | ||||
| -rw-r--r-- | tile.hpp | 117 |
8 files changed, 201 insertions, 9 deletions
@@ -1,4 +1,5 @@ #include "atlas.hpp" +#include "defs.hpp" #include <Magnum/ImageView.h> #include <Magnum/GL/TextureFormat.h> @@ -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); } @@ -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 @@ -1,24 +1,59 @@ #pragma once +#include <cstddef> #include <cstdio> -#include <exception> +#include <limits> +#include <type_traits> + +#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<std::size_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<ssize_t>::min(); + ssize_t max = std::numeric_limits<ssize_t>::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 <cstdint> + +namespace Magnum::Examples { + +template<unsigned N = sizeof(std::size_t)*8> 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 <string> #include <unordered_map> #include <utility> -#include <optional> namespace Magnum::Examples { @@ -2,10 +2,8 @@ #include "loader.hpp" #include "tile-shader.hpp" -#include <Corrade/Containers/Optional.h> #include <Corrade/Containers/ArrayViewStl.h> #include <Corrade/PluginManager/Manager.h> -#include <Corrade/Utility/Resource.h> #include <Magnum/Magnum.h> #include <Magnum/Math/Vector.h> #include <Magnum/ImageView.h> @@ -16,7 +14,6 @@ #include <Magnum/GL/TextureFormat.h> #include <Magnum/Platform/Sdl2Application.h> #include <Magnum/Trade/AbstractImporter.h> -#include <Magnum/Trade/ImageData.h> #include <Magnum/GlmIntegration/Integration.h> #include <glm/glm.hpp> 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 <limits> + +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 <cstddef> +#include <tuple> +#include <array> +#include <memory> +#include <unordered_map> +#include <utility> + +namespace Magnum::Examples { + +struct tile_image final : std::tuple<atlas_ptr, UnsignedByte> +{ + 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<UnsignedByte, UnsignedByte> { + constexpr std::size_t to_index() const noexcept; +}; + +struct chunk_coords final : std::pair<Short, Short> { + constexpr std::size_t to_index() const noexcept; +}; + +struct global_coords final : std::pair<chunk_coords, local_coords> {}; + +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<UnsignedByte, TILE_COUNT>; + 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<chunk&>(*this).tile(xy); } + constexpr struct tile& operator[](std::size_t i); + + template<typename F> constexpr inline void foreach_tile(F&& fun) { foreach_tile_<F, chunk&>(fun); } + template<typename F> constexpr inline void foreach_tile(F&& fun) const { foreach_tile_<F, const chunk&>(fun); } + +private: + template<typename F, typename Self> constexpr void foreach_tile_(F&& fun); + std::array<struct tile, TILE_COUNT> 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<typename F, typename Self> +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<Self>(*this).tiles[idx]); + } +} + +constexpr std::size_t chunk_coords::to_index() const noexcept +{ + using unsigned_type = std::make_unsigned_t<decltype(second)>; + using limits = std::numeric_limits<unsigned_type>; + 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<sizeof(std::size_t)*8>{}(xy.to_index()); + } +}; + +struct world final +{ + explicit world(); + +private: + std::unordered_map<chunk_coords, std::shared_ptr<chunk>, hash_chunk> chunks; +}; + +} //namespace Magnum::Examples |
