#pragma once #include "hd2d/Texture.h" #include #include namespace hd2d { // Fixed-cell dynamic atlas on one Texture: images of up to `cellPixels` are // packed into a cols x rows grid at runtime (e.g. sprites generated or // downloaded while the game runs) so many billboards share a texture. Use // with `BillboardBatch::sharedTexture = &atlas.texture()` and per-instance // `uv = atlas.uv(slot)`, `anchor = atlas.anchor(slot)`. // // Every cell keeps its own 1-px transparent border (gutter), so sharp // bilinear sampling and the first mip levels never bleed between cells. // Images are placed bottom-centered in their cell; images larger than the // cell are cropped to it (keeping the bottom rows and the horizontal center). class SpriteAtlas { public: // Allocates a transparent texture of cols x rows cells. Clears all slots. bool init(glm::ivec2 cellPixels, int cols, int rows); int add(const Image& img); // first free slot, or -1 when full void set(int slot, const Image& img); // replace (or fill) a slot void remove(int slot); // clear a slot and free it // BillboardInstance::uv of the whole cell (cellPixels, gutter excluded). glm::vec4 uv(int slot) const; // BillboardInstance::anchor: v of the lowest opaque (alpha >= 128) row of // the image in `slot`; the cell bottom if it has no opaque pixels. float anchor(int slot) const; glm::ivec2 imageSize(int slot) const; // size placed in the cell (after cropping) bool inUse(int slot) const; const Texture& texture() const { return texture_; } glm::ivec2 cellPixels() const { return cell_; } int capacity() const { return cols_ * rows_; } int used() const { return used_; } private: struct Slot { bool used = false; glm::ivec2 size{0}; int feetRow = 0; // lowest opaque row, in cell pixels from the cell bottom }; glm::ivec2 origin(int slot) const; // GL-orientation pixel of the cell's bottom-left (inside the gutter) bool valid(int slot) const { return slot >= 0 && slot < capacity(); } Texture texture_; glm::ivec2 cell_{0}; int cols_ = 0, rows_ = 0, used_ = 0; std::vector slots_; }; } // namespace hd2d