168 lines
4.7 KiB
C++
168 lines
4.7 KiB
C++
#pragma once
|
|
|
|
#include "util/StringParser.h"
|
|
|
|
class TextureAtlas;
|
|
class AtlasTexture;
|
|
|
|
class TextureBuilder {
|
|
public:
|
|
struct Data;
|
|
|
|
private:
|
|
struct Context {
|
|
TextureAtlas& atlas;
|
|
};
|
|
|
|
typedef StringParser<Data, Context> Parser;
|
|
|
|
public:
|
|
class Texture {
|
|
public:
|
|
struct ByteData {
|
|
ByteData() = default;
|
|
ByteData(const vec<u8>& data): data(data) {};
|
|
|
|
vec<u8> data;
|
|
};
|
|
|
|
struct CropData {
|
|
CropData(u16vec2 offset, const sptr<AtlasTexture>& source): offset(offset), source(source) {}
|
|
|
|
u16vec2 offset;
|
|
sptr<AtlasTexture> source;
|
|
};
|
|
|
|
void alpha(f32 factor);
|
|
|
|
void crop(u16vec2 pos, u16vec2 size);
|
|
|
|
void multiply(vec4 scalar);
|
|
|
|
void multiply(Texture& texture);
|
|
|
|
void stack(Texture& texture, Texture* mask = nullptr);
|
|
|
|
Texture(u16vec2 size, vec4 color):
|
|
size(size), data(ByteData(vec<u8>(size.x * size.y * 4))) {
|
|
let& bytes = get<ByteData>(data).data;
|
|
for (u32 i = 0; i < size.x * size.y * 4; i++) bytes[i] = color[i % 4] * 255;
|
|
}
|
|
|
|
Texture(u16vec2 size, sptr<AtlasTexture> tex):
|
|
size(size), data(CropData({}, tex)) {}
|
|
|
|
Texture(u16vec2 pos, u16vec2 size, sptr<AtlasTexture> tex):
|
|
size(size), data(CropData(pos, tex)) {}
|
|
|
|
u16vec2 size;
|
|
variant<CropData, ByteData> data;
|
|
|
|
vec<u8>& getBytes();
|
|
};
|
|
|
|
class Data {
|
|
friend class TextureBuilder;
|
|
|
|
/**
|
|
* Loads a texture identified by a string into a Data.
|
|
*
|
|
* @param str - The string texture name to load.
|
|
*/
|
|
|
|
static Parser::Data literal(Parser::Ctx& ctx, string str);
|
|
|
|
/**
|
|
* Creates an empty canvas of a specified color.
|
|
*
|
|
* @param w - The width of the canvas.
|
|
* @param h - [optional] The height of the canvas, defaults to the width otherwise.
|
|
* @param fill - [optional] The color to fill the canvas with, defaults to transparent.
|
|
*/
|
|
|
|
static Parser::Data canvas(u16 w, optional<variant<u16, string>> h, optional<string> fill);
|
|
|
|
/**
|
|
* Adjusts the opacity of the provided texture by a factor.
|
|
*
|
|
* @param factor - The factor that the opacity should be scaled by. 0 = transparent, 1 = opaque.
|
|
* @param tex - The texture to scale the alpha of.
|
|
*/
|
|
|
|
static Parser::Data alpha(f32 factor, Parser::Data tex);
|
|
|
|
/**
|
|
* Crops the texture to the specified dimensions and offset.
|
|
*
|
|
* @param x - The left edge of the crop on the base texture.
|
|
* @param y - The top edge of the crop on the base texture.
|
|
* @param w - The width of the crop.
|
|
* @param h - The height of the crop.
|
|
* @param tex - The texture to crop.
|
|
*/
|
|
|
|
static Parser::Data crop(u16 x, u16 y, u16 w, variant<u16, Data> hV, optional<Data> texO);
|
|
|
|
/**
|
|
* Multiplies the texture by the specified color or texture.
|
|
*
|
|
* @param multiple - A color to multiply the texture by, or another texture to multiply it by.
|
|
* @param tex - The texture to multiply.
|
|
*/
|
|
|
|
static Parser::Data multiply(variant<string, Data> multiple, Data tex);
|
|
|
|
/**
|
|
* Stacks the provided textures on top of each other, blending partially opaque pixels.
|
|
* Requires at least two textures. The maximum is currently eight textures,
|
|
* however that could be removed later with some tweaks to StringParser.
|
|
*
|
|
* @param b - The base texture to stack onto.
|
|
* @param s1 - A texture to stack on top of the base texture.
|
|
* @param s2 - Another texture to stack on top of s1.
|
|
* @param s3 - ...
|
|
*/
|
|
|
|
static Parser::Data stack(Data b, Data s1, optional<Data> s2, optional<Data> s3,
|
|
optional<Data> s4, optional<Data> s5, optional<Data> s6, optional<Data> s7, optional<Data> s8);
|
|
|
|
/**
|
|
* Tints the texture specified with a specific tint map, usually controlled by biome parameters.
|
|
* @param tint - The tint map to use.
|
|
* @param tex - The texture to tint.
|
|
* @param mask - An image whose red channel determines the strength of the tint for every pixel.
|
|
*/
|
|
|
|
static Parser::Data tint(u32 tint, Data tex, optional<Data> mask);
|
|
|
|
public:
|
|
Data() = default;
|
|
Data(const Data& o): texture(std::move(const_cast<Data&>(o).texture)),
|
|
tintMask(std::move(const_cast<Data&>(o).tintMask)) {};
|
|
|
|
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& operator=(const Data& o) {
|
|
texture = std::move(const_cast<Data&>(o).texture);
|
|
tintMask = std::move(const_cast<Data&>(o).tintMask);
|
|
return *this;
|
|
};
|
|
|
|
uptr<Texture> texture = {};
|
|
optional<std::pair<u32, uptr<Texture>>> tintMask = {};
|
|
};
|
|
|
|
TextureBuilder(TextureAtlas& atlas);
|
|
|
|
Data build(const string& str) const;
|
|
|
|
private:
|
|
|
|
mutable Context ctx;
|
|
Parser parser {};
|
|
};
|
|
|
|
|