From 3eccd8e7e78d58a59f13aef5295f5a691009e094 Mon Sep 17 00:00:00 2001 From: Auri Date: Sun, 10 Oct 2021 14:26:21 -0700 Subject: [PATCH] "working" texture atlas, but cropping is gimped --- src/game/atlas/TextureAtlas.cpp | 7 +++---- src/game/atlas/TextureAtlas.h | 2 +- src/game/atlas/TextureBuilder.cpp | 20 +++++++++++--------- src/game/atlas/TextureBuilder.h | 19 ++++++------------- src/util/FunctionTraits.h | 31 +++++++++++++++++++++++++++++++ src/util/StringParser.h | 13 +++++++------ 6 files changed, 59 insertions(+), 33 deletions(-) create mode 100644 src/util/FunctionTraits.h diff --git a/src/game/atlas/TextureAtlas.cpp b/src/game/atlas/TextureAtlas.cpp index d5262036..5d60eef0 100644 --- a/src/game/atlas/TextureAtlas.cpp +++ b/src/game/atlas/TextureAtlas.cpp @@ -43,7 +43,7 @@ AtlasRef TextureAtlas::addFile(const std::filesystem::path& path, bool persisten return ref; } -AtlasRef TextureAtlas::addBytes(const string& identifier, bool persistent, u16vec2 size, vec data) { +AtlasRef TextureAtlas::addBytes(const string& identifier, bool persistent, u16vec2 size, const vec& data) { let tileSize = u16vec2(glm::ceil(vec2(size) / 16.f)); let posOpt = findAtlasSpace(tileSize); if (!posOpt) throw std::runtime_error("Failed to find space in the dynamic definition atlas."); @@ -64,11 +64,10 @@ AtlasRef TextureAtlas::operator[](const string& identifier) { if (tex->getIdentifier() != "_missing") return tex; let data = texBuilder.build(identifier); - throw std::runtime_error("unimplemented"); -// let texture = addBytes(identifier, false, data.size, data.getBytes()); + let texture = addBytes(identifier, false, data.texture->size, data.texture->getBytes()); // if (data.tintMask) texture->setTintData(*data.tintInd, // addBytes(identifier + ":tint", false, data.size, *data.tintMask)); -// return texture; + return texture; } AtlasRef TextureAtlas::get(const string& identifier) const { diff --git a/src/game/atlas/TextureAtlas.h b/src/game/atlas/TextureAtlas.h index e833f3b0..55d5da10 100644 --- a/src/game/atlas/TextureAtlas.h +++ b/src/game/atlas/TextureAtlas.h @@ -27,7 +27,7 @@ public: sptr addFile(const std::filesystem::path& path, bool persistent); - sptr addBytes(const string& identifier, bool persistent, u16vec2 size, vec data); + sptr addBytes(const string& identifier, bool persistent, u16vec2 size, const vec& data); sptr operator[](const string& identifier); diff --git a/src/game/atlas/TextureBuilder.cpp b/src/game/atlas/TextureBuilder.cpp index a225d637..4ba2efe2 100644 --- a/src/game/atlas/TextureBuilder.cpp +++ b/src/game/atlas/TextureBuilder.cpp @@ -8,11 +8,14 @@ vec& TextureBuilder::Texture::getBytes() { const vec sourceBytes = cropData.source->getBytes(); const u16 sourceWidth = cropData.source->getSize().x; + std::cout << "cropping " << cropData.source->getIdentifier() << " to " << size << std::endl; + vec newBytes(size.x * size.y * 4); for (u32 i = 0; i < size.x * size.y * 4; i++) newBytes[i] = - sourceBytes[((cropData.offset.x + i / 4 % size.x) + + sourceBytes[(((cropData.offset.x + i / 4) % size.x) + (cropData.offset.y + i / 4 / size.x) * sourceWidth) * 4 + i % 4]; +// data = ByteData(sourceBytes); data = ByteData(newBytes); return get(data).data; } @@ -120,14 +123,13 @@ TextureBuilder::Data TextureBuilder::Data::tint(u32 tint, Data tex, optional>, optional>("canvas", &TextureBuilder::Data::canvas); - parser.addFn("alpha", &TextureBuilder::Data::alpha); - parser.addFn>("crop", &TextureBuilder::Data::crop); - parser.addFn("crop", &TextureBuilder::Data::crop); - parser.addFn, Data>("multiply", &TextureBuilder::Data::multiply); - parser.addFn, optional, optional, optional, - optional, optional, optional>("", &TextureBuilder::Data::stack); - parser.addFn>("tint", &TextureBuilder::Data::tint); + parser.addFn("", &TextureBuilder::Data::stack); + + parser.addFn("canvas", &TextureBuilder::Data::canvas); + parser.addFn("alpha", &TextureBuilder::Data::alpha); + parser.addFn("crop", &TextureBuilder::Data::crop); + parser.addFn("multiply", &TextureBuilder::Data::multiply); + parser.addFn("tint", &TextureBuilder::Data::tint); } TextureBuilder::Data TextureBuilder::build(const string& str) const { diff --git a/src/game/atlas/TextureBuilder.h b/src/game/atlas/TextureBuilder.h index efc8d074..e245d99d 100644 --- a/src/game/atlas/TextureBuilder.h +++ b/src/game/atlas/TextureBuilder.h @@ -33,8 +33,6 @@ public: sptr source; }; - vec& getBytes(); - public: void alpha(f32 factor); @@ -60,6 +58,8 @@ public: u16vec2 size; variant data; + + vec& getBytes(); }; class Data { @@ -138,23 +138,16 @@ public: public: Data() = default; - - Data(Data&) = default; - Data(Data&&) = default; - Data& operator=(Data&) = default; - Data& operator=(Data&&) = default; + Data(const Data& o): texture(std::move(const_cast(o).texture)) {}; Data(u16vec2 size, vec4 color): texture(make_unique(size, color)) {}; Data(u16vec2 size, sptr tex): texture(make_unique(size, tex)) {}; Data(u16vec2 pos, u16vec2 size, sptr tex): texture(make_unique(pos, size, tex)) {}; -// Data(Data& o): texture(std::move(o.texture)) {}; -// Data(Data&& o): texture(std::move(o.texture)) {}; -// Data& operator=(Data& o) { this->texture = std::move(o.texture); return *this; }; -// Data& operator=(Data&& o) { this->texture = std::move(o.texture); return *this; }; + Data& operator=(const Data& o) { texture = std::move(const_cast(o).texture); return *this; }; - sptr texture = {}; - optional>> tintMask = {}; + uptr texture = {}; + optional>> tintMask = {}; }; TextureBuilder(TextureAtlas& atlas); diff --git a/src/util/FunctionTraits.h b/src/util/FunctionTraits.h new file mode 100644 index 00000000..ee3dedf2 --- /dev/null +++ b/src/util/FunctionTraits.h @@ -0,0 +1,31 @@ +#pragma once + +/** + * Template struct that takes a function pointer, method pointer, or lambda and + * exposes the corresponding std::function type, arguments types, and return type. + * From the god over at https://stackoverflow.com/q/21657627 (thank you thank you) + */ + +template +struct function_traits : public function_traits {}; + +template +struct function_traits { + typedef std::function function_type; + typedef std::tuple args_type; + typedef R return_type; +}; + +template +struct function_traits { + typedef std::function function_type; + typedef std::tuple args_type; + typedef R return_type; +}; + +template +struct function_traits { + typedef std::function function_type; + typedef std::tuple args_type; + typedef R return_type; +}; \ No newline at end of file diff --git a/src/util/StringParser.h b/src/util/StringParser.h index a2ca5394..0fc8ed2b 100644 --- a/src/util/StringParser.h +++ b/src/util/StringParser.h @@ -4,6 +4,7 @@ #include #include "util/Types.h" +#include "util/FunctionTraits.h" /** SFINAE Helpers. */ namespace { @@ -66,19 +67,19 @@ public: * Adds a function to the functions map. * For a function to be valid, it must only have parameters that are * integral, floating point, strings, the Data type, or optionals & variants of them. - * It must also return a Data type. The Args type parameter must match the function's types. + * It must also return a Data type. * If the function needs access to the Context, use addFnCtx() instead. * - * @tparam Args - The argument types of the function. * @param name - The name of the function. * @param fn - The function lambda. */ - template - void addFn(const string& name, const Func& fn) { + template + void addFn(const string& name, const L& fn) { functions.emplace(name, [=, this](C& ctx, STR_ARGS strArgs) { - std::tuple args = {}; - parseStrArgs>(strArgs, args, ctx); + typedef typename function_traits::args_type Args; + Args args = {}; + parseStrArgs(strArgs, args, ctx); return std::apply(fn, args); }); }