SDF Text Demo
App: apps/sdf_text_demo/
Demonstrates signed-distance-field text: five cached Text labels styled with face color, outline and softness. Four are drawn in world space with a model matrix, one is drawn in screen space as a HUD overlay. There is no camera and no scene — the demo sets an identity view/projection so the model matrix places each label directly in normalized device coordinates, which keeps it independent of any camera setup. After ~1.5 seconds it writes a screenshot and keeps running.
Run from root
Section titled “Run from root”% ./plume3d sdf_text_demoWhat it does
Section titled “What it does”- Builds five labels with
Text.new(content)ininit(), each styled once and re-drawn every frame:- PLUME3D — a bold gold title with a dark rim (
outlineColor,outlineWidth = 0.28). - subtitle — plain body text,
outlineWidth = 0.0. - paragraph — wrapped and centered via
align = 1andwrapWidth = 16.0. - rich text —
richText = true, with inline<color=#rrggbb>and<size=N>markup. - HUD — a screen-space label at
size = 24.0(pixels).
- PLUME3D — a bold gold title with a dark rim (
- Reads the measured
width,heightandlineCountback off the labels —width/heightdrive the layout math, and all three are logged withLogger.info. - Disables the camera by enabling the view/projection stage and feeding it identity matrices:
Graphics.setViewProjectionEnabled(true),setViewMatrix,setProjectionMatrix. - Draws the four world-space labels with
draw(model), passing a column-major 16-float model matrix built by aplaceCenteredhelper that scales each label to a target NDC half-width and centers it. - Draws the HUD label with
drawScreen(24, 24)— pixels, top-left origin. - Calls
Engine.screenshot("sdf_text_demo.png")once, ~1.5s in, counted down inupdate(dt).
Note that size means different things per draw path: world units for draw(model), pixels for drawScreen(x, y). The world-space labels all set size = 1.0 and let the model matrix do the scaling.
Key pattern
Section titled “Key pattern”// Style once in init() — labels are cached and re-drawn each frame._title = Text.new("PLUME3D")_title.color = [0.98, 0.80, 0.25, 1.0] // warm gold face_title.outlineColor = [0.10, 0.05, 0.0, 1.0] // dark rim_title.outlineWidth = 0.28
_rich = Text.new("<color=#ffd24a>rich</color> <size=1.5>text</size> markup")_rich.richText = true
// Scale a label to `halfWidth` in NDC and center it at cy (column-major).placeCentered(label, halfWidth, cy) { var w = label.width var h = label.height if (w <= 0.0001) return identity var s = (halfWidth * 2) / w return [ s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1, 0, -(w * s) / 2, cy - (h * s) / 2, 0, 1 ]}
draw() { Graphics.setViewProjectionEnabled(true) Graphics.setViewMatrix(identity) Graphics.setProjectionMatrix(identity)
_title.draw(placeCentered(_title, 0.80, -0.62)) // world space _hud.drawScreen(24, 24) // screen space, pixels}