atlas
stableTexture atlas management for 2D graphics — store, query, pack, and compute UV coordinates for sprite regions.
use plugin atlas::{TextureAtlas.new, add_region, get_region, …} Functions (16)
- TextureAtlas.new Create a new texture atlas
- add_region Register a named sprite region
- get_region Look up a region by name
- remove_region Remove a named region
- regions List all regions with coordinates
- contains Check if a region name exists
- width Get the atlas width in pixels
- height Get the atlas height in pixels
- get_uv Compute normalized UV coordinates
- find_by_prefix Find all regions matching a prefix
- count Return the number of regions
- clear Remove all regions
- resize Change atlas dimensions
- info Get width, height, and region count
- pack Auto-pack items using shelf algorithm
- rename_region Rename an existing region
Overview
The atlas plugin manages a texture atlas: a single large texture subdivided into named rectangular regions, the standard way 2D engines pack many sprites into one GPU texture. Each atlas is a stateful handle returned by TextureAtlas.new(width, height); you call methods on it to register regions, query them, and compute the normalized UV coordinates a shader needs to sample a sprite. Pixel coordinates stay in image space, while get_uv divides them by the atlas dimensions to produce floats in [0, 1].
Reach for it whenever you have many small images that should live in one texture: sprite sheets, animation frames, tilesets, or UI icons. You can place regions manually with add_region, or hand a batch of sizes to pack and let the shelf bin-packing algorithm assign coordinates for you. Region names are arbitrary strings, so prefix conventions like walk_0, walk_1 pair naturally with find_by_prefix to gather animation frames.
Common patterns
Pack a sprite sheet and read back UVs
Let the atlas place a batch of sprites, then fetch UV coordinates for the GPU.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(256, 256)
let placed = atlas.pack([
#{"name": "hero", "w": 64, "h": 64},
#{"name": "coin", "w": 32, "h": 32},
#{"name": "gem", "w": 32, "h": 32}
])
print("packed {atlas.count()} sprites")
let uv = atlas.get_uv("hero")
print("hero uv: ({uv["u0"]}, {uv["v0"]}) -> ({uv["u1"]}, {uv["v1"]})")
Drive an animation from prefixed frames
Register frames with a shared prefix, then collect them as a sequence.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(512, 64)
atlas.add_region("walk_0", 0, 0, 64, 64)
atlas.add_region("walk_1", 64, 0, 64, 64)
atlas.add_region("walk_2", 128, 0, 64, 64)
let frames = atlas.find_by_prefix("walk_")
print("walk cycle has {frames.len()} frames")
for frame in frames {
print("frame {frame["name"]} at x={frame["x"]}")
}
Rebuild an atlas in place
Clear stale regions and re-pack at a new size without allocating a new handle.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(128, 128)
atlas.add_region("old", 0, 0, 32, 32)
atlas.clear()
atlas.resize(256, 256)
atlas.add_region("fresh", 0, 0, 64, 64)
let info = atlas.info()
print("atlas {info["width"]}x{info["height"]}, {info["count"]} regions")
Create a new texture atlas
Creates a new texture atlas with the given pixel dimensions. The atlas stores named rectangular regions and can compute UV coordinates for use in shaders.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(1024, 1024)
atlas.add_region("player_idle", 0, 0, 64, 64)
atlas.add_region("player_run", 64, 0, 64, 64)
print(atlas.count())
Register a named sprite region
Registers a named sprite region with pixel coordinates (x, y) and size (w, h). If a region with the same name already exists, it is replaced.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(512, 512)
atlas.add_region("coin", 0, 0, 32, 32)
atlas.add_region("gem", 32, 0, 32, 32)
Look up a region by name
Returns a table with x, y, w, h fields for the named region, or nil if the name is not registered.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(512, 512)
atlas.add_region("player", 0, 0, 64, 64)
let r = atlas.get_region("player")
print("x={r["x"]} y={r["y"]} w={r["w"]} h={r["h"]}")
Remove a named region
Removes the named region. Returns true if the region existed and was removed, false if it was not found.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(512, 512)
atlas.add_region("temp", 0, 0, 16, 16)
print(atlas.remove_region("temp"))
print(atlas.remove_region("temp"))
List all regions with coordinates
Returns a list of all regions. Each entry is a table with name, x, y, w, h fields.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(512, 512)
atlas.add_region("a", 0, 0, 32, 32)
atlas.add_region("b", 32, 0, 32, 32)
let all = atlas.regions()
print(all[0]["name"])
Check if a region name exists
Returns true if a region with the given name is registered in the atlas.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(256, 256)
atlas.add_region("icon", 0, 0, 16, 16)
print(atlas.contains("icon"))
print(atlas.contains("missing"))
Get the atlas width in pixels
Returns the atlas width in pixels as set at construction or after resize.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(1024, 512)
print(atlas.width())
Get the atlas height in pixels
Returns the atlas height in pixels.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(1024, 512)
print(atlas.height())
Compute normalized UV coordinates
Computes normalized UV coordinates for the named region. Returns a table with u0, v0, u1, v1 as floats in [0, 1], suitable for GPU texture sampling. Returns nil if the region is not found.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(512, 512)
atlas.add_region("hero", 0, 0, 64, 64)
let uv = atlas.get_uv("hero")
print("u0={uv["u0"]} v0={uv["v0"]} u1={uv["u1"]} v1={uv["v1"]}")
Because UVs are computed from the current atlas dimensions, the same region
yields different coordinates after a resize:
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(64, 64)
atlas.add_region("tile", 0, 0, 64, 64)
print(atlas.get_uv("tile")["u1"])
atlas.resize(128, 128)
print(atlas.get_uv("tile")["u1"])
Find all regions matching a prefix
Returns all regions whose names start with prefix. Each entry has name, x, y, w, h. Useful for finding all frames of an animation (e.g. "walk_").
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(512, 256)
atlas.add_region("walk_0", 0, 0, 32, 32)
atlas.add_region("walk_1", 32, 0, 32, 32)
atlas.add_region("idle_0", 64, 0, 32, 32)
let frames = atlas.find_by_prefix("walk_")
print(frames[0]["name"])
Pair it with count to confirm a prefix matched the expected number of
frames before driving an animation:
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(512, 256)
atlas.add_region("run_0", 0, 0, 32, 32)
atlas.add_region("run_1", 32, 0, 32, 32)
atlas.add_region("jump_0", 64, 0, 32, 32)
let run = atlas.find_by_prefix("run_")
print("{run.len()} run frames of {atlas.count()} total")
Return the number of regions
Returns the number of regions currently registered.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(256, 256)
atlas.add_region("a", 0, 0, 16, 16)
atlas.add_region("b", 16, 0, 16, 16)
print(atlas.count())
Remove all regions
Removes all registered regions from the atlas. The atlas dimensions are unchanged.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(256, 256)
atlas.add_region("sprite", 0, 0, 32, 32)
atlas.clear()
print(atlas.count())
Change atlas dimensions
Updates the atlas pixel dimensions. Existing region pixel coordinates are not changed, but UV values will differ after a resize.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(256, 256)
atlas.resize(512, 512)
print(atlas.width())
Get width, height, and region count
Returns a summary table with width, height, and count fields.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(1024, 1024)
atlas.add_region("icon", 0, 0, 32, 32)
let info = atlas.info()
print("atlas {info["width"]}x{info["height"]}, {info["count"]} regions")
Auto-pack items using shelf algorithm
Auto-packs a list of {name, w, h} entries into the atlas using a shelf (row-based) bin-packing algorithm. Items are sorted by height descending for better fit. Returns the list of placed regions with their assigned coordinates. Errors if items do not fit.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(256, 256)
let items = [
#{"name": "hero", "w": 64, "h": 64},
#{"name": "coin", "w": 32, "h": 32},
#{"name": "gem", "w": 32, "h": 32}
]
let placed = atlas.pack(items)
print(placed[0]["name"])
print(atlas.count())
Packing can overflow when the items exceed the atlas area; size the atlas generously or pack in batches:
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(64, 64)
let tiles = [
#{"name": "a", "w": 48, "h": 48},
#{"name": "b", "w": 48, "h": 48}
]
let placed = atlas.pack(tiles)
for p in placed {
print("{p["name"]} -> ({p["x"]}, {p["y"]})")
}
Rename an existing region
Renames an existing region. Returns true on success, false if old_name was not found.
use plugin atlas::{TextureAtlas}
let atlas = TextureAtlas.new(256, 256)
atlas.add_region("tmp_sprite", 0, 0, 32, 32)
atlas.rename_region("tmp_sprite", "player_idle")
print(atlas.contains("player_idle"))