"working" texture atlas, but cropping is gimped

master
Auri 2021-10-10 14:26:21 -07:00
parent 62c6162f47
commit 3eccd8e7e7
6 changed files with 59 additions and 33 deletions

View File

@ -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<u8> data) {
AtlasRef TextureAtlas::addBytes(const string& identifier, bool persistent, u16vec2 size, const vec<u8>& 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 {

View File

@ -27,7 +27,7 @@ public:
sptr<AtlasTexture> addFile(const std::filesystem::path& path, bool persistent);
sptr<AtlasTexture> addBytes(const string& identifier, bool persistent, u16vec2 size, vec<u8> data);
sptr<AtlasTexture> addBytes(const string& identifier, bool persistent, u16vec2 size, const vec<u8>& data);
sptr<AtlasTexture> operator[](const string& identifier);

View File

@ -8,11 +8,14 @@ vec<u8>& TextureBuilder::Texture::getBytes() {
const vec<u8> sourceBytes = cropData.source->getBytes();
const u16 sourceWidth = cropData.source->getSize().x;
std::cout << "cropping " << cropData.source->getIdentifier() << " to " << size << std::endl;
vec<u8> 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<ByteData>(data).data;
}
@ -120,14 +123,13 @@ TextureBuilder::Data TextureBuilder::Data::tint(u32 tint, Data tex, optional<Dat
TextureBuilder::TextureBuilder(TextureAtlas& atlas): ctx({ atlas }) {
parser.addLiteralFnCtx(&TextureBuilder::Data::literal);
parser.addFn<u16, optional<variant<u16, string>>, optional<string>>("canvas", &TextureBuilder::Data::canvas);
parser.addFn<f32, Data>("alpha", &TextureBuilder::Data::alpha);
parser.addFn<u16, u16, u16, variant<u16, Data>>("crop", &TextureBuilder::Data::crop);
parser.addFn<u16, u16, u16, u16, Data>("crop", &TextureBuilder::Data::crop);
parser.addFn<variant<string, Data>, Data>("multiply", &TextureBuilder::Data::multiply);
parser.addFn<Data, Data, optional<Data>, optional<Data>, optional<Data>, optional<Data>,
optional<Data>, optional<Data>, optional<Data>>("", &TextureBuilder::Data::stack);
parser.addFn<u32, Data, optional<Data>>("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 {

View File

@ -33,8 +33,6 @@ public:
sptr<AtlasTexture> source;
};
vec<u8>& getBytes();
public:
void alpha(f32 factor);
@ -60,6 +58,8 @@ public:
u16vec2 size;
variant<CropData, ByteData> data;
vec<u8>& 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<Data&>(o).texture)) {};
Data(u16vec2 size, vec4 color): texture(make_unique<Texture>(size, color)) {};
Data(u16vec2 size, sptr<AtlasTexture> tex): texture(make_unique<Texture>(size, tex)) {};
Data(u16vec2 pos, u16vec2 size, sptr<AtlasTexture> tex): texture(make_unique<Texture>(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<Data&>(o).texture); return *this; };
sptr<Texture> texture = {};
optional<std::pair<u32, sptr<Texture>>> tintMask = {};
uptr<Texture> texture = {};
optional<std::pair<u32, uptr<Texture>>> tintMask = {};
};
TextureBuilder(TextureAtlas& atlas);

31
src/util/FunctionTraits.h Normal file
View File

@ -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 <typename T>
struct function_traits : public function_traits<decltype(&T::operator())> {};
template <typename C, typename R, typename... Args>
struct function_traits<R(C::*)(Args...) const> {
typedef std::function<R(Args...)> function_type;
typedef std::tuple<Args...> args_type;
typedef R return_type;
};
template <typename C, typename R, typename... Args>
struct function_traits<R(C::*)(Args...)> {
typedef std::function<R(Args...)> function_type;
typedef std::tuple<Args...> args_type;
typedef R return_type;
};
template <typename R, typename... Args>
struct function_traits<R(*)(Args...)> {
typedef std::function<R(Args...)> function_type;
typedef std::tuple<Args...> args_type;
typedef R return_type;
};

View File

@ -4,6 +4,7 @@
#include <unordered_map>
#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 <typename... Args, typename Func>
void addFn(const string& name, const Func& fn) {
template <typename L>
void addFn(const string& name, const L& fn) {
functions.emplace(name, [=, this](C& ctx, STR_ARGS strArgs) {
std::tuple<Args...> args = {};
parseStrArgs<std::tuple<Args...>>(strArgs, args, ctx);
typedef typename function_traits<L>::args_type Args;
Args args = {};
parseStrArgs<Args>(strArgs, args, ctx);
return std::apply(fn, args);
});
}