Source:
draw.h
draw¶
Bounds-clipped, integer-only drawing from 1D through 3D over the flat light buffer.
The Bresenham walk and the clipping live here once, so an effect calls line rather than re-rolling it.
Classes¶
| Name | Description |
|---|---|
Canvas |
The surface a draw call writes to: a buffer plus the grid dimensions that address it. |
BlobPath |
One blob's orbit: where it sits at time t on a grid of w by h. |
UpscaleTap |
One destination column's blend: the two source columns and the weight between them. |
Canvas¶
src/light/powerfunctions/draw.h:58The surface a draw call writes to: a buffer plus the grid dimensions that address it.
Binding the two makes a mismatch unrepresentable, and applies the depth guard once rather than per effect.
Public Attributes¶
uint8_t * data = nullptr
: first byte of the light array
size_t bytes = 0
: total writable bytes (the bound every write is clipped to)
Coord3D dims {0, 0, 0}
: logical extents; z is >= 1 (see the depth guard above)
uint8_t cpl = 3
: channels per light
Public Methods¶
inline size_t offsetOf(Coord3D p) const
: Byte offset of a coordinate, or bytes when it is outside the grid.
Public Static Methods¶
static inline Canvas of(Buffer & buf, lengthType w, lengthType h, lengthType d)
: Build from a [Buffer] + the layer's logical extents, applying the depth guard.
BlobPath¶
src/light/powerfunctions/draw.h:372One blob's orbit: where it sits at time t on a grid of w by h.
Public Attributes¶
uint8_t speedMul
: multiplies the shared time base, so blobs drift apart
uint8_t phaseX
: phase offset on x, keeping the paths from coinciding
uint8_t phaseY
: the vertical path's phase offset
UpscaleTap¶
src/light/powerfunctions/draw.h:1064One destination column's blend: the two source columns and the weight between them.
Public Attributes¶
uint16_t a
uint16_t b
uint16_t w
Sprite¶
src/light/powerfunctions/draw.h:647A small movable bitmap: palette-indexed pixels (index 0 = the transparent key, the classic key-color scheme), frames stacked vertically (frame f = rows [fh, (f+1)h)).
Carried as constexpr data, the [fonts.h] shape. Full alpha (Porter-Duff over) stays deferred until a consumer needs it. A transparent index is what classic sprites used and what LED walls need.
Public Attributes¶
const uint8_t * pixels
: palette-indexed bytes, one per pixel per frame
const RGB * palette
: the sprite's own colors; index 0 is never read
uint8_t w
uint8_t h
uint8_t frames
uint8_t paletteCount
: the sprite's extents and its palette size
More info¶
Why the box is clipped¶
addPixel already rejects an out-of-bounds pixel, but only AFTER the distance function has run for it, which leaves two faults the clip removes. A radius the caller chose makes the walk cost r squared however small the grid is, so one large number stalls the render thread. And lengthType is 16 bits, so a radius near its ceiling puts x1 at INT16_MAX, the increment wraps to negative, and the loop never ends at all.
An empty canvas is emptied at BOTH ends for the same reason: the walk is inclusive. Setting only x1 = -1 left x0 at whatever negative value the caller computed, and -2 to -1 is a two-iteration range writing outside the buffer.
Addressing¶
Index order matches the engine, and a pixel outside the grid is silently clipped, so a line running off the edge stops drawing.
Signed distance fields¶
An SDF answers how far a point is from a shape's edge: negative inside, zero on it, positive outside. One number then gives a fill, an edge, an outline, a glow and a smooth blend, and the same expression serves a strand, a matrix and a volume.
Squared first¶
Measured on an S3 at 128 by 128: about 14 cycles a pixel squared, against about 108 for the true distance. So every shape has a squared variant, and an effect asks for a real distance only when it needs one.
Rendering below the output resolution¶
A field's cost is per light, so computing fewer and interpolating the rest is what affords one on a large fixture. The stretch costs a fixed price per output light, so it saves nothing on a field that was already cheap. On a 64 by 64 layer a two-octave field goes 59 to 34 microseconds at half resolution, a curl field 212 to 71.