summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-02-19 21:40:17 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-02-19 21:40:17 +0100
commitb8aa39d289c605b13bb550b786cba3f646fa5b48 (patch)
treebf74772e84b9d48474298a7cae96698a4c3193ae
parent241d6bf6f4414cb5238d0193014b653a50e0fe64 (diff)
flush
-rw-r--r--CMakeLists.txt4
-rw-r--r--defs.hpp47
-rw-r--r--loader-impl.cpp82
-rw-r--r--loader.cpp6
-rw-r--r--loader.hpp32
-rw-r--r--main.cpp33
-rw-r--r--resources.conf2
-rw-r--r--tile-shader.cpp7
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
diff --git a/main.cpp b/main.cpp
index 964f3fc0..e134134a 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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}));