Add sprite atlasing
We need sprite atlasing for the UI and other things.
This includes:
texpacker
A tool (in Go) to take an arbitrary number of input images (format can be limited to Go's builtin formats, ie. PNG JPEG GIF) and output one (or more) textures (in PNG, preferably) with all the input textures packed. The output should also include a header file with data saying where each sprite is (texture path + UV offset + UV size).
What do you mean "one or more" output textures?
Two 128x128 textures are lighter than a single 256x256 texture, if we can't fit something just barely on a 128x128 texture it might be better to have multiple ones. This is a long term goal with low priority, I rather spend time on having a working tool first and maybe some decent packing algorithm second (not expecting MaxRects, but would be nice)
Better way to initialize sprites
The constructor for a sprite component is
explicit Sprite(const Vector2D& size, const std::shared_ptr<Material>& material,
const Rect& bounds = Rect(0, 0, 1, 1))
This means that it takes the full texture (in material) and UV bounds. With texpacker, we should make a simpler version that takes one of the outputs from texture packer or something like that.
Doing stuff here. Regarding the header file: would it be ok to output something like this?
#include <unordered_map>
#include "../math/Rect.h"
#include "../resources/ResourceLoader.h" // for FileHash
// Map texture path hash -> UV coords in atlas
static const std::unordered_map<FileHash, Rect> atlasCoords = {
{..., ...}
};
Sure, just make sure it uses text/template like bento does so it can easily changed later on.
Minor nitpicking:
#include <unordered_map>
I rather this be
#include "../pchheader.h"
Or whatever the relative path to the preconfigured header will end up being as that should contain all standard library headers (including adding unordered_map there + math eventually, so even Rect.h wouldn't be needed)
Also I want the atlas to specify the hash of the atlas texture, as that should be completely transparent to us, so maybe add a field for that, like
const FileHash atlasTexture = ...;
Ok 👍 (is there a specific reason for using std::map rather than std::unordered_map in other parts of the code, i.e. ResourceLoader.h ?)
It's because we use .find on those map every time we want to load something in, so we thought std::map would be faster for lookups (we don't care about insertion performance since it's all compiled in).
We haven't done too much research into that, so std::unordered_map might still be faster I guess.
Pick whatever you like, we can always change it later.