From 66ee29df9c19e35b4c126e12e48bc144fe72eb22 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 6 Oct 2022 07:11:48 +0200 Subject: a --- CMakeLists.txt | 31 +++--- anim-crop-tool/CMakeLists.txt | 2 +- loader-impl.cpp | 89 ----------------- main.cpp | 224 ------------------------------------------ main/CMakeLists.txt | 8 ++ main/loader-impl.cpp | 89 +++++++++++++++++ main/main.cpp | 222 +++++++++++++++++++++++++++++++++++++++++ serialize/CMakeLists.txt | 5 - serialize/tile-atlas.cpp | 42 ++++++++ serialize/tile-atlas.hpp | 27 ++--- tile-atlas.hpp | 4 +- 11 files changed, 387 insertions(+), 356 deletions(-) delete mode 100644 loader-impl.cpp delete mode 100644 main.cpp create mode 100644 main/CMakeLists.txt create mode 100644 main/loader-impl.cpp create mode 100644 main/main.cpp delete mode 100644 serialize/CMakeLists.txt create mode 100644 serialize/tile-atlas.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e5ef563..dc24f387 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,28 +55,25 @@ if(NOT BOOTSTRAP_DEPENDS) find_package(MagnumPlugins QUIET REQUIRED) find_package(MagnumIntegration QUIET REQUIRED COMPONENTS Glm) - include_directories("${CMAKE_CURRENT_SOURCE_DIR}") - include_directories(.) - add_subdirectory(anim-crop-tool) - add_subdirectory(serialize) - - corrade_add_resource(game_RESOURCES resources.conf) file(GLOB sources "*.cpp" "shaders/*.cpp" "serialize/*.cpp" CONFIGURE_ARGS) - - add_executable(${PROJECT_NAME} WIN32 "${sources}" "${game_RESOURCES}") - target_link_libraries(${PROJECT_NAME} PRIVATE - Magnum::Application - Magnum::GL - Magnum::Magnum - Magnum::Shaders - Magnum::Trade - MagnumIntegration::Glm - nlohmann_json::nlohmann_json - ) + add_library(${PROJECT_NAME} STATIC "${sources}") + target_link_libraries( + ${PROJECT_NAME} PUBLIC + Magnum::GL + Magnum::Magnum + Magnum::Shaders + nlohmann_json::nlohmann_json + ) target_include_directories(${PROJECT_NAME} PRIVATE ${GLM_INCLUDE_DIRS}) target_include_directories(${PROJECT_NAME} PRIVATE magnum-integration/src) + + add_subdirectory(main) + add_subdirectory(anim-crop-tool) + + install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) + install(DIRECTORY images DESTINATION /src) install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) install(DIRECTORY images DESTINATION "share/${PROJECT_NAME}") endif() diff --git a/anim-crop-tool/CMakeLists.txt b/anim-crop-tool/CMakeLists.txt index 76304068..6e7863e6 100644 --- a/anim-crop-tool/CMakeLists.txt +++ b/anim-crop-tool/CMakeLists.txt @@ -3,8 +3,8 @@ set(self "${PROJECT_NAME}-anim-crop-tool") include_directories(SYSTEM PRIVATE ${OpenCV_INCLUDE_DIRS}) link_libraries(Corrade::Utility Magnum::Magnum) -link_libraries("${PROJECT_NAME}-serialize") link_libraries(opencv_imgproc opencv_imgcodecs opencv_core) +link_libraries(${PROJECT_NAME}) file(GLOB sources "*.cpp" CONFIGURE_ARGS) add_executable(${self} ${sources}) diff --git a/loader-impl.cpp b/loader-impl.cpp deleted file mode 100644 index 24d43fdb..00000000 --- a/loader-impl.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "loader.hpp" -#include "tile-atlas.hpp" -#include "compat/assert.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Magnum::Examples { - -struct loader_impl final : loader_ -{ - std::optional shader_res; - PluginManager::Manager importer_plugins; - Containers::Pointer tga_importer = - importer_plugins.loadAndInstantiate("AnyImageImporter"); - - PluginManager::Manager image_converter_plugins; - Containers::Pointer tga_converter = - image_converter_plugins.loadAndInstantiate("AnyImageConverter"); - - std::unordered_map> atlas_map; - - std::string shader(const Containers::StringView& filename) override; - Trade::ImageData2D tile_texture(const Containers::StringView& filename) override; - std::shared_ptr tile_atlas(const Containers::StringView& filename, Vector2i size) override; - - explicit loader_impl(); - ~loader_impl() override; -}; - -std::string loader_impl::shader(const Containers::StringView& filename) -{ - if (!shader_res) - shader_res = std::make_optional("game/shaders"); - auto ret = shader_res->getString(filename); - if (ret.isEmpty()) - ABORT("can't find shader resource '%s'", filename.cbegin()); - return ret; -} - -std::shared_ptr loader_impl::tile_atlas(const Containers::StringView& name, Vector2i size) -{ - auto it = atlas_map.find(name); - if (it != atlas_map.end()) - return it->second; - auto image = tile_texture(name); - auto atlas = std::make_shared(name, image, size); - atlas_map[name] = atlas; - return atlas; -} - -Trade::ImageData2D loader_impl::tile_texture(const Containers::StringView& filename) -{ - if(!tga_importer || !tga_importer->openFile(filename)) - ABORT("can't open tile image '%s'", filename.cbegin()); - auto img = tga_importer->image2D(0); - if (!img) - ABORT("can't allocate tile image for '%s'", filename.cbegin()); - auto ret = std::move(*img); - return ret; -} - -void loader_::destroy() -{ - loader.~loader_(); - new (&loader) loader_impl(); -} - -loader_impl::loader_impl() = default; -loader_impl::~loader_impl() = default; - -static loader_& make_default_loader() -{ - static loader_impl loader_singleton{}; - return loader_singleton; -} - -// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) -loader_& loader = make_default_loader(); - -} // namespace Magnum::Examples diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 208579fb..00000000 --- a/main.cpp +++ /dev/null @@ -1,224 +0,0 @@ -#include "tile-atlas.hpp" -#include "loader.hpp" -#include "shaders/tile-shader.hpp" -#include "tile.hpp" -#include "chunk.hpp" -#include "floor-mesh.hpp" -#include "wall-mesh.hpp" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "serialize/tile-atlas.hpp" //test - -namespace Magnum::Examples { - -template -struct enum_bitset : std::bitset<(std::size_t)enum_type::MAX> { - static_assert(std::is_same_v>>); - static_assert(std::is_same_v>); - using std::bitset<(std::size_t)enum_type::MAX>::bitset; - constexpr bool operator[](enum_type x) const { return operator[]((std::size_t)x); } - constexpr decltype(auto) operator[](enum_type x) { - return std::bitset<(std::size_t)enum_type::MAX>::operator[]((std::size_t)x); - } -}; - -struct app final : Platform::Application -{ - using dpi_policy = Platform::Implementation::Sdl2DpiScalingPolicy; - using tile_atlas_ = std::shared_ptr; - - explicit app(const Arguments& arguments); - virtual ~app(); - void drawEvent() override; - void update(float dt); - void do_camera(float dt); - void reset_camera_offset(); - void keyPressEvent(KeyEvent& event) override; - void keyReleaseEvent(KeyEvent& event) override; - void do_key(KeyEvent::Key k, KeyEvent::Modifiers m, bool pressed, bool repeated); - void draw_chunk(chunk& c); - void update_window_scale(); - - enum class key : int { - camera_up, camera_left, camera_right, camera_down, camera_reset, - quit, - MAX - }; - chunk make_test_chunk(); - - tile_shader _shader; - tile_atlas_ floor1 = loader.tile_atlas("../share/game/images/metal1.tga", {2, 2}); - tile_atlas_ floor2 = loader.tile_atlas("../share/game/images/floor1.tga", {4, 4}); - tile_atlas_ wall1 = loader.tile_atlas("../share/game/images/metal2.tga", {2, 2}); - tile_atlas_ wall2 = loader.tile_atlas("../share/game/images/wood1.tga", {2, 2}); - chunk _chunk = make_test_chunk(); - floor_mesh _floor_mesh; - wall_mesh _wall_mesh; - - Vector2 camera_offset; - enum_bitset keys; - Magnum::Timeline timeline; -}; - -using namespace Math::Literals; - -chunk app::make_test_chunk() -{ - constexpr auto N = TILE_MAX_DIM; - chunk c; - c.foreach_tile([&, this](tile& x, std::size_t k, local_coords pt) { - const auto& atlas = pt.x > N/2 && pt.y >= N/2 ? floor2 : floor1; - x.ground_image = { atlas, (std::uint8_t)(k % atlas->size()) }; - }); - constexpr auto K = N/2; - c[{K, K }].wall_north = { wall1, 0 }; - c[{K, K }].wall_west = { wall2, 0 }; - c[{K, K+1}].wall_north = { wall1, 0 }; - c[{K+1, K }].wall_west = { wall2, 0 }; - return c; -} - -void app::update_window_scale() -{ - auto sz = windowSize(); - _shader.set_scale({ (float)sz[0], (float)sz[1] }); -} - -void app::draw_chunk(chunk& c) -{ - _floor_mesh.draw(_shader, c); - _wall_mesh.draw(_shader, c); -} - -app::app(const Arguments& arguments): - Platform::Application{ - arguments, - Configuration{} - .setTitle("Test") - .setSize({1024, 768}, dpi_policy::Physical), - GLConfiguration{} - //.setSampleCount(16) - } -{ - reset_camera_offset(); - timeline.start(); -} - -void app::drawEvent() { -#if 0 - GL::defaultFramebuffer.clear(GL::FramebufferClear::Color | GL::FramebufferClear::Depth); - GL::Renderer::setDepthMask(true); - GL::Renderer::setDepthFunction(GL::Renderer::DepthFunction::LessOrEqual); - GL::Renderer::enable(GL::Renderer::Feature::DepthTest); -#else - GL::defaultFramebuffer.clear(GL::FramebufferClear::Color); - GL::Renderer::setDepthFunction(GL::Renderer::DepthFunction::Never); -#endif - - update_window_scale(); - { - float dt = timeline.previousFrameDuration(); - update(dt); - } - - draw_chunk(_chunk); - - swapBuffers(); - redraw(); - timeline.nextFrame(); -} - -void app::do_camera(float dt) -{ - constexpr float pixels_per_second = 512; - if (keys[key::camera_up]) - camera_offset += Vector2(0, 1) * dt * pixels_per_second; - else if (keys[key::camera_down]) - camera_offset += Vector2(0, -1) * dt * pixels_per_second; - if (keys[key::camera_left]) - camera_offset += Vector2(1, 0) * dt * pixels_per_second; - else if (keys[key::camera_right]) - camera_offset += Vector2(-1, 0) * dt * pixels_per_second; - - _shader.set_camera_offset(camera_offset); - - if (keys[key::camera_reset]) - reset_camera_offset(); -} - -void app::reset_camera_offset() -{ - camera_offset = _shader.project({TILE_MAX_DIM*TILE_SIZE[0]/2.f, TILE_MAX_DIM*TILE_SIZE[1]/2.f, 0}); - //camera_offset = {}; -} - -void app::update(float dt) -{ - do_camera(dt); - if (keys[key::quit]) - Platform::Sdl2Application::exit(0); -} - -void app::do_key(KeyEvent::Key k, KeyEvent::Modifiers m, bool pressed, bool repeated) -{ - //using Mods = KeyEvent::Modifiers; - - (void)m; - (void)repeated; - - const key x = progn(switch (k) { - using enum KeyEvent::Key; - using enum key; - - case W: return camera_up; - case A: return camera_left; - case S: return camera_down; - case D: return camera_right; - case Home: return camera_reset; - case Esc: return quit; - default: return MAX; - }); - - if (x != key::MAX) - keys[x] = pressed; -} - -app::~app() -{ - loader_::destroy(); -} - -void app::keyPressEvent(Platform::Sdl2Application::KeyEvent& event) -{ - do_key(event.key(), event.modifiers(), true, event.isRepeated()); -} - -void app::keyReleaseEvent(Platform::Sdl2Application::KeyEvent& event) -{ - do_key(event.key(), event.modifiers(), false, false); -} - -} // namespace Magnum::Examples - -MAGNUM_APPLICATION_MAIN(Magnum::Examples::app) - -#ifdef _MSC_VER -# include -# ifdef __clang__ -# pragma clang diagnostic ignored "-Wmissing-prototypes" -# pragma clang diagnostic ignored "-Wmain" -# endif - -extern "C" int __stdcall WinMain(void*, void*, void*, int /* nCmdShow */) { - return main(__argc, __argv); -} -#endif diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 00000000..cb3b1f2c --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,8 @@ +set(self "${PROJECT_NAME}-main") +file(GLOB sources "*.cpp" CONFIGURE_ARGS) + +link_libraries(${PROJECT_NAME} + Magnum::Application Magnum::Trade MagnumIntegration::Glm) +corrade_add_resource(res ../resources.conf) +add_executable(${self} WIN32 "${sources}" "${res}") +set_property(TARGET ${self} PROPERTY OUTPUT_NAME "${PROJECT_NAME}") diff --git a/main/loader-impl.cpp b/main/loader-impl.cpp new file mode 100644 index 00000000..24d43fdb --- /dev/null +++ b/main/loader-impl.cpp @@ -0,0 +1,89 @@ +#include "loader.hpp" +#include "tile-atlas.hpp" +#include "compat/assert.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Magnum::Examples { + +struct loader_impl final : loader_ +{ + std::optional shader_res; + PluginManager::Manager importer_plugins; + Containers::Pointer tga_importer = + importer_plugins.loadAndInstantiate("AnyImageImporter"); + + PluginManager::Manager image_converter_plugins; + Containers::Pointer tga_converter = + image_converter_plugins.loadAndInstantiate("AnyImageConverter"); + + std::unordered_map> atlas_map; + + std::string shader(const Containers::StringView& filename) override; + Trade::ImageData2D tile_texture(const Containers::StringView& filename) override; + std::shared_ptr tile_atlas(const Containers::StringView& filename, Vector2i size) override; + + explicit loader_impl(); + ~loader_impl() override; +}; + +std::string loader_impl::shader(const Containers::StringView& filename) +{ + if (!shader_res) + shader_res = std::make_optional("game/shaders"); + auto ret = shader_res->getString(filename); + if (ret.isEmpty()) + ABORT("can't find shader resource '%s'", filename.cbegin()); + return ret; +} + +std::shared_ptr loader_impl::tile_atlas(const Containers::StringView& name, Vector2i size) +{ + auto it = atlas_map.find(name); + if (it != atlas_map.end()) + return it->second; + auto image = tile_texture(name); + auto atlas = std::make_shared(name, image, size); + atlas_map[name] = atlas; + return atlas; +} + +Trade::ImageData2D loader_impl::tile_texture(const Containers::StringView& filename) +{ + if(!tga_importer || !tga_importer->openFile(filename)) + ABORT("can't open tile image '%s'", filename.cbegin()); + auto img = tga_importer->image2D(0); + if (!img) + ABORT("can't allocate tile image for '%s'", filename.cbegin()); + auto ret = std::move(*img); + return ret; +} + +void loader_::destroy() +{ + loader.~loader_(); + new (&loader) loader_impl(); +} + +loader_impl::loader_impl() = default; +loader_impl::~loader_impl() = default; + +static loader_& make_default_loader() +{ + static loader_impl loader_singleton{}; + return loader_singleton; +} + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) +loader_& loader = make_default_loader(); + +} // namespace Magnum::Examples diff --git a/main/main.cpp b/main/main.cpp new file mode 100644 index 00000000..f58228c6 --- /dev/null +++ b/main/main.cpp @@ -0,0 +1,222 @@ +#include "tile-atlas.hpp" +#include "loader.hpp" +#include "shaders/tile-shader.hpp" +#include "tile.hpp" +#include "chunk.hpp" +#include "floor-mesh.hpp" +#include "wall-mesh.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace Magnum::Examples { + +template +struct enum_bitset : std::bitset<(std::size_t)enum_type::MAX> { + static_assert(std::is_same_v>>); + static_assert(std::is_same_v>); + using std::bitset<(std::size_t)enum_type::MAX>::bitset; + constexpr bool operator[](enum_type x) const { return operator[]((std::size_t)x); } + constexpr decltype(auto) operator[](enum_type x) { + return std::bitset<(std::size_t)enum_type::MAX>::operator[]((std::size_t)x); + } +}; + +struct app final : Platform::Application +{ + using dpi_policy = Platform::Implementation::Sdl2DpiScalingPolicy; + using tile_atlas_ = std::shared_ptr; + + explicit app(const Arguments& arguments); + virtual ~app(); + void drawEvent() override; + void update(float dt); + void do_camera(float dt); + void reset_camera_offset(); + void keyPressEvent(KeyEvent& event) override; + void keyReleaseEvent(KeyEvent& event) override; + void do_key(KeyEvent::Key k, KeyEvent::Modifiers m, bool pressed, bool repeated); + void draw_chunk(chunk& c); + void update_window_scale(); + + enum class key : int { + camera_up, camera_left, camera_right, camera_down, camera_reset, + quit, + MAX + }; + chunk make_test_chunk(); + + tile_shader _shader; + tile_atlas_ floor1 = loader.tile_atlas("../share/game/images/metal1.tga", {2, 2}); + tile_atlas_ floor2 = loader.tile_atlas("../share/game/images/floor1.tga", {4, 4}); + tile_atlas_ wall1 = loader.tile_atlas("../share/game/images/metal2.tga", {2, 2}); + tile_atlas_ wall2 = loader.tile_atlas("../share/game/images/wood1.tga", {2, 2}); + chunk _chunk = make_test_chunk(); + floor_mesh _floor_mesh; + wall_mesh _wall_mesh; + + Vector2 camera_offset; + enum_bitset keys; + Magnum::Timeline timeline; +}; + +using namespace Math::Literals; + +chunk app::make_test_chunk() +{ + constexpr auto N = TILE_MAX_DIM; + chunk c; + c.foreach_tile([&, this](tile& x, std::size_t k, local_coords pt) { + const auto& atlas = pt.x > N/2 && pt.y >= N/2 ? floor2 : floor1; + x.ground_image = { atlas, (std::uint8_t)(k % atlas->size()) }; + }); + constexpr auto K = N/2; + c[{K, K }].wall_north = { wall1, 0 }; + c[{K, K }].wall_west = { wall2, 0 }; + c[{K, K+1}].wall_north = { wall1, 0 }; + c[{K+1, K }].wall_west = { wall2, 0 }; + return c; +} + +void app::update_window_scale() +{ + auto sz = windowSize(); + _shader.set_scale({ (float)sz[0], (float)sz[1] }); +} + +void app::draw_chunk(chunk& c) +{ + _floor_mesh.draw(_shader, c); + _wall_mesh.draw(_shader, c); +} + +app::app(const Arguments& arguments): + Platform::Application{ + arguments, + Configuration{} + .setTitle("Test") + .setSize({1024, 768}, dpi_policy::Physical), + GLConfiguration{} + //.setSampleCount(16) + } +{ + reset_camera_offset(); + timeline.start(); +} + +void app::drawEvent() { +#if 0 + GL::defaultFramebuffer.clear(GL::FramebufferClear::Color | GL::FramebufferClear::Depth); + GL::Renderer::setDepthMask(true); + GL::Renderer::setDepthFunction(GL::Renderer::DepthFunction::LessOrEqual); + GL::Renderer::enable(GL::Renderer::Feature::DepthTest); +#else + GL::defaultFramebuffer.clear(GL::FramebufferClear::Color); + GL::Renderer::setDepthFunction(GL::Renderer::DepthFunction::Never); +#endif + + update_window_scale(); + { + float dt = timeline.previousFrameDuration(); + update(dt); + } + + draw_chunk(_chunk); + + swapBuffers(); + redraw(); + timeline.nextFrame(); +} + +void app::do_camera(float dt) +{ + constexpr float pixels_per_second = 512; + if (keys[key::camera_up]) + camera_offset += Vector2(0, 1) * dt * pixels_per_second; + else if (keys[key::camera_down]) + camera_offset += Vector2(0, -1) * dt * pixels_per_second; + if (keys[key::camera_left]) + camera_offset += Vector2(1, 0) * dt * pixels_per_second; + else if (keys[key::camera_right]) + camera_offset += Vector2(-1, 0) * dt * pixels_per_second; + + _shader.set_camera_offset(camera_offset); + + if (keys[key::camera_reset]) + reset_camera_offset(); +} + +void app::reset_camera_offset() +{ + camera_offset = _shader.project({TILE_MAX_DIM*TILE_SIZE[0]/2.f, TILE_MAX_DIM*TILE_SIZE[1]/2.f, 0}); + //camera_offset = {}; +} + +void app::update(float dt) +{ + do_camera(dt); + if (keys[key::quit]) + Platform::Sdl2Application::exit(0); +} + +void app::do_key(KeyEvent::Key k, KeyEvent::Modifiers m, bool pressed, bool repeated) +{ + //using Mods = KeyEvent::Modifiers; + + (void)m; + (void)repeated; + + const key x = progn(switch (k) { + using enum KeyEvent::Key; + using enum key; + + case W: return camera_up; + case A: return camera_left; + case S: return camera_down; + case D: return camera_right; + case Home: return camera_reset; + case Esc: return quit; + default: return MAX; + }); + + if (x != key::MAX) + keys[x] = pressed; +} + +app::~app() +{ + loader_::destroy(); +} + +void app::keyPressEvent(Platform::Sdl2Application::KeyEvent& event) +{ + do_key(event.key(), event.modifiers(), true, event.isRepeated()); +} + +void app::keyReleaseEvent(Platform::Sdl2Application::KeyEvent& event) +{ + do_key(event.key(), event.modifiers(), false, false); +} + +} // namespace Magnum::Examples + +MAGNUM_APPLICATION_MAIN(Magnum::Examples::app) + +#ifdef _MSC_VER +# include +# ifdef __clang__ +# pragma clang diagnostic ignored "-Wmissing-prototypes" +# pragma clang diagnostic ignored "-Wmain" +# endif + +extern "C" int __stdcall WinMain(void*, void*, void*, int /* nCmdShow */) { + return main(__argc, __argv); +} +#endif diff --git a/serialize/CMakeLists.txt b/serialize/CMakeLists.txt deleted file mode 100644 index e695aff2..00000000 --- a/serialize/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -find_package(nlohmann_json QUIET REQUIRED) -set(self "${PROJECT_NAME}-serialize") -link_libraries(Magnum::Magnum nlohmann_json::nlohmann_json) -file(GLOB sources "*.cpp" CONFIGURE_ARGS) -add_library(${self} STATIC ${sources}) diff --git a/serialize/tile-atlas.cpp b/serialize/tile-atlas.cpp new file mode 100644 index 00000000..0f03e6b2 --- /dev/null +++ b/serialize/tile-atlas.cpp @@ -0,0 +1,42 @@ +#include "../tile-atlas.hpp" +#include "serialize/tile-atlas.hpp" +#include "serialize/magnum-vector.hpp" +#include "loader.hpp" + +#include + +namespace Magnum::Examples::Serialize { + +struct proxy_atlas final { + std::string name; + Vector2i size; +}; + +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(proxy_atlas, name, size) + +} // namespace Magnum::Examples::Serialize + +namespace nlohmann { + +using namespace Magnum::Examples; +using namespace Magnum::Examples::Serialize; + +using shared_atlas = std::shared_ptr; + +void adl_serializer::to_json(json& j, const shared_atlas& x) +{ + if (!x) + j = nullptr; + else { + using nlohmann::to_json; + to_json(j, proxy_atlas{x->name(), x->dimensions()}); + } +} + +void adl_serializer::from_json(const json& j, shared_atlas& x) +{ + proxy_atlas proxy = j; + x = loader.tile_atlas(proxy.name, proxy.size); +} + +} // namespace nlohmann diff --git a/serialize/tile-atlas.hpp b/serialize/tile-atlas.hpp index af279251..c49b8a72 100644 --- a/serialize/tile-atlas.hpp +++ b/serialize/tile-atlas.hpp @@ -1,27 +1,16 @@ #pragma once -#include "../tile-atlas.hpp" -#include +#include "loader.hpp" +#include +#include + +namespace Magnum::Examples { struct tile_atlas; } namespace nlohmann { template<> -struct adl_serializer final { - static void to_json(json& j, const Magnum::Examples::tile_atlas& x); - static void from_json(const json& j, Magnum::Examples::tile_atlas& x); +struct adl_serializer> final { + static void to_json(json& j, const std::shared_ptr& x); + static void from_json(const json& j, std::shared_ptr& x); }; -void adl_serializer::to_json(json& j, const Magnum::Examples::tile_atlas& x) -{ -} - -void adl_serializer::from_json(const json& j, Magnum::Examples::tile_atlas& x) -{ -} - } // namespace nlohmann - -namespace Magnum::Examples::Serialize { - - - -} // namespace Magnum::Examples::Serialize diff --git a/tile-atlas.hpp b/tile-atlas.hpp index 3416314c..f2cacf09 100644 --- a/tile-atlas.hpp +++ b/tile-atlas.hpp @@ -11,7 +11,8 @@ struct tile_atlas final { using quad = std::array; - tile_atlas(const Containers::StringView& name, const ImageView2D& img, Vector2i dims); + tile_atlas(const Containers::StringView& name, const ImageView2D& img, Vector2i dimensions); + std::array texcoords_for_id(std::size_t id) const; static constexpr quad floor_quad(Vector3 center, Vector2 size); static constexpr quad wall_quad_N(Vector3 center, Vector3 size); @@ -19,6 +20,7 @@ struct tile_atlas final static constexpr std::array indices(std::size_t N); std::size_t size() const { return (std::size_t)dims_.product(); } Vector2i tile_size() const { return size_ / dims_; } + Vector2i dimensions() const { return dims_; } GL::Texture2D& texture() { return tex_; } std::string name() const { return name_; } -- cgit v1.2.3