147 lines
4.8 KiB
C++
147 lines
4.8 KiB
C++
#pragma once
|
|
|
|
#include "util/Util.h"
|
|
|
|
class TextureAtlas;
|
|
|
|
/**
|
|
* Represents a single drawable texture from the texture atlas.
|
|
* Will either contain its own data, or reference another atlas texture as a crop of it.
|
|
* AtlasTextures will automatically remove themselves from the texture atlas once all copies of them are destroyed.
|
|
*/
|
|
|
|
class AtlasTexture {
|
|
/** Stores byte data for an atlas texture. */
|
|
struct ByteData {
|
|
ByteData(uvec2 size, const vec<u8>& data): data(data), size(size) {};
|
|
|
|
/** The size of the texture. */
|
|
uvec2 size;
|
|
|
|
/** The raw bytes of the texture. */
|
|
vec<u8> data;
|
|
};
|
|
|
|
/** Stores a reference to another atlas texture and a crop region. */
|
|
struct CropData {
|
|
CropData(uvec2 pos, uvec2 size, const sptr<AtlasTexture>& source): pos(pos), size(size), source(source) {}
|
|
|
|
/** The top-left position of the crop region. */
|
|
uvec2 pos;
|
|
|
|
/** The sise of the crop region. */
|
|
uvec2 size;
|
|
|
|
/** The image to crop from. */
|
|
sptr<AtlasTexture> source;
|
|
};
|
|
|
|
/**
|
|
* The main data container for the AtlasTexture. It is stored in a
|
|
* shared pointer so that it may be reference counted.
|
|
* Contains the identifier, atlas position, and data of a texture in the atlas.
|
|
* The data may be a ByteData storing raw texture bytes,
|
|
* or a CropData referencing another texture to crop this one from.
|
|
* May also store a reference to a tint index and mask, if the texture is to be biome tinted.
|
|
*/
|
|
|
|
struct SharedData {
|
|
SharedData(const string& identifier, uvec2 pos, const variant<ByteData, CropData>& data):
|
|
identifier(identifier), pos(pos), data(data) {}
|
|
|
|
/** The position of the top-left point of the texture in the texture atlas. */
|
|
uvec2 pos {};
|
|
|
|
/** The identifier of the texture. */
|
|
string identifier;
|
|
|
|
/** Whether or not the texture should be kept even if it is not in use. */
|
|
bool persistent = false;
|
|
|
|
/** The data of the texture, either bytes or a crop region. */
|
|
variant<ByteData, CropData> data;
|
|
|
|
/** An optional pair containing biome tint data. */
|
|
optional<std::pair<u32, uptr<AtlasTexture>>> tintData;
|
|
};
|
|
|
|
public:
|
|
AtlasTexture(const AtlasTexture& o): shr(o.shr), atlas(o.atlas) {}
|
|
|
|
AtlasTexture& operator=(const AtlasTexture& o) { shr = o.shr; return *this; }
|
|
|
|
AtlasTexture(TextureAtlas& atlas, const string& identifier, uvec2 pos, uvec2 size, const sptr<AtlasTexture>& source):
|
|
AtlasTexture(atlas, identifier, source->getPos(), CropData { pos, size, source }) {}
|
|
|
|
AtlasTexture(TextureAtlas& atlas, const string& identifier, uvec2 pos, uvec2 size, vec<u8> data):
|
|
AtlasTexture(atlas, identifier, pos, ByteData { size, data }) {}
|
|
|
|
AtlasTexture(TextureAtlas& atlas, const string& identifier, uvec2 pos, const variant<ByteData, CropData>& data):
|
|
shr(std::make_shared<SharedData>(identifier, pos, data)), atlas(atlas) {}
|
|
|
|
/** Returns the texture's identifier. */
|
|
inline const string& getIdentifier() const {
|
|
return shr->identifier;
|
|
}
|
|
|
|
/** Returns the texture's atlas position in pixels. */
|
|
inline const uvec2& getPos() const {
|
|
return shr->pos;
|
|
}
|
|
|
|
/** Returns the texture's altas size in pixels. */
|
|
inline const uvec2& getSize() const {
|
|
return holds_alternative<ByteData>(shr->data) ?
|
|
get<ByteData>(shr->data).size : get<CropData>(shr->data).size;
|
|
}
|
|
|
|
/** Returns the texture's atlas position in tiles. */
|
|
inline u16vec2 getTilePos() const {
|
|
return u16vec2(shr->pos / 16u);
|
|
}
|
|
|
|
/** Returns the texture's atlas size in tiles. */
|
|
inline u16vec2 getTileSize() const {
|
|
return u16vec2(glm::ceil(vec2(getSize()) / 16.f));
|
|
}
|
|
|
|
/** Returns the texture's UVs, in a four-dimensional vector. */
|
|
vec4 getUVPos() const;
|
|
|
|
/**
|
|
* Returns the bytes of the texture.
|
|
* This is an expensive operation because the bytes may need to be cloned from a crop region,
|
|
* so a reference cannot be returned. In the future,
|
|
* a ref-counted object may be returned instead to reduce overhead.
|
|
*/
|
|
|
|
vec<u8> getBytes() const;
|
|
|
|
/** Returns the biome tint index of the texture, if it is to be tinted. */
|
|
optional<u32> getTintInd() const;
|
|
|
|
/** Returns the biome tint mask texture of this texture, if it is to be tinted. */
|
|
optional<AtlasTexture> getTintMask() const;
|
|
|
|
/** Sets the persistence of the texture, if it is persistent, it will not be deleted when it is no longer in use. */
|
|
void setPersistent(bool persistent);
|
|
|
|
/** Sets the tint information of the texture. */
|
|
void setTintData(u32 tintInd, const AtlasTexture& tintMask);
|
|
|
|
/** Returns true if the texture is only referenced by the texture atlas and is not persistent. */
|
|
bool shouldBeRemoved();
|
|
|
|
~AtlasTexture();
|
|
|
|
private:
|
|
|
|
// IF YOU ARE PUTTING SOMETHING ELSE HERE, YOU PROBABLY SHOULDN'T BE.
|
|
// PUT ANY ATLASTEXTURE DATA IN THE SHAREDDATA STRUCT INSTEAD.
|
|
|
|
/** A reference to the texture atlas holding this texture. */
|
|
TextureAtlas& atlas;
|
|
|
|
/** The actual ref-counted data of the AtlasTexture. */
|
|
sptr<SharedData> shr;
|
|
}; |