(data …)
Defines embedded data for buffer initialization. Supports compile-time shape generators, inline float arrays, WASM (WebAssembly) generated data, and external image files.
Syntax
Section titled “Syntax”; Shape generator (compile-time mesh generation)(data :name cubeVerts (cube :format [position4 color4 uv2]))
; Inline float array(data :name weights :float32 [1.0 2.0 3.0])
; WASM-generated data(data :name curve (wasm-data :file "gen.wasm" :func make :returns "array<f32,360>"))
; External image file(data :name logoFile :file "path/to/file.png" :mime "image/png")| Key | Type | Required | Default | Description |
|---|---|---|---|---|
:name |
symbol | Yes | - | Unique data name |
| generator sub-form | positional form | No* | - | (cube …), (plane …), … or (wasm-data …) |
:float32 |
array | No* | - | Inline float array data |
:file |
string | No* | - | Image file path, relative to the source document |
:mime |
string | No | application/octet-stream |
MIME type stored with the :file bytes |
*One byte source, three spellings. A (data …) carries at most one
positional generator sub-form; a second one is a positional_too_many error
rather than a silently ignored form. If more than one spelling is present the
generator wins, then :file, then :float32; a (data …) with none of them
is an empty entry of zero bytes.
Shape Generators
Section titled “Shape Generators”Generate vertex data at compile time instead of writing arrays manually. A shape
is a positional sub-form inside (data …). Shape generators produce triangle
lists with the specified vertex attributes.
Available shapes: cube, plane, sphere, torus, truncated-cone,
cylinder, teapot, dragon. Each accepts a :format list, plus
generator-specific parameters:
| Key | Type | Default | Applies to |
|---|---|---|---|
:segments |
number | 24 |
sphere (longitude) |
:rings |
number | 12 |
sphere (latitude) |
:radius |
number | 1.0 |
sphere, torus (major radius), cylinder |
:thickness |
number | 0.24 |
torus (minor radius) |
:radial-subdivisions |
number | 24 |
torus, truncated-cone, cylinder |
:body-subdivisions |
number | 12 |
torus |
:vertical-subdivisions |
number | 1 |
truncated-cone, cylinder |
:bottom-radius |
number | 1.0 |
truncated-cone (a cylinder takes :radius for both ends) |
:top-radius |
number | 0.0 |
truncated-cone |
:height |
number | 1.0 |
truncated-cone, cylinder |
:top-cap / :bottom-cap |
boolean | true |
truncated-cone, cylinder |
:faceted |
boolean | false |
flat normals, one per triangle |
A subdivision count outside its generatable range is a compile error naming the key and the range: no generated mesh may exceed 65536 indices.
Generates a cube centered at the origin, vertices at ±1. Produces 36 vertices (6 faces × 2 triangles × 3 vertices), deindexed.
(data :name cubeVertices (cube :format [position4 color4 uv2]))Generates a single 1×1 quad on the XY plane, facing +Z. Produces 6 vertices (2 triangles), deindexed.
(data :name planeVertices (plane :format [position3 uv2]))sphere
Section titled “sphere”Generates a UV sphere. Extra parameters (:segments, :rings) tune the
tessellation:
(data :name sphereVertices (sphere :format [position3 normal3] :segments 24 :rings 12))Indexed Meshes
Section titled “Indexed Meshes”The teapot and dragon generators produce an indexed mesh: vertex data plus an
index companion. Source a vertex buffer from the shape and an index buffer with
:index-of:
(data :name teapotMesh (teapot :format [position3 normal3]))
(buffer :name vertexBuffer :usage [vertex] :data teapotMesh)(buffer :name indexBuffer :index-of teapotMesh :usage [index])Format Specifiers
Section titled “Format Specifiers”The :format array specifies which attributes to generate for each vertex:
| Specifier | Type | Size | Description |
|---|---|---|---|
position3 |
vec3f | 12 bytes | XYZ position |
position4 |
vec4f | 16 bytes | XYZW position (w=1) |
normal3 |
vec3f | 12 bytes | Surface normal |
color3 |
vec3f | 12 bytes | RGB vertex color |
color4 |
vec4f | 16 bytes | RGBA vertex color |
uv2 |
vec2f | 8 bytes | Texture coordinates |
Vertex stride is the sum of all attribute sizes. For [position4 color4 uv2]:
- position4: 16 bytes
- color4: 16 bytes
- uv2: 8 bytes
- Total stride: 40 bytes
:float32
Section titled “:float32”Type: array of numbers
Inline float values, written directly:
(data :name vertices :float32 [ 0.0 0.5 1.0 0.0 0.0 -0.5 -0.5 0.0 1.0 0.0 0.5 -0.5 0.0 0.0 1.0])
:float32takes a literal list only; there is no repeat-or-fill generator. For computed values, use a(wasm-data …)generator (below) to produce the bytes at compile time, or a compute init pass (see(init …)) to fill the buffer on the GPU.
WASM-Generated Data
Section titled “WASM-Generated Data”A (wasm-data …) sub-form calls a WASM function once at buffer-create time; its
returned bytes fill the buffer.
(data :name curve (wasm-data :file "gen.wasm" :func makeCurve :returns "array<f32,360>"))| Key | Type | Required | Description |
|---|---|---|---|
:file |
string | Yes | WASM file path, relative to the source document |
:func |
symbol | Yes | Exported function to call |
:returns |
string | Yes | Return type, turned into a byte count (array<f32,360> is 1440, mat4x4 is 64, vec4 is 16, f32 is 4) |
Modules are deduplicated by path, and are read at compile time, so an
unreadable :file is an error that names the path.
Type: string
Path to an image file, relative to the source document. It is embedded in the
PNGB payload (the compiled bytecode) at compile time as
[mime_len][mime][bytes], and decoded at runtime by an (image-bitmap …):
(data :name imageFile :file "textures/diffuse.png" :mime "image/png")Examples
Section titled “Examples”Cube with Shape Generator
Section titled “Cube with Shape Generator”(data :name cubeVertices (cube :format [position4 color4 uv2]))
(buffer :name vertexBuffer :usage [vertex] :data cubeVertices)
(render-pipeline :name cubeRenderer :layout auto (vertex :module shader :entry vs (vertex-buffer :array-stride 40 (attribute :shader-location 0 :offset 0 :format float32x4) (attribute :shader-location 1 :offset 16 :format float32x4) (attribute :shader-location 2 :offset 32 :format float32x2))) (fragment :module shader :entry fs (target :format preferred-canvas-format)))Simple Triangle (Manual Data)
Section titled “Simple Triangle (Manual Data)”(data :name triangleVerts :float32 [ 0.0 0.5 1 0 0 -0.5 -0.5 0 1 0 0.5 -0.5 0 0 1])
(buffer :name vertexBuffer :usage [vertex] :data triangleVerts)External Image
Section titled “External Image”(data :name textureData :file "assets/logo.png" :mime "image/png")
(image-bitmap :name logo :data textureData)Data Size
Section titled “Data Size”A buffer with :data takes its size from the data, so no byte count is written
beside it:
(data :name vertexData (cube :format [position4 color4 uv2]))
(buffer :name verts ; sized by the data it is filled from :usage [vertex] :data vertexData)Size calculation:
- Shape generators: vertex_count × stride (e.g. a cube with position4+color4+uv2 = 36 × 40 = 1440 bytes)
- Inline
:float32arrays: element_count × 4 bytes (wasm-data …): the byte count its:returnstype spells
A numeric :size beside :data is legal and over-allocates on purpose; a
:size smaller than the data is a compile error. A (data …) name is not
accepted in :size itself, which takes a number, an expression, or a
(define …) constant.
Validation Rules
Section titled “Validation Rules”| Rule | Error |
|---|---|
| A name is declared once, across every form kind | duplicate_cross_ref_target, or duplicate name 'x': already declared as a (data …) at line N |
| At most one generator sub-form | positional_too_many |
| The sub-form head is one of the nine generators | not_head_member |
:format entries are position3, position4, normal3, color3, color4 or uv2 |
not_member |
| A generator’s subdivision counts are in range | (sphere …) :segments 0 is outside the generatable range 3..4096 |
:file must be readable at compile time |
cannot read 'assets/logo.png': FileNotFound (located on the (data …) form; the path is resolved against the document’s directory) |
The rows with a code are schema checks; the rows with a message are compiler checks, and they report the line the form is written on.
Related
Section titled “Related”(buffer …)- Use data for buffer initialization(image-bitmap …)- Create images from blob data(queue …)- Write data to buffers at runtime