diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-02-19 21:40:17 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-02-19 21:40:17 +0100 |
commit | b8aa39d289c605b13bb550b786cba3f646fa5b48 (patch) | |
tree | bf74772e84b9d48474298a7cae96698a4c3193ae | |
parent | 241d6bf6f4414cb5238d0193014b653a50e0fe64 (diff) |
flush
-rw-r--r-- | CMakeLists.txt | 4 | ||||
-rw-r--r-- | defs.hpp | 47 | ||||
-rw-r--r-- | loader-impl.cpp | 82 | ||||
-rw-r--r-- | loader.cpp | 6 | ||||
-rw-r--r-- | loader.hpp | 32 | ||||
-rw-r--r-- | main.cpp | 33 | ||||
-rw-r--r-- | resources.conf | 2 | ||||
-rw-r--r-- | tile-shader.cpp | 7 |
8 files changed, 184 insertions, 29 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a918b30..37f77fbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,10 +53,10 @@ if(NOT BOOTSTRAP_DEPENDS) find_package(MagnumPlugins QUIET REQUIRED) find_package(MagnumIntegration COMPONENTS Glm QUIET REQUIRED) - corrade_add_resource(TexturedQuad_RESOURCES resources.conf) + corrade_add_resource(game_RESOURCES resources.conf) file(GLOB sources "*.cpp" CONFIGURE_ARGS) - add_executable(${PROJECT_NAME} WIN32 "${sources}" "${TexturedQuad_RESOURCES}") + add_executable(${PROJECT_NAME} WIN32 "${sources}" "${game_RESOURCES}") target_link_libraries(${PROJECT_NAME} PRIVATE Magnum::Application Magnum::GL diff --git a/defs.hpp b/defs.hpp new file mode 100644 index 00000000..a2f5d240 --- /dev/null +++ b/defs.hpp @@ -0,0 +1,47 @@ +#pragma once +#include <cstdio> +#include <exception> + +namespace Magnum::Examples { + +struct assertion_failure final : std::exception +{ + const char* file = nullptr; + int line = -1; + char msg[128 - sizeof(int) - sizeof(char*)]; + + const char* what() const noexcept override { return msg; } +}; + +} // namespace Magnum::Examples + +#define ABORT_WITH(exc_type, ...) ([&]() { \ + exc_type _e; \ + _e.line = __LINE__; \ + _e.file = __FILE__; \ + std::snprintf(_e.msg, sizeof(_e.msg), __VA_ARGS__); \ + throw _e; \ +}()) + +#define ABORT(...) \ + ABORT_WITH(::Magnum::Examples::assertion_failure, __VA_ARGS__) + +#define ASSERT(expr) \ + do { \ + if (!(expr)) \ + ABORT("assertion failed: '%s' in %s:%d", \ + #expr, __FILE__, __LINE__); \ + } while(false) + +#define GAME_DEBUG_OUT(pfx, ...) ([&]() { \ + if constexpr (sizeof((pfx)) > 1) \ + std::fputs((pfx), stderr); \ + std::fprintf(stderr, __VA_ARGS__); \ + std::fputs("\n", stderr); \ + std::fflush(stderr); \ +}()) + +#define WARN(...) GAME_DEBUG_OUT("warning: ", __VA_ARGS__) +#define ERR(...) GAME_DEBUG_OUT("error: ", __VA_ARGS__) +#define DEBUG(...) GAME_DEBUG_OUT("", __VA_ARGS__) + diff --git a/loader-impl.cpp b/loader-impl.cpp new file mode 100644 index 00000000..96f5930b --- /dev/null +++ b/loader-impl.cpp @@ -0,0 +1,82 @@ +#include "defs.hpp" +#include "loader.hpp" +#include "atlas.hpp" +#include <Corrade/Containers/Optional.h> +#include <Corrade/PluginManager/PluginManager.h> +#include <Corrade/Utility/Resource.h> +#include <Magnum/Trade/AbstractImporter.h> +#include <Magnum/Trade/ImageData.h> +#include <string> +#include <unordered_map> +#include <utility> +#include <optional> + +namespace Magnum::Examples { + +struct loader_impl final : loader_ +{ + const Utility::Resource shader_res{"game/shaders"}; + PluginManager::Manager<Trade::AbstractImporter> plugins; + Containers::Pointer<Trade::AbstractImporter> tga_importer = + plugins.loadAndInstantiate("TgaImporter"); + + std::unordered_map<std::string, atlas_ptr> atlas_map; + + std::string shader(const std::string& filename) override; + Trade::ImageData2D tile_texture(const std::string& filename) override; + atlas_ptr tile_atlas(const std::string& filename) override; + + explicit loader_impl(); + ~loader_impl() override; +}; + +std::string loader_impl::shader(const std::string& filename) +{ + auto ret = shader_res.get(filename); + if (ret.empty()) + ABORT("can't find shader resource '%s'", filename.c_str()); + return ret; +} + +atlas_ptr loader_impl::tile_atlas(const std::string& name) +{ + constexpr Vector2i size{8, 4}; // TODO + + auto it = atlas_map.find(name); + if (it != atlas_map.end()) + return it->second; + auto atlas = std::make_shared<atlas_texture>(tile_texture(name), size); + atlas_map[name] = atlas; + return atlas; +} + +Trade::ImageData2D loader_impl::tile_texture(const std::string& filename) +{ + if(!tga_importer || !tga_importer->openFile(filename)) + ABORT("can't open tile image '%s'", filename.c_str()); + auto img = tga_importer->image2D(0); + if (!img) + ABORT("can't allocate tile image for '%s'", filename.c_str()); + 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{}; + return loader; +} + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) +loader_& loader = make_default_loader(); + +} // namespace Magnum::Examples diff --git a/loader.cpp b/loader.cpp new file mode 100644 index 00000000..f6219350 --- /dev/null +++ b/loader.cpp @@ -0,0 +1,6 @@ +#include "loader.hpp" + +namespace Magnum::Examples { +loader_::loader_() = default; +loader_::~loader_() = default; +} // namespace Magnum::Examples diff --git a/loader.hpp b/loader.hpp new file mode 100644 index 00000000..0406d4e2 --- /dev/null +++ b/loader.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include <Magnum/Trade/ImageData.h> + +#include <string> +#include <optional> +#include <memory> + +namespace Magnum::Examples { + +struct atlas_texture; +using atlas_ptr = std::shared_ptr<atlas_texture>; + +struct loader_ +{ + virtual std::string shader(const std::string& filename) = 0; + virtual Trade::ImageData2D tile_texture(const std::string& filename) = 0; + virtual atlas_ptr tile_atlas(const std::string& filename) = 0; + static void destroy(); + + loader_(const loader_&) = delete; + loader_& operator=(const loader_&) = delete; + + virtual ~loader_(); + +protected: + loader_(); +}; + +extern loader_& loader; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + +} // namespace Magnum::Examples @@ -1,4 +1,5 @@ #include "atlas.hpp" +#include "loader.hpp" #include "tile-shader.hpp" #include <Corrade/Containers/Optional.h> @@ -27,18 +28,13 @@ namespace Magnum::Examples { struct application final : Platform::Application { explicit application(const Arguments& arguments); + virtual ~application(); void drawEvent() override; - const Utility::Resource rs{"texturedquad-data"}; - PluginManager::Manager<Trade::AbstractImporter> plugins; - Containers::Pointer<Trade::AbstractImporter> tga_importer = - plugins.loadAndInstantiate("TgaImporter"); - GL::Mesh _mesh; tile_shader _shader; - atlas_texture atlas = make_atlas("../share/game/images/tiles.tga", {8, 4}); + std::shared_ptr<atlas_texture> atlas = loader.tile_atlas("../share/game/images/tiles.tga"); - atlas_texture make_atlas(const std::string& file, Vector2i dims); Matrix4x4 make_projection(Vector3 offset); }; @@ -63,9 +59,9 @@ application::application(const Arguments& arguments): for (int i = -2; i <= 2; i++) { constexpr int sz = 48; - auto positions = atlas.floor_quad({(float)(sz*i), (float)(sz*j), 0}, {sz, sz}); - auto texcoords = atlas.texcoords_for_id(((k+5)*101) % atlas.size()); - auto indices_ = atlas.indices(k); + auto positions = atlas->floor_quad({(float)(sz*i), (float)(sz*j), 0}, {sz, sz}); + auto texcoords = atlas->texcoords_for_id(((k+5)*101) % atlas->size()); + auto indices_ = atlas->indices(k); for (unsigned x = 0; x < 4; x++) vertices.push_back({ positions[x], texcoords[x] }); @@ -91,23 +87,12 @@ void application::drawEvent() { _shader .set_projection(make_projection({0, 0, 0})) .set_color(0xffffff_rgbf) - .bindTexture(atlas.texture()) + .bindTexture(atlas->texture()) .draw(_mesh); swapBuffers(); } -atlas_texture application::make_atlas(const std::string& file, Vector2i dims) -{ - if(!tga_importer || !tga_importer->openFile(file)) - std::exit(1); - - Containers::Optional<Trade::ImageData2D> image = tga_importer->image2D(0); - CORRADE_INTERNAL_ASSERT(image); - - return atlas_texture{*image, dims}; -} - Matrix4x4 application::make_projection(Vector3 offset) { using vec3 = glm::vec<3, double, glm::highp>; @@ -123,6 +108,10 @@ Matrix4x4 application::make_projection(Vector3 offset) m = glm::rotate(m, glm::radians(-45.), vec3(0, 0, 1)); return Matrix4x4{glm::mat4(m)}; } +application::~application() +{ + loader_::destroy(); +} } // namespace Magnum::Examples diff --git a/resources.conf b/resources.conf index cc2e5e9e..251f4501 100644 --- a/resources.conf +++ b/resources.conf @@ -1,4 +1,4 @@ -group=texturedquad-data +group=game/shaders [file] filename=shaders/tile-shader.frag diff --git a/tile-shader.cpp b/tile-shader.cpp index cff3d7f6..3477a00c 100644 --- a/tile-shader.cpp +++ b/tile-shader.cpp @@ -1,4 +1,5 @@ #include "tile-shader.hpp" +#include "loader.hpp" #include <Corrade/Containers/Reference.h> #include <Corrade/Utility/Resource.h> @@ -12,13 +13,11 @@ tile_shader::tile_shader() { MAGNUM_ASSERT_GL_VERSION_SUPPORTED(GL::Version::GL460); - const Utility::Resource rs{"texturedquad-data"}; - GL::Shader vert{GL::Version::GL460, GL::Shader::Type::Vertex}; GL::Shader frag{GL::Version::GL460, GL::Shader::Type::Fragment}; - vert.addSource(rs.get("shaders/tile-shader.vert")); - frag.addSource(rs.get("shaders/tile-shader.frag")); + vert.addSource(loader.shader("shaders/tile-shader.vert")); + frag.addSource(loader.shader("shaders/tile-shader.frag")); CORRADE_INTERNAL_ASSERT_OUTPUT(GL::Shader::compile({vert, frag})); |