On this page
  1. tecs.gfx
  2. Coordinate conversion
  3. Fonts and layout
  4. Module contents
    1. Submodules
    2. Constructors
    3. Types
    4. Functions
  5. Constructors
    1. newTTF
  6. Types
    1. Bounds3D
    2. Camera2D
    3. Camera3D
    4. Clip
    5. DropShadow2D
    6. Font
    7. FontRaster
    8. Material
    9. Mesh
    10. MeshMaterial
    11. Occluder2D
    12. PointLight2D
    13. PreviousTransform2D
    14. Renderable2D
    15. Renderable3D
    16. Renderer
    17. Sprite
    18. Text
    19. TextOptions
    20. Tint
    21. TTFOptions
  7. Functions
    1. glyphAt
    2. imageId
    3. imageName
    4. measureIntrinsic
    5. measureText
    6. meshId
    7. meshMaterialId
    8. meshMaterialName
    9. meshName
    10. textLayouts
    11. textPlugin

tecs.gfx

Entity components that describe a rendered scene.

Transform2D places an entity, graphics components describe its appearance, and Renderable2D admits it to rendering. Transform2D, Tint, and Renderable2D form the minimum drawable set:

local player <const> = world:spawn(
    tecs.Transform2D(120, 80, 0, 1, 0, 32, 32),
    app.renderer.sprites:sprite("player.png"),
    tecs.gfx.Tint(1.0, 1.0, 1.0, 1.0),
    tecs.gfx.Renderable2D()
)

local tint <const> = world:getMut(player, tecs.gfx.Tint)
tint.a = 0.5

Sprite selects an image region. Material selects fragment coverage and lighting. Clip selects a target-pixel clip region. PointLight2D, Occluder2D, and DropShadow2D describe deferred lighting and shadows.

The 3D mesh contract is separate from the sprite lane. tecs.Transform3D, Mesh, Bounds3D, MeshMaterial, Tint, and Renderable3D describe an opaque mesh for the optional mesh domain. Material remains the compiled 2D shader identity; mesh material data has its own persisted name and resident slot.

Transform2D remains at tecs.Transform2D because physics, hierarchy, sequencing, and graphics share it. Other render components live under tecs.gfx.

Use world:getMut for authored changes. A direct cdata write through world:get must call world:markComponentDirty, or rendering keeps the old value. batchSpawn skips FFI defaults, so its callback must initialize every field.

PreviousTransform2D stores the pose before the current fixed step. The renderer interpolates it toward Transform2D for presentation without changing simulation state.

A camera maps world coordinates to one viewport.

The camera stores the view center in world units, zoom, and rotation. Callers write these fields directly:

local camera <const> = app.renderer.sprites.camera
camera.x = player.x
camera.y = player.y
camera.zoom = 2
camera.rotation = 0

Position names the center rather than a corner. The default view starts at the world origin. World Y and screen Y both increase downward.

Coordinate conversion

Each conversion takes the viewport dimensions because one camera can serve targets of different sizes:

local worldX <const>, worldY <const> = camera:toWorld(
    mouseX, mouseY, width, height
)

local screenX <const>, screenY <const> = camera:toScreen(
    worldX, worldY, width, height
)

Use the same dimensions for conversion and rendering. toWorld, toScreen, and matrix then share one mapping, and points round-trip. viewBounds returns a conservative axis-aligned world rectangle when the camera rotates.

matrix reuses the camera's sixteen-float array, and viewBounds reuses its four-element table. Copy either result before retaining it across another call.

A perspective camera maps a right-handed 3D world to one viewport.

World +X points right, +Y points up, and the default camera looks along -Z. The camera orientation is a quaternion in (x, y, z, w) order that turns camera-local coordinates into world coordinates. Position and orientation are caller-writable fields:

local camera <const> = tecs.gfx.newCamera3D({
    x = 0,
    y = 2,
    z = 6,
    verticalFov = math.rad(60),
})
camera.rotationY = math.sin(math.rad(15) * 0.5)
camera.rotationW = math.cos(math.rad(15) * 0.5)

matrix writes a column-major world-to-clip matrix with depth in [0, 1]. It reuses one sixteen-float array, so copy the result before retaining it across another call on the same camera.

Coordinates rendering domains and owns frame-wide GPU work.

An application owns one renderer. The renderer owns the deferred graph, presentation targets, capture, and staging-slot rotation. sprites is the 2D domain and meshes is the 3D domain. Each owns its own extraction, residency, instance buffers, and backend. A domain disabled at creation is neither loaded nor allocated.

This division is the 3D extension seam. A mesh domain can be prepared beside the sprite domain and contribute its own pass bodies without either domain branching per entity on what kind of renderer it belongs to.

When both domains contribute transparent work, meshes draw first and sprites draw second. Their camera spaces have no universal cross-domain depth order, so the fixed order makes sprites deterministic overlays while each domain retains its own back-to-front sort.

Shaped text as entities in the rendered world.

A Text names a font and string. Transform2D places its top-left corner, Tint colors every glyph, and Clip clips it like any other drawable.

world:addPlugin(tecs.gfx.textPlugin({
    renderer = app.renderer,
}))

world:spawn(
    tecs.Transform2D(24, 24),
    tecs.gfx.Tint(0.92, 0.96, 1.0, 1.0),
    tecs.gfx.Text.new({
        text = "tecs\n1200 entities",
        font = tecs.gfx.newTTF({
            source = "fonts/JetBrainsMono-ExtraBold.ttf",
        }).value,
        size = 28,
        align = "center",
    })
)

Write text fields through world:getMut. A direct world:get write leaves the column clean and the displayed glyphs unchanged.

Fonts and layout

newTTF reads source font bytes off the main thread and returns a Future. SDLttf and HarfBuzz shape and lay out UTF-8. Tecs asks SDLttf for glyph images lazily, caches each glyph once per renderer, and keeps its own one-instance-per-glyph producer.

The default "sdf" raster scales without regenerating glyphs. Choose a loaded size near the largest ordinary on-screen size. A fixed-size UI may instead load an "alpha" raster at exactly its displayed size. Alpha glyphs retain the font rasterizer's small-size fitting and automatically snap their origin on a screen-space layer when they are unrotated and unscaled.

Text supports explicit newlines and left, center, or right alignment. It does not wrap to a width, anchor outside the top-left corner, or style individual glyphs. The glyph material draws text unlit through the forward-blended lane so its distance-field edge retains partial coverage.

Module contents

Submodules

Submodule Description
tecs.gfx.animation Sprite sheets, fixed-step playback, Aseprite slices, pivots, and reloads
tecs.gfx.layers Layer bands, sorting, coordinate spaces, parallax, lighting, and clipping
tecs.gfx.materials Material selection, shader authoring, built-in materials, and reload rules
tecs.gfx.particles GPU particle effects, emitter playback, pool sizing, and rendering limits

Constructors

Constructor Description
newTTF Starts loading and opening a source font with SDL_ttf.

Types

Type Kind Description
Bounds3D record Defines a mesh's local-space bounding sphere.
Camera2D record Represents a view onto the world.
Camera3D record Represents one perspective view into a right-handed 3D world.
Clip record Restricts a renderable's fragments to a clip region.
DropShadow2D record Casts a stretched copy of the entity along the ground, away from light.
Font record Represents a loaded font named by Text.
FontRaster enum Selects a font's glyph raster representation.
Material record Selects the material that shades renderable geometry.
Mesh record Selects immutable geometry for the 3D mesh domain.
MeshMaterial record Selects resident PBR data for the 3D mesh domain.
Occluder2D record Blocks light from reaching what lies behind the entity.
PointLight2D record Represents a light resolved by the deferred lighting pass.
PreviousTransform2D record Stores the transform as it stood before the current fixed step.
Renderable2D record Marks an entity as contributing geometry.
Renderable3D record Marks an entity as contributing geometry to the 3D mesh domain.
Renderer record Something that draws instances without owning entities.
Sprite record Samples a texture instead of drawing flat color.
Text record Lays a string out into glyph instances.
TextOptions record Configures textPlugin.
Tint record Controls base color and how much of the background remains visible.
TTFOptions record Configures newTTF.

Functions

Function Kind Description
glyphAt Static Returns a glyph's world x, y, width, and height.
imageId Static Returns the index of an image name and assigns one on first use.
imageName Static Returns the name represented by an image index.
measureIntrinsic Static Returns the preferred and minimum-content metrics for a text item.
measureText Static Returns a text item's width and height in world units.
meshId Static Returns the process-local index of a normalized mesh asset name.
meshMaterialId Static Returns the process-local identity of a mesh material name.
meshMaterialName Static Returns the name represented by a mesh material index.
meshName Static Returns the normalized asset name represented by a mesh index.
textLayouts Static Returns how many texts the world has laid out.
textPlugin Static Creates the plugin that lays out text for a renderer.

Constructors

tecs.gfx.newTTF Static

Starts loading and opening a source font with SDL_ttf.

The file read happens on the asset worker. The future settles only after SDL_ttf has opened the bytes, selected the raster mode, and verified the requested point size.

function tecs.gfx.newTTF(options: TTFOptions): Future<Font>

Arguments

Name Type Description
options TTFOptions The caller must set source. name defaults to that path, size defaults to 48 points, and raster defaults to "sdf".

Returns

Type Description
Future<Font> Returns a Future for an immutable Font.

Types

tecs.gfx.Bounds3D record

Defines a mesh's local-space bounding sphere.

A sphere stays four floats in extraction and transforms conservatively under non-uniform scale by multiplying radius by the largest absolute scale axis. Asset loading may supply these values, and callers may override them for generated or animated geometry. Read-only. Exposes a local-space mesh bounding sphere. The center uses mesh-local coordinates and radius defaults to one world unit.

record tecs.gfx.Bounds3D is Component
    centerX: number
    centerY: number
    centerZ: number
    radius: number
end

Interfaces

Interface
Component

tecs.gfx.Bounds3D.centerX field

Caller-writable. Sets the local-space sphere-center x coordinate.

tecs.gfx.Bounds3D.centerX: number

tecs.gfx.Bounds3D.centerY field

Caller-writable. Sets the local-space sphere-center y coordinate.

tecs.gfx.Bounds3D.centerY: number

tecs.gfx.Bounds3D.centerZ field

Caller-writable. Sets the local-space sphere-center z coordinate.

tecs.gfx.Bounds3D.centerZ: number

tecs.gfx.Bounds3D.radius field

Caller-writable. Sets the non-negative local-space sphere radius.

tecs.gfx.Bounds3D.radius: number

tecs.gfx.Camera2D record

Represents a view onto the world.

Assign every field directly, frame by frame. A renderer copies the values it draws from during extraction, so moving a camera afterwards affects the next frame, not the one in flight.

global record tecs.gfx.Camera2D
    record Options
        x: number
        y: number
        zoom: number
        rotation: number
    end

    x: number
    y: number
    zoom: number
    rotation: number

    newCamera2D: function(options: Camera2DOptions): Camera2D
    matrix: function(self, width: number, height: number): loader.CArray
    toScreen: function(
        self,
        worldX: number,
        worldY: number,
        width: number,
        height: number
    ): number, number
    toWorld: function(
        self,
        screenX: number,
        screenY: number,
        width: number,
        height: number
    ): number, number
    viewBounds: function(self, width: number, height: number): {number}
end

tecs.gfx.Camera2D.Options record

Names the options accepted by newCamera2D so a game can annotate the table it passes without reaching into this file.

record tecs.gfx.Camera2D.Options
    x: number
    y: number
    zoom: number
    rotation: number
end

tecs.gfx.Camera2D.Options.x field

Caller-writable. Sets the center of the view in world units. Both values default to zero.

tecs.gfx.Camera2D.Options.x: number

tecs.gfx.Camera2D.Options.y field

Caller-writable. Sets the center of the view in world units. Both values default to zero.

tecs.gfx.Camera2D.Options.y: number

tecs.gfx.Camera2D.Options.zoom field

Caller-writable. Sets the zoom and defaults to one. Zero or less divides through in every method here and is not rejected.

tecs.gfx.Camera2D.Options.zoom: number

tecs.gfx.Camera2D.Options.rotation field

Caller-writable. Sets the rotation in radians and defaults to zero.

tecs.gfx.Camera2D.Options.rotation: number

tecs.gfx.Camera2D.x field

Caller-writable. Sets the horizontal center of the view in world units.

tecs.gfx.Camera2D.x: number

tecs.gfx.Camera2D.y field

Caller-writable. Sets the vertical center of the view in world units. Increasing y moves the view towards the bottom of the world.

tecs.gfx.Camera2D.y: number

tecs.gfx.Camera2D.zoom field

Caller-writable. Sets the zoom. Values above one magnify about the center without moving the point under the middle of the window.

tecs.gfx.Camera2D.zoom: number

tecs.gfx.Camera2D.rotation field

Caller-writable. Sets the rotation in radians. Positive values turn the scene counter-clockwise on screen.

tecs.gfx.Camera2D.rotation: number

tecs.gfx.Camera2D.newCamera2D Static

Creates a camera. Everything defaults to an unrotated, unzoomed view at the world origin, which a renderer then recenters if the game never moves it.

function tecs.gfx.Camera2D.newCamera2D(
    options: Camera2DOptions
): Camera2D
Arguments
Name Type Description
options Camera2DOptions Omit for the default view. The constructor stores every value without validation.
Returns
Type Description
Camera2D Returns a camera whose fields the caller assigns directly.

tecs.gfx.Camera2D:matrix Instance

Writes the world-to-clip matrix for a viewport of width by height.

Column major, because that is how a GLSL mat4 reads a uniform: the first four floats are the first column, not the first row. Transposing these is a mistake that renders something plausible rather than nothing, which is how it survives review.

function tecs.gfx.Camera2D.matrix(
    self, width: number, height: number
): loader.CArray
Arguments
Name Type Description
self Camera2D
width number Viewport width in pixels.
height number Viewport height in pixels.
Returns
Type Description
loader.CArray The camera's own sixteen-float array, rewritten in place. It is valid until the next call on this camera, so a caller that needs to keep it copies it rather than holding the pointer.

tecs.gfx.Camera2D:toScreen Instance

Converts a world point to screen space.

Exactly the inverse of toWorld at the same width and height, and the same mapping the matrix applies, so a point round-trips.

function tecs.gfx.Camera2D.toScreen(
    self, worldX: number, worldY: number, width: number, height: number
): number, number
Arguments
Name Type Description
self Camera2D
worldX number World x.
worldY number World y, running down.
width number Viewport width in pixels, the same one the matrix was built with.
height number Viewport height in pixels, the same one the matrix was built with.
Returns
Type Description
number Returns screen x from the left and screen y from the top, in pixels. The function does not clamp either value to the viewport.
number

tecs.gfx.Camera2D:toWorld Instance

Converts a screen point to world space.

The inverse of what the matrix does, written out rather than inverted, so the Y flip appears once here in the same place it appears above.

function tecs.gfx.Camera2D.toWorld(
    self,
    screenX: number,
    screenY: number,
    width: number,
    height: number
): number, number
Arguments
Name Type Description
self Camera2D
screenX number Pixels from the left of the viewport.
screenY number Pixels from the top of the viewport, running down.
width number Viewport width in pixels, the same one the matrix was built with.
height number Viewport height in pixels, the same one the matrix was built with.
Returns
Type Description
number The world x, then the world y. Points outside the viewport convert too, and land outside the view rectangle.
number

tecs.gfx.Camera2D:viewBounds Instance

Returns the world-space rectangle this camera can see as minX, minY, maxX, and maxY.

When rotated, an axis-aligned box encloses the view's corners, so culling keeps a little more than it must. Keeping too much costs a few instances; keeping too little drops geometry that should have drawn, which is why the error goes this way.

function tecs.gfx.Camera2D.viewBounds(
    self, width: number, height: number
): {number}
Arguments
Name Type Description
self Camera2D
width number Viewport width in pixels.
height number Viewport height in pixels.
Returns
Type Description
{number} The camera's own four-element table, rewritten in place. It is valid until the next call on this camera, so a caller that needs to keep it copies it rather than holding the table.

tecs.gfx.Camera3D record

Represents one perspective view into a right-handed 3D world.

global record tecs.gfx.Camera3D
    record Options
        x: number
        y: number
        z: number
        rotationX: number
        rotationY: number
        rotationZ: number
        rotationW: number
        verticalFov: number
        near: number
        far: number
    end

    x: number
    y: number
    z: number
    rotationX: number
    rotationY: number
    rotationZ: number
    rotationW: number
    verticalFov: number
    near: number
    far: number

    newCamera3D: function(options: Camera3DOptions): Camera3D
    matrix: function(self, width: number, height: number): loader.CArray
end

tecs.gfx.Camera3D.Options record

Names the options accepted by newCamera3D.

record tecs.gfx.Camera3D.Options
    x: number
    y: number
    z: number
    rotationX: number
    rotationY: number
    rotationZ: number
    rotationW: number
    verticalFov: number
    near: number
    far: number
end

tecs.gfx.Camera3D.Options.x field

Caller-writable. Sets the world-space x coordinate and defaults to zero.

tecs.gfx.Camera3D.Options.x: number

tecs.gfx.Camera3D.Options.y field

Caller-writable. Sets the world-space y coordinate and defaults to zero.

tecs.gfx.Camera3D.Options.y: number

tecs.gfx.Camera3D.Options.z field

Caller-writable. Sets the world-space z coordinate and defaults to zero.

tecs.gfx.Camera3D.Options.z: number

tecs.gfx.Camera3D.Options.rotationX field

Caller-writable. Sets the orientation quaternion x component and defaults to zero.

tecs.gfx.Camera3D.Options.rotationX: number

tecs.gfx.Camera3D.Options.rotationY field

Caller-writable. Sets the orientation quaternion y component and defaults to zero.

tecs.gfx.Camera3D.Options.rotationY: number

tecs.gfx.Camera3D.Options.rotationZ field

Caller-writable. Sets the orientation quaternion z component and defaults to zero.

tecs.gfx.Camera3D.Options.rotationZ: number

tecs.gfx.Camera3D.Options.rotationW field

Caller-writable. Sets the orientation quaternion scalar component and defaults to one.

tecs.gfx.Camera3D.Options.rotationW: number

tecs.gfx.Camera3D.Options.verticalFov field

Caller-writable. Sets the vertical field of view in radians and defaults to pi divided by three.

tecs.gfx.Camera3D.Options.verticalFov: number

tecs.gfx.Camera3D.Options.near field

Caller-writable. Sets the positive near-plane distance and defaults to 0.1 world units.

tecs.gfx.Camera3D.Options.near: number

tecs.gfx.Camera3D.Options.far field

Caller-writable. Sets the far-plane distance and defaults to 1000 world units.

tecs.gfx.Camera3D.Options.far: number

tecs.gfx.Camera3D.x field

Caller-writable. Sets the world-space x coordinate.

tecs.gfx.Camera3D.x: number

tecs.gfx.Camera3D.y field

Caller-writable. Sets the world-space y coordinate.

tecs.gfx.Camera3D.y: number

tecs.gfx.Camera3D.z field

Caller-writable. Sets the world-space z coordinate.

tecs.gfx.Camera3D.z: number

tecs.gfx.Camera3D.rotationX field

Caller-writable. Sets the local-to-world orientation quaternion x component.

tecs.gfx.Camera3D.rotationX: number

tecs.gfx.Camera3D.rotationY field

Caller-writable. Sets the local-to-world orientation quaternion y component.

tecs.gfx.Camera3D.rotationY: number

tecs.gfx.Camera3D.rotationZ field

Caller-writable. Sets the local-to-world orientation quaternion z component.

tecs.gfx.Camera3D.rotationZ: number

tecs.gfx.Camera3D.rotationW field

Caller-writable. Sets the local-to-world orientation quaternion scalar component.

tecs.gfx.Camera3D.rotationW: number

tecs.gfx.Camera3D.verticalFov field

Caller-writable. Sets the vertical field of view in radians between zero and pi.

tecs.gfx.Camera3D.verticalFov: number

tecs.gfx.Camera3D.near field

Caller-writable. Sets the positive near-plane distance.

tecs.gfx.Camera3D.near: number

tecs.gfx.Camera3D.far field

Caller-writable. Sets the far-plane distance, which must exceed near.

tecs.gfx.Camera3D.far: number

tecs.gfx.Camera3D.newCamera3D Static

Creates a perspective camera.

function tecs.gfx.Camera3D.newCamera3D(
    options: Camera3DOptions
): Camera3D
Arguments
Name Type Description
options Camera3DOptions Omit for an identity camera at the origin looking along negative z.
Returns
Type Description
Camera3D A camera whose fields the caller assigns directly.

tecs.gfx.Camera3D:matrix Instance

Writes the column-major world-to-clip matrix for a viewport.

The method normalizes the camera quaternion while calculating the view, without modifying the caller's fields. Clip depth maps near to zero and far to one.

function tecs.gfx.Camera3D.matrix(
    self, width: number, height: number
): loader.CArray
Arguments
Name Type Description
self Camera3D
width number The positive viewport width in pixels.
height number The positive viewport height in pixels.
Returns
Type Description
loader.CArray The camera's own sixteen-float array, valid until the next call on this camera.

tecs.gfx.Clip record

Restricts a renderable's fragments to a clip region.

A component rather than a field on something every renderable has, because presence is the opt-in and absence is the common case. Archetypes without this column skip clipping, and their fragments never read the region table.

The index names a rectangle set with renderer.sprites:setClipRegion. Zero, which is the default, means no clipping. Nesting is the caller's: a region is one rectangle, so a panel inside a panel is set up as the intersection of the two rather than as two regions an instance sits in at once. Read-only. Exposes the clip component, which keeps a renderable's fragments inside one rectangle. index names a region set with renderer.sprites:setClipRegion, and 0, the default, means no clipping. A region is a single rectangle, so the caller intersects nested regions.

record tecs.gfx.Clip is Component
    index: number
end

Interfaces

Interface
Component

tecs.gfx.Clip.index field

Caller-writable. Selects a clip region configured with renderer.sprites:setClipRegion. Zero disables clipping.

tecs.gfx.Clip.index: number

tecs.gfx.DropShadow2D record

Casts a stretched copy of the entity along the ground, away from light.

This darkens everything a light left, including ambient light, which Occluder2D cannot do. It blocks no light in return: a crowd of light-blocking silhouettes merges under the mask into one flat mat of darkness, so the thing that wants a contact shadow is exactly the thing that must not be an occluder. An entity carrying both is an occluder, because dropping that half would silently unblock a light.

The nearest few lights by weight throw the copy. Adding a distant light does not move an established shadow. Read-only. Exposes the drop-shadow component, which darkens the ground away from each nearby light, including ambient light, without blocking light. height is 0 to 1 and controls the copy's travel under the same interpretation as Occluder2D.height.

record tecs.gfx.DropShadow2D is Component
    height: number
end

Interfaces

Interface
Component

tecs.gfx.DropShadow2D.height field

Caller-writable. Sets how far lights throw the shadow, from zero to one of the world's configured shadow height.

tecs.gfx.DropShadow2D.height: number

tecs.gfx.Font record

Represents a loaded font named by Text.

record tecs.gfx.Font
    name: string
    source: string
    size: number
    raster: FontRaster
end

tecs.gfx.Font.name field

Read-only. Reports the caller-selected identity that snapshots store.

tecs.gfx.Font.name: string

tecs.gfx.Font.source field

Read-only. Reports the source path passed to newTTF.

tecs.gfx.Font.source: string

tecs.gfx.Font.size field

Read-only. Reports the point size at which SDL_ttf rasterizes glyphs.

tecs.gfx.Font.size: number

tecs.gfx.Font.raster field

Read-only. Reports whether glyph images contain a scalable distance field or direct alpha coverage.

tecs.gfx.FontRaster enum

Selects a font's glyph raster representation.

enum tecs.gfx.FontRaster
    "alpha"
    "sdf"
end

tecs.gfx.Material record

Selects the material that shades renderable geometry.

Absent means the default 2D material. It samples the sprite image array and covers the whole quad, so an entity with neither a Sprite nor a Material still draws. Present selects one of the compiled shader materials found under materials/.

Use materials.id(name) instead of writing an id. Sorted material names determine ids, so adding a file may renumber them. Snapshots therefore store only the material name.

Meshes use MeshMaterial, whose resident PBR data is independent from this compiled 2D shader identity. Read-only. Exposes the compiled 2D shader material component. Absent selects the default material. Take id from materials.id(name) rather than writing a number because sorted material names determine ids and may move when a file appears. Meshes use MeshMaterial.

record tecs.gfx.Material is Component
    id: number
    param: number
end

Interfaces

Interface
Component

tecs.gfx.Material.id field

Caller-writable. Selects a material by the id returned from materials.id.

tecs.gfx.Material.id: number

tecs.gfx.Material.param field

Caller-writable. Passes a value from zero to one to the material. The material's business; the rounded rectangle reads it as a corner radius.

tecs.gfx.Material.param: number

tecs.gfx.Mesh record

Selects immutable geometry for the 3D mesh domain.

asset is the process-local index returned by meshId. slot is engine-owned residency state and starts negative so a mesh domain can resolve it once. Snapshots store only the normalized asset name. Read-only. Exposes the mesh-reference component. asset is a process-local meshId and zero means no mesh. slot is engine-owned residency state and a negative value means unresolved.

record tecs.gfx.Mesh is Component
    asset: number
    slot: number
end

Interfaces

Interface
Component

tecs.gfx.Mesh.asset field

Caller-writable. Selects geometry by its meshId index. Zero selects no mesh.

tecs.gfx.Mesh.asset: number

tecs.gfx.Mesh.slot field

Engine-owned. Stores the mesh domain's residency slot. Set it negative when changing asset; otherwise ordinary game code should ignore it.

tecs.gfx.Mesh.slot: number

tecs.gfx.MeshMaterial record

Selects resident PBR data for the 3D mesh domain.

A compiled 2D Material and a loaded glTF material are different compatibility surfaces. asset therefore names a mesh material independently, while slot is engine-owned device residency. Zero in both fields selects the neutral built-in material. Read-only. Exposes the 3D material-reference component. asset is a process-local meshMaterialId; slot is engine-owned residency, and zero selects the neutral built-in material.

record tecs.gfx.MeshMaterial is Component
    asset: number
    slot: number
end

Interfaces

Interface
Component

tecs.gfx.MeshMaterial.asset field

Caller-writable. Selects material data by its meshMaterialId index. Zero selects the neutral built-in material.

tecs.gfx.MeshMaterial.asset: number

tecs.gfx.MeshMaterial.slot field

Engine-owned. Stores the mesh domain's resident material slot. Set it negative when changing asset; otherwise game code should ignore it.

tecs.gfx.MeshMaterial.slot: number

tecs.gfx.Occluder2D record

Blocks light from reaching what lies behind the entity.

The renderer adds the silhouette to the occluder mask every light samples, so one entity blocks every light at the cost of one drawing of itself rather than one per light. It blocks each light's contribution, not ambient light. DropShadow2D handles ambient darkening.

Coverage is the silhouette, so a circle, a rounded box or a glyph casts the shape it draws with no threshold of its own to set. A translucent entity casts nothing: it is drawn forward over the composited image and never reaches the G-buffer, so a hard silhouette of it would be a lie. Read-only. Exposes the occluder component, which blocks every light with the entity's shape. height is 0 to 1 of the world height Deferred.shadowHeight sets, so 1 is a full wall and 0 blocks nothing. This component requires renderer shadows.

record tecs.gfx.Occluder2D is Component
    height: number
end

Interfaces

Interface
Component

tecs.gfx.Occluder2D.height field

Caller-writable. Sets the occluder height from zero to one of the world's configured shadow height.

tecs.gfx.Occluder2D.height: number

tecs.gfx.PointLight2D record

Represents a light resolved by the deferred lighting pass. Read-only. Exposes the point-light component resolved by deferred lighting and positioned by the entity's Transform2D. height is above the surface plane and at 0 the light contributes nothing at all; radius is its reach in world units; r, g, b and intensity default to white at 1.

record tecs.gfx.PointLight2D is Component
    height: number
    radius: number
    r: number
    g: number
    b: number
    intensity: number
end

Interfaces

Interface
Component

tecs.gfx.PointLight2D.height field

Caller-writable. Sets the height above the surface plane. At zero, the Lambert term vanishes and the light contributes nothing.

tecs.gfx.PointLight2D.height: number

tecs.gfx.PointLight2D.radius field

Caller-writable. Sets the light's reach in world units.

tecs.gfx.PointLight2D.radius: number

tecs.gfx.PointLight2D.r field

Caller-writable. Sets the red channel from zero to one.

tecs.gfx.PointLight2D.r: number

tecs.gfx.PointLight2D.g field

Caller-writable. Sets the green channel from zero to one.

tecs.gfx.PointLight2D.g: number

tecs.gfx.PointLight2D.b field

Caller-writable. Sets the blue channel from zero to one.

tecs.gfx.PointLight2D.b: number

tecs.gfx.PointLight2D.intensity field

Caller-writable. Scales the light's contribution.

tecs.gfx.PointLight2D.intensity: number

tecs.gfx.PreviousTransform2D record

Stores the transform as it stood before the current fixed step.

Presence is the opt-in: an entity carrying it is drawn somewhere between this and its current transform, according to how far through the step the frame falls. Simulation advances in fixed jumps and frames arrive whenever the display asks for one, so without this an entity moved by physics steps visibly rather than moving.

Only the fields that move continuously are here. Scale and layer change by assignment rather than by integration, and a half-applied assignment is not a value anything asked for. Read-only. Exposes the transform component used for frame interpolation. Presence is the opt-in to interpolation: an entity carrying it is drawn between this and its current transform, so physics does not step visibly. Carries x, y and rotation (radians) only, because scale and layer change by assignment rather than by integration.

record tecs.gfx.PreviousTransform2D is Component
    x: number
    y: number
    rotation: number
end

Interfaces

Interface
Component

tecs.gfx.PreviousTransform2D.x field

Engine-owned. Stores the previous horizontal position for frame interpolation. Ordinary game code should ignore this field.

tecs.gfx.PreviousTransform2D.x: number

tecs.gfx.PreviousTransform2D.y field

Engine-owned. Stores the previous vertical position for frame interpolation. Ordinary game code should ignore this field.

tecs.gfx.PreviousTransform2D.y: number

tecs.gfx.PreviousTransform2D.rotation field

Engine-owned. Stores the previous rotation in radians for frame interpolation. Ordinary game code should ignore this field.

tecs.gfx.PreviousTransform2D.rotation: number

tecs.gfx.Renderable2D record

Marks an entity as contributing geometry. Without it, a Transform2D represents only a position. Read-only. Exposes the renderable tag, which marks an entity as contributing geometry. The tag costs a column of nothing; without it a Transform2D is only a position, which is what most entities in a world are.

record tecs.gfx.Renderable2D is Component
end

Interfaces

Interface
Component

tecs.gfx.Renderable3D record

Marks an entity as contributing geometry to the 3D mesh domain. Without it, a tecs.Transform3D and Mesh describe state but enter no render query. Read-only. Exposes the tag that admits an entity carrying tecs.Transform3D, Mesh, and Bounds3D to the mesh domain.

record tecs.gfx.Renderable3D is Component
end

Interfaces

Interface
Component

tecs.gfx.Renderer record

global record tecs.gfx.Renderer
    record Options
        ambient: {number}
        shadows: Deferred.ShadowOptions
        sprites: SpriteDomain.Options | boolean
        meshes: MeshDomain.Options
    end

    record SpriteDomain
        record Options
            capacity: integer
            cell: integer
            layers: integer
            reserveRuns: boolean
            partialRewrites: boolean
            packImages: boolean
        end

        record InstanceProducer
            destroy: function(InstanceProducer) | nil

            blended: function(self): integer
            casting: function(self): integer
            count: function(self): integer
            takeDirty: function(self): {integer}
            write: function(
                self,
                loader.CArray,
                loader.CArray,
                integer,
                integer,
                integer
            )
        end

        record ClipRegion
            x: number
            y: number
            width: number
            height: number
        end

        record ComputeStage
            active: function(self): boolean
            destroy: function(self)
            record: function(self, Frame, Buffer, Buffer)
        end

        camera: Camera2D
        capacity: integer
        count: integer
        dropped: integer
        rewritten: integer
        images: TextureArray
        instances: Buffer

        addComputeStage: function(self, stage: ComputeStage)
        addProducer: function(self, producer: InstanceProducer)
        clearClipRegion: function(self, index: integer)
        regionOf: function(self, path: string): TextureArray.Region
        registerImage: function(
            self, decoded: assets.Image
        ): components.Sprite, TextureArray.Region
        replaceImage: function(
            self, decoded: assets.Image
        ): components.Sprite, TextureArray.Region
        reservesRuns: function(self): boolean
        setClipRegion: function(
            self, index: integer, region: ClipRegion
        )
        sprite: function(
            self,
            name: string,
            u0: number,
            v0: number,
            u1: number,
            v1: number
        ): components.Sprite
        spriteSize: function(
            self, sprite: components.Sprite
        ): number, number
    end

    record SpriteOptions
        capacity: integer
        cell: integer
        layers: integer
        reserveRuns: boolean
        partialRewrites: boolean
        packImages: boolean
    end

    record SpriteInstanceProducer
        destroy: function(InstanceProducer) | nil

        blended: function(self): integer
        casting: function(self): integer
        count: function(self): integer
        takeDirty: function(self): {integer}
        write: function(
            self,
            loader.CArray,
            loader.CArray,
            integer,
            integer,
            integer
        )
    end

    record SpriteClipRegion
        x: number
        y: number
        width: number
        height: number
    end

    record SpriteComputeStage
        active: function(self): boolean
        destroy: function(self)
        record: function(self, Frame, Buffer, Buffer)
    end

    record MeshDomain
        record Options
            capacity: integer
            vertexCapacity: integer
            indexCapacity: integer
            materialCapacity: integer
            textureWidth: integer
            textureHeight: integer
            textureLayers: integer
            packTextures: boolean
            transparency: boolean
        end

        record MaterialOptions
            name: string
            model: integer
            alphaMode: integer
            baseColorTexture: integer
            normalTexture: integer
            metallicRoughnessTexture: integer
            occlusionTexture: integer
            emissiveTexture: integer
            alphaCutoff: number
            baseR: number
            baseG: number
            baseB: number
            baseA: number
            emissiveR: number
            emissiveG: number
            emissiveB: number
            metallic: number
            roughness: number
            normalScale: number
            occlusionStrength: number
        end

        record RegisteredPrimitive
            transform: ecs.Transform3D
            mesh: components.Mesh
            bounds: components.Bounds3D
            material: components.MeshMaterial
        end

        MATERIAL_METALLIC_ROUGHNESS: integer
        MATERIAL_UNLIT: integer
        ALPHA_OPAQUE: integer
        ALPHA_MASK: integer
        ALPHA_BLEND: integer
        camera: Camera3D
        capacity: integer
        vertexCapacity: integer
        indexCapacity: integer
        count: integer
        dropped: integer
        rewritten: integer
        meshCount: integer
        vertexCount: integer
        indexCount: integer
        materialCount: integer
        textureCount: integer
        transparency: boolean
        vertices: Buffer
        indices: Buffer
        instances: Buffer
        materials: Buffer

        material: function(self, name: string): components.MeshMaterial
        mesh: function(
            self, name: string
        ): components.Mesh, components.Bounds3D
        registerMaterial: function(
            self, options: MeshMaterialOptions
        ): components.MeshMaterial
        registerMesh: function(
            self, mesh: assets.Mesh
        ): components.Mesh, components.Bounds3D
        registerModel: function(
            self, model: assets.Model
        ): {RegisteredPrimitive}
        registerTexture: function(self, image: assets.Image): integer
    end

    record MeshOptions
        capacity: integer
        vertexCapacity: integer
        indexCapacity: integer
        materialCapacity: integer
        textureWidth: integer
        textureHeight: integer
        textureLayers: integer
        packTextures: boolean
        transparency: boolean
    end

    sprites: SpriteDomain
    meshes: MeshDomain
    deferred: Deferred

    newRenderer: function(
        device: loader.CPtr,
        swapchainFormat: integer,
        options: RendererOptions
    ): Renderer
    captureTexture: function(self): Texture
    depthSortCollapse: function(self): number
    destroy: function(self)
    device: function(self): loader.CPtr
    extractSeconds: function(self): number
    install: function(self, world: types.World)
    rebuildPipelines: function(self)
    render: function(self, frame: Frame)
    saveScreenshot: function(self, path: string): boolean, string
    screenshot: function(self): string, string
end

tecs.gfx.Renderer.Options record

record tecs.gfx.Renderer.Options
    ambient: {number}
    shadows: Deferred.ShadowOptions
    sprites: SpriteDomain.Options | boolean
    meshes: MeshDomain.Options
end

tecs.gfx.Renderer.Options.ambient field

Caller-writable. Sets ambient red, green, and blue and defaults to white.

tecs.gfx.Renderer.Options.ambient: {number}

tecs.gfx.Renderer.Options.shadows field

Caller-writable. Enables and configures 2D shadows. Nil disables them.

tecs.gfx.Renderer.Options.shadows: Deferred.ShadowOptions

tecs.gfx.Renderer.Options.sprites field

Caller-writable. Configures the 2D sprite rendering domain. False disables it; nil enables it with defaults.

tecs.gfx.Renderer.Options.meshes field

Caller-writable. Configures and enables the 3D mesh rendering domain. Nil leaves every mesh module and allocation out of this renderer.

tecs.gfx.Renderer.SpriteDomain record

record tecs.gfx.Renderer.SpriteDomain
    record Options
        capacity: integer
        cell: integer
        layers: integer
        reserveRuns: boolean
        partialRewrites: boolean
        packImages: boolean
    end

    record InstanceProducer
        destroy: function(InstanceProducer) | nil

        blended: function(self): integer
        casting: function(self): integer
        count: function(self): integer
        takeDirty: function(self): {integer}
        write: function(
            self,
            loader.CArray,
            loader.CArray,
            integer,
            integer,
            integer
        )
    end

    record ClipRegion
        x: number
        y: number
        width: number
        height: number
    end

    record ComputeStage
        active: function(self): boolean
        destroy: function(self)
        record: function(self, Frame, Buffer, Buffer)
    end

    camera: Camera2D
    capacity: integer
    count: integer
    dropped: integer
    rewritten: integer
    images: TextureArray
    instances: Buffer

    addComputeStage: function(self, stage: ComputeStage)
    addProducer: function(self, producer: InstanceProducer)
    clearClipRegion: function(self, index: integer)
    regionOf: function(self, path: string): TextureArray.Region
    registerImage: function(
        self, decoded: assets.Image
    ): components.Sprite, TextureArray.Region
    replaceImage: function(
        self, decoded: assets.Image
    ): components.Sprite, TextureArray.Region
    reservesRuns: function(self): boolean
    setClipRegion: function(self, index: integer, region: ClipRegion)
    sprite: function(
        self,
        name: string,
        u0: number,
        v0: number,
        u1: number,
        v1: number
    ): components.Sprite
    spriteSize: function(
        self, sprite: components.Sprite
    ): number, number
end

tecs.gfx.Renderer.SpriteDomain.Options record
record tecs.gfx.Renderer.SpriteDomain.Options
    capacity: integer
    cell: integer
    layers: integer
    reserveRuns: boolean
    partialRewrites: boolean
    packImages: boolean
end

tecs.gfx.Renderer.SpriteDomain.Options.capacity field

Caller-writable. Sets the maximum resident sprite-instance count. Rows beyond this fixed ceiling are dropped instead of growing a buffer under a frame that may still read it.

tecs.gfx.Renderer.SpriteDomain.Options.cell field

Caller-writable. Sets the image-array cell size in pixels.

tecs.gfx.Renderer.SpriteDomain.Options.cell: integer

tecs.gfx.Renderer.SpriteDomain.Options.layers field

Caller-writable. Sets the image-array layer count.

tecs.gfx.Renderer.SpriteDomain.Options.reserveRuns field

Caller-writable. Gives archetype runs room to grow without moving every later run. Defaults to false, which packs runs end to end.

tecs.gfx.Renderer.SpriteDomain.Options.partialRewrites field

Caller-writable. Rewrites only structurally changed rows instead of a whole archetype run. Defaults to false.

tecs.gfx.Renderer.SpriteDomain.Options.packImages field

Caller-writable. Packs many images into each array layer. Defaults to false, which gives each image its own layer.

tecs.gfx.Renderer.SpriteDomain.InstanceProducer record

Something that draws instances without owning entities.

Text is the reason this exists. A glyph is a textured quad like any other, but making each one an entity puts every glyph in the world into one archetype, so editing one string marks that column dirty and rewrites all of them; and spawning or despawning glyphs moves an archetype's length, which forces the whole scene to be laid out again. A producer sidesteps both: it is laid out as its own run, and it says which parts of that run changed.

It writes the same sixteen floats and four bounds floats every other instance carries, so culling, depth, layers and materials all apply to it without knowing it is not an entity.

record tecs.gfx.Renderer.SpriteDomain.InstanceProducer
    destroy: function(InstanceProducer) | nil

    blended: function(self): integer
    casting: function(self): integer
    count: function(self): integer
    takeDirty: function(self): {integer}
    write: function(
        self, loader.CArray, loader.CArray, integer, integer, integer
    )
end

tecs.gfx.Renderer.SpriteDomain.InstanceProducer.destroy field

Caller-writable. Releases work the producer owns. The renderer calls this at most once, before releasing the device resources its instances feed. The producer may omit it when it has nothing to release.

tecs.gfx.Renderer.SpriteDomain.InstanceProducer:blended Instance

Instances of its run that may reach the forward pass.

Asked every sync, because the forward lane is skipped entirely on a frame nothing said was blended and a producer whose run holds blended instances would then not be drawn. A producer that never blends answers zero and costs one call.

An upper bound rather than a count, and deliberately: a producer whose instances are written by compute cannot know how many of them a frame actually has. Over-reporting runs a lane that finds less than it was told to expect, which is the safe direction; under-reporting drops the whole lane, which is not.

function tecs.gfx.Renderer.SpriteDomain.InstanceProducer.blended(
    self
): integer
Arguments
Name Type Description
self InstanceProducer
Returns
Type Description
integer

tecs.gfx.Renderer.SpriteDomain.InstanceProducer:casting Instance

Caller-writable. Reports instances of its run that may reach the shadow lane.

This has the same upper-bound contract as blended: a CPU producer answers exactly, while a compute producer may conservatively report every slot that can carry a caster. Under-reporting would skip the lane and lose shadows; over-reporting only runs an empty compaction.

function tecs.gfx.Renderer.SpriteDomain.InstanceProducer.casting(
    self
): integer
Arguments
Name Type Description
self InstanceProducer
Returns
Type Description
integer

tecs.gfx.Renderer.SpriteDomain.InstanceProducer:count Instance

Instances to reserve. Changing it moves the layout, so a producer that can avoid changing it should.

function tecs.gfx.Renderer.SpriteDomain.InstanceProducer.count(
    self
): integer
Arguments
Name Type Description
self InstanceProducer
Returns
Type Description
integer

tecs.gfx.Renderer.SpriteDomain.InstanceProducer:takeDirty Instance

Sub-ranges written since the last sync, as flat one-based inclusive pairs, and cleared by returning them. Empty means nothing changed and the run is skipped.

function tecs.gfx.Renderer.SpriteDomain.InstanceProducer.takeDirty(
    self
): {integer}
Arguments
Name Type Description
self InstanceProducer
Returns
Type Description
{integer}

tecs.gfx.Renderer.SpriteDomain.InstanceProducer:write Instance

Writes instances first through last of its run. base is the instance index the run starts at, so instance first is written at base + first - 1.

function tecs.gfx.Renderer.SpriteDomain.InstanceProducer.write(
    self, loader.CArray, loader.CArray, integer, integer, integer
)
Arguments
Name Type Description
self InstanceProducer
#2 loader.CArray
#3 loader.CArray
#4 integer
#5 integer
#6 integer
Returns

None.

tecs.gfx.Renderer.SpriteDomain.ClipRegion record

A clip rectangle, in target pixels measured from the top left.

Screen space rather than world space, because that is what a fragment is tested in and what a scissor means: a panel occupies a part of the window whether its contents are placed by the camera, in screen pixels, or in virtual coordinates, and one rectangle is right for all three.

record tecs.gfx.Renderer.SpriteDomain.ClipRegion
    x: number
    y: number
    width: number
    height: number
end

tecs.gfx.Renderer.SpriteDomain.ClipRegion.x field

Caller-writable. Sets the left edge in target pixels.

tecs.gfx.Renderer.SpriteDomain.ClipRegion.y field

Caller-writable. Sets the top edge in target pixels.

tecs.gfx.Renderer.SpriteDomain.ClipRegion.width field

Caller-writable. Sets the width in target pixels.

tecs.gfx.Renderer.SpriteDomain.ClipRegion.height field

Caller-writable. Sets the height in target pixels.

tecs.gfx.Renderer.SpriteDomain.ComputeStage record

Something that writes instances with compute before the cull runs.

The pool a particle emitter draws from is the caller this exists for. Its contents outlive the frame, so it is not written through staging the way an archetype run is, and what it writes has to land before the mark pass reads the bounds beside it. A stage is recorded on the frame's command buffer between the staging flush and the cull, and SDL orders all three because each declares what it writes.

record tecs.gfx.Renderer.SpriteDomain.ComputeStage
    active: function(self): boolean
    destroy: function(self)
    record: function(self, Frame, Buffer, Buffer)
end

tecs.gfx.Renderer.SpriteDomain.ComputeStage:active Instance

Whether this stage has anything to record this frame.

Asked every frame rather than derived from a dirty bit, because the thing this exists for dirties nothing: an emitter's whole field moves every frame while the world holding it reports no change at all. There is no bit to read, so the stage has to publish the answer.

function tecs.gfx.Renderer.SpriteDomain.ComputeStage.active(
    self
): boolean
Arguments
Name Type Description
self ComputeStage
Returns
Type Description
boolean

tecs.gfx.Renderer.SpriteDomain.ComputeStage:destroy Instance

Releases what the stage owns, called when the backend is destroyed.

A stage's buffers and pipelines are built on the backend's device, so they cannot outlive it and nothing else is holding them: a world that installed a stage and then dropped its renderer would leak every one of them otherwise. Must be safe to call more than once.

function tecs.gfx.Renderer.SpriteDomain.ComputeStage.destroy(self)
Arguments
Name Type Description
self ComputeStage
Returns

None.

tecs.gfx.Renderer.SpriteDomain.ComputeStage:record Instance

Records its dispatches onto frame's command buffer.

The instance and bounds buffers are handed over rather than reached for, because writing them is the whole point of being here and a stage that had to find them would be a stage that could find something else.

function tecs.gfx.Renderer.SpriteDomain.ComputeStage.record(
    self, Frame, Buffer, Buffer
)
Arguments
Name Type Description
self ComputeStage
#2 Frame
#3 Buffer
#4 Buffer
Returns

None.

tecs.gfx.Renderer.SpriteDomain.camera field

Caller-writable. Controls the 2D view. The first drawable frame centers it on the viewport.

tecs.gfx.Renderer.SpriteDomain.capacity field

Read-only. Reports the instance capacity fixed at creation.

tecs.gfx.Renderer.SpriteDomain.capacity: integer

tecs.gfx.Renderer.SpriteDomain.count field

Read-only. Reports the instances resident after the last extraction.

tecs.gfx.Renderer.SpriteDomain.count: integer

tecs.gfx.Renderer.SpriteDomain.dropped field

Read-only. Reports the instances the last extraction could not fit.

tecs.gfx.Renderer.SpriteDomain.dropped: integer

tecs.gfx.Renderer.SpriteDomain.rewritten field

Read-only. Reports the instances rewritten by the last extraction.

tecs.gfx.Renderer.SpriteDomain.rewritten: integer

tecs.gfx.Renderer.SpriteDomain.images field

Read-only. Provides the sprite image array.

tecs.gfx.Renderer.SpriteDomain.images: TextureArray

tecs.gfx.Renderer.SpriteDomain.instances field

Engine-owned. Exposes sprite instances to custom compute stages. Ordinary game code should ignore it.

tecs.gfx.Renderer.SpriteDomain:addComputeStage Instance

Adds a compute stage between staging flush and sprite culling.

function tecs.gfx.Renderer.SpriteDomain.addComputeStage(
    self, stage: ComputeStage
)
Arguments
Name Type Description
self SpriteDomain
stage ComputeStage The caller supplies a stage retained and destroyed by the domain.
Returns

None.

tecs.gfx.Renderer.SpriteDomain:addProducer Instance

Adds a retained instance producer after archetype instances.

function tecs.gfx.Renderer.SpriteDomain.addProducer(
    self, producer: InstanceProducer
)
Arguments
Name Type Description
self SpriteDomain
producer InstanceProducer The caller supplies a producer destroyed with the domain.
Returns

None.

tecs.gfx.Renderer.SpriteDomain:clearClipRegion Instance

Stops one clip-region index from clipping.

function tecs.gfx.Renderer.SpriteDomain.clearClipRegion(
    self, index: integer
)
Arguments
Name Type Description
self SpriteDomain
index integer The caller supplies an integer from 1 through 255.
Returns

None.

tecs.gfx.Renderer.SpriteDomain:regionOf Instance

Returns the region occupied by a registered image.

function tecs.gfx.Renderer.SpriteDomain.regionOf(
    self, path: string
): TextureArray.Region
Arguments
Name Type Description
self SpriteDomain
path string The caller supplies the path used during registration.
Returns
Type Description
TextureArray.Region Returns the domain-owned live region, or nil when none matches.

tecs.gfx.Renderer.SpriteDomain:registerImage Instance

Uploads a decoded image and returns a sprite selecting the whole image.

The path identifies the image for this domain's lifetime. Re-registering it returns the existing region. The call releases valid decoded pixels.

function tecs.gfx.Renderer.SpriteDomain.registerImage(
    self, decoded: assets.Image
): components.Sprite, TextureArray.Region
Arguments
Name Type Description
self SpriteDomain
decoded assets.Image The caller supplies a ready image that still owns its pixels.
Returns
Type Description
components.Sprite Returns a fresh sprite that selects the whole image.
TextureArray.Region Returns the domain-owned live region that contains the image.

tecs.gfx.Renderer.SpriteDomain:replaceImage Instance

Uploads a decoded image over the one registered under its path.

The replacement keeps the registered layer and rectangle, so existing sprites keep their identity. Missing pixels, an unknown path, or a size change raises. The call releases valid decoded pixels.

function tecs.gfx.Renderer.SpriteDomain.replaceImage(
    self, decoded: assets.Image
): components.Sprite, TextureArray.Region
Arguments
Name Type Description
self SpriteDomain
decoded assets.Image The caller supplies an image matching a registered path and size.
Returns
Type Description
components.Sprite Returns a fresh sprite selecting the unchanged region.
TextureArray.Region Returns the domain-owned live region.

tecs.gfx.Renderer.SpriteDomain:reservesRuns Instance

Returns whether archetype runs have room to grow.

function tecs.gfx.Renderer.SpriteDomain.reservesRuns(self): boolean
Arguments
Name Type Description
self SpriteDomain
Returns
Type Description
boolean Returns the fixed creation setting.

tecs.gfx.Renderer.SpriteDomain:setClipRegion Instance

Assigns a clipping rectangle in target pixels.

function tecs.gfx.Renderer.SpriteDomain.setClipRegion(
    self, index: integer, region: ClipRegion
)
Arguments
Name Type Description
self SpriteDomain
index integer The caller supplies an integer from 1 through 255.
region ClipRegion The caller supplies the target-pixel rectangle.
Returns

None.

tecs.gfx.Renderer.SpriteDomain:sprite Instance

Returns a sprite for a registered image.

UVs are fractions of the image. Omitted values select the whole image. An unknown name raises.

function tecs.gfx.Renderer.SpriteDomain.sprite(
    self, name: string, u0: number, v0: number, u1: number, v1: number
): components.Sprite
Arguments
Name Type Description
self SpriteDomain
name string The caller supplies the registered image path.
u0 number The caller supplies the left fraction or omits it for zero.
v0 number The caller supplies the top fraction or omits it for zero.
u1 number The caller supplies the right fraction or omits it for one.
v1 number The caller supplies the bottom fraction or omits it for one.
Returns
Type Description
components.Sprite Returns a fresh sprite mapped into the image-array region.

tecs.gfx.Renderer.SpriteDomain:spriteSize Instance

Returns a sprite's natural size in source-image pixels.

function tecs.gfx.Renderer.SpriteDomain.spriteSize(
    self, sprite: components.Sprite
): number, number
Arguments
Name Type Description
self SpriteDomain
sprite components.Sprite The caller supplies a sprite registered on this domain.
Returns
Type Description
number Returns its width, or zero when the image is unresolved.
number Returns its height, or zero when the image is unresolved.

tecs.gfx.Renderer.SpriteOptions record

record tecs.gfx.Renderer.SpriteOptions
    capacity: integer
    cell: integer
    layers: integer
    reserveRuns: boolean
    partialRewrites: boolean
    packImages: boolean
end

tecs.gfx.Renderer.SpriteOptions.capacity field

Caller-writable. Sets the maximum resident sprite-instance count. Rows beyond this fixed ceiling are dropped instead of growing a buffer under a frame that may still read it.

tecs.gfx.Renderer.SpriteOptions.capacity: integer

tecs.gfx.Renderer.SpriteOptions.cell field

Caller-writable. Sets the image-array cell size in pixels.

tecs.gfx.Renderer.SpriteOptions.cell: integer

tecs.gfx.Renderer.SpriteOptions.layers field

Caller-writable. Sets the image-array layer count.

tecs.gfx.Renderer.SpriteOptions.layers: integer

tecs.gfx.Renderer.SpriteOptions.reserveRuns field

Caller-writable. Gives archetype runs room to grow without moving every later run. Defaults to false, which packs runs end to end.

tecs.gfx.Renderer.SpriteOptions.partialRewrites field

Caller-writable. Rewrites only structurally changed rows instead of a whole archetype run. Defaults to false.

tecs.gfx.Renderer.SpriteOptions.packImages field

Caller-writable. Packs many images into each array layer. Defaults to false, which gives each image its own layer.

tecs.gfx.Renderer.SpriteInstanceProducer record

Something that draws instances without owning entities.

Text is the reason this exists. A glyph is a textured quad like any other, but making each one an entity puts every glyph in the world into one archetype, so editing one string marks that column dirty and rewrites all of them; and spawning or despawning glyphs moves an archetype's length, which forces the whole scene to be laid out again. A producer sidesteps both: it is laid out as its own run, and it says which parts of that run changed.

It writes the same sixteen floats and four bounds floats every other instance carries, so culling, depth, layers and materials all apply to it without knowing it is not an entity.

record tecs.gfx.Renderer.SpriteInstanceProducer
    destroy: function(InstanceProducer) | nil

    blended: function(self): integer
    casting: function(self): integer
    count: function(self): integer
    takeDirty: function(self): {integer}
    write: function(
        self, loader.CArray, loader.CArray, integer, integer, integer
    )
end

tecs.gfx.Renderer.SpriteInstanceProducer.destroy field

Caller-writable. Releases work the producer owns. The renderer calls this at most once, before releasing the device resources its instances feed. The producer may omit it when it has nothing to release.

tecs.gfx.Renderer.SpriteInstanceProducer:blended Instance

Instances of its run that may reach the forward pass.

Asked every sync, because the forward lane is skipped entirely on a frame nothing said was blended and a producer whose run holds blended instances would then not be drawn. A producer that never blends answers zero and costs one call.

An upper bound rather than a count, and deliberately: a producer whose instances are written by compute cannot know how many of them a frame actually has. Over-reporting runs a lane that finds less than it was told to expect, which is the safe direction; under-reporting drops the whole lane, which is not.

function tecs.gfx.Renderer.SpriteInstanceProducer.blended(self): integer
Arguments
Name Type Description
self InstanceProducer
Returns
Type Description
integer

tecs.gfx.Renderer.SpriteInstanceProducer:casting Instance

Caller-writable. Reports instances of its run that may reach the shadow lane.

This has the same upper-bound contract as blended: a CPU producer answers exactly, while a compute producer may conservatively report every slot that can carry a caster. Under-reporting would skip the lane and lose shadows; over-reporting only runs an empty compaction.

function tecs.gfx.Renderer.SpriteInstanceProducer.casting(self): integer
Arguments
Name Type Description
self InstanceProducer
Returns
Type Description
integer

tecs.gfx.Renderer.SpriteInstanceProducer:count Instance

Instances to reserve. Changing it moves the layout, so a producer that can avoid changing it should.

function tecs.gfx.Renderer.SpriteInstanceProducer.count(self): integer
Arguments
Name Type Description
self InstanceProducer
Returns
Type Description
integer

tecs.gfx.Renderer.SpriteInstanceProducer:takeDirty Instance

Sub-ranges written since the last sync, as flat one-based inclusive pairs, and cleared by returning them. Empty means nothing changed and the run is skipped.

function tecs.gfx.Renderer.SpriteInstanceProducer.takeDirty(
    self
): {integer}
Arguments
Name Type Description
self InstanceProducer
Returns
Type Description
{integer}

tecs.gfx.Renderer.SpriteInstanceProducer:write Instance

Writes instances first through last of its run. base is the instance index the run starts at, so instance first is written at base + first - 1.

function tecs.gfx.Renderer.SpriteInstanceProducer.write(
    self, loader.CArray, loader.CArray, integer, integer, integer
)
Arguments
Name Type Description
self InstanceProducer
#2 loader.CArray
#3 loader.CArray
#4 integer
#5 integer
#6 integer
Returns

None.

tecs.gfx.Renderer.SpriteClipRegion record

A clip rectangle, in target pixels measured from the top left.

Screen space rather than world space, because that is what a fragment is tested in and what a scissor means: a panel occupies a part of the window whether its contents are placed by the camera, in screen pixels, or in virtual coordinates, and one rectangle is right for all three.

record tecs.gfx.Renderer.SpriteClipRegion
    x: number
    y: number
    width: number
    height: number
end

tecs.gfx.Renderer.SpriteClipRegion.x field

Caller-writable. Sets the left edge in target pixels.

tecs.gfx.Renderer.SpriteClipRegion.x: number

tecs.gfx.Renderer.SpriteClipRegion.y field

Caller-writable. Sets the top edge in target pixels.

tecs.gfx.Renderer.SpriteClipRegion.y: number

tecs.gfx.Renderer.SpriteClipRegion.width field

Caller-writable. Sets the width in target pixels.

tecs.gfx.Renderer.SpriteClipRegion.height field

Caller-writable. Sets the height in target pixels.

tecs.gfx.Renderer.SpriteComputeStage record

Something that writes instances with compute before the cull runs.

The pool a particle emitter draws from is the caller this exists for. Its contents outlive the frame, so it is not written through staging the way an archetype run is, and what it writes has to land before the mark pass reads the bounds beside it. A stage is recorded on the frame's command buffer between the staging flush and the cull, and SDL orders all three because each declares what it writes.

record tecs.gfx.Renderer.SpriteComputeStage
    active: function(self): boolean
    destroy: function(self)
    record: function(self, Frame, Buffer, Buffer)
end

tecs.gfx.Renderer.SpriteComputeStage:active Instance

Whether this stage has anything to record this frame.

Asked every frame rather than derived from a dirty bit, because the thing this exists for dirties nothing: an emitter's whole field moves every frame while the world holding it reports no change at all. There is no bit to read, so the stage has to publish the answer.

function tecs.gfx.Renderer.SpriteComputeStage.active(self): boolean
Arguments
Name Type Description
self ComputeStage
Returns
Type Description
boolean

tecs.gfx.Renderer.SpriteComputeStage:destroy Instance

Releases what the stage owns, called when the backend is destroyed.

A stage's buffers and pipelines are built on the backend's device, so they cannot outlive it and nothing else is holding them: a world that installed a stage and then dropped its renderer would leak every one of them otherwise. Must be safe to call more than once.

function tecs.gfx.Renderer.SpriteComputeStage.destroy(self)
Arguments
Name Type Description
self ComputeStage
Returns

None.

tecs.gfx.Renderer.SpriteComputeStage:record Instance

Records its dispatches onto frame's command buffer.

The instance and bounds buffers are handed over rather than reached for, because writing them is the whole point of being here and a stage that had to find them would be a stage that could find something else.

function tecs.gfx.Renderer.SpriteComputeStage.record(
    self, Frame, Buffer, Buffer
)
Arguments
Name Type Description
self ComputeStage
#2 Frame
#3 Buffer
#4 Buffer
Returns

None.

tecs.gfx.Renderer.MeshDomain record

record tecs.gfx.Renderer.MeshDomain
    record Options
        capacity: integer
        vertexCapacity: integer
        indexCapacity: integer
        materialCapacity: integer
        textureWidth: integer
        textureHeight: integer
        textureLayers: integer
        packTextures: boolean
        transparency: boolean
    end

    record MaterialOptions
        name: string
        model: integer
        alphaMode: integer
        baseColorTexture: integer
        normalTexture: integer
        metallicRoughnessTexture: integer
        occlusionTexture: integer
        emissiveTexture: integer
        alphaCutoff: number
        baseR: number
        baseG: number
        baseB: number
        baseA: number
        emissiveR: number
        emissiveG: number
        emissiveB: number
        metallic: number
        roughness: number
        normalScale: number
        occlusionStrength: number
    end

    record RegisteredPrimitive
        transform: ecs.Transform3D
        mesh: components.Mesh
        bounds: components.Bounds3D
        material: components.MeshMaterial
    end

    MATERIAL_METALLIC_ROUGHNESS: integer
    MATERIAL_UNLIT: integer
    ALPHA_OPAQUE: integer
    ALPHA_MASK: integer
    ALPHA_BLEND: integer
    camera: Camera3D
    capacity: integer
    vertexCapacity: integer
    indexCapacity: integer
    count: integer
    dropped: integer
    rewritten: integer
    meshCount: integer
    vertexCount: integer
    indexCount: integer
    materialCount: integer
    textureCount: integer
    transparency: boolean
    vertices: Buffer
    indices: Buffer
    instances: Buffer
    materials: Buffer

    material: function(self, name: string): components.MeshMaterial
    mesh: function(
        self, name: string
    ): components.Mesh, components.Bounds3D
    registerMaterial: function(
        self, options: MeshMaterialOptions
    ): components.MeshMaterial
    registerMesh: function(
        self, mesh: assets.Mesh
    ): components.Mesh, components.Bounds3D
    registerModel: function(
        self, model: assets.Model
    ): {RegisteredPrimitive}
    registerTexture: function(self, image: assets.Image): integer
end

tecs.gfx.Renderer.MeshDomain.Options record
record tecs.gfx.Renderer.MeshDomain.Options
    capacity: integer
    vertexCapacity: integer
    indexCapacity: integer
    materialCapacity: integer
    textureWidth: integer
    textureHeight: integer
    textureLayers: integer
    packTextures: boolean
    transparency: boolean
end

tecs.gfx.Renderer.MeshDomain.Options.capacity field

Caller-writable. Sets the maximum resident mesh-instance count and defaults to 65,536.

tecs.gfx.Renderer.MeshDomain.Options.vertexCapacity field

Caller-writable. Sets the immutable geometry ceiling in vertices and defaults to 1,048,576.

tecs.gfx.Renderer.MeshDomain.Options.indexCapacity field

Caller-writable. Sets the immutable geometry ceiling in 32-bit indices and defaults to 3,145,728.

tecs.gfx.Renderer.MeshDomain.Options.materialCapacity field

Caller-writable. Sets the material-table ceiling, including the built-in neutral slot, and defaults to 1,024.

tecs.gfx.Renderer.MeshDomain.Options.textureWidth field

Caller-writable. Sets the width of every mesh texture-array layer and defaults to 1,024 pixels.

tecs.gfx.Renderer.MeshDomain.Options.textureHeight field

Caller-writable. Sets the height of every mesh texture-array layer and defaults to 1,024 pixels.

tecs.gfx.Renderer.MeshDomain.Options.textureLayers field

Caller-writable. Sets the fixed mesh texture-array layer count and defaults to 16.

tecs.gfx.Renderer.MeshDomain.Options.packTextures field

Caller-writable. Packs multiple images into each texture layer and defaults to true.

tecs.gfx.Renderer.MeshDomain.Options.transparency field

Caller-writable. Enables the independently allocated transparent mesh lane and defaults to false.

tecs.gfx.Renderer.MeshDomain.MaterialOptions record
record tecs.gfx.Renderer.MeshDomain.MaterialOptions
    name: string
    model: integer
    alphaMode: integer
    baseColorTexture: integer
    normalTexture: integer
    metallicRoughnessTexture: integer
    occlusionTexture: integer
    emissiveTexture: integer
    alphaCutoff: number
    baseR: number
    baseG: number
    baseB: number
    baseA: number
    emissiveR: number
    emissiveG: number
    emissiveB: number
    metallic: number
    roughness: number
    normalScale: number
    occlusionStrength: number
end

tecs.gfx.Renderer.MeshDomain.MaterialOptions.name field

Caller-writable. Supplies the stable, non-empty material name used by snapshots and duplicate registration.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.model field

Caller-writable. Selects one of the domain's MATERIAL_* integer constants and defaults to MATERIAL_METALLIC_ROUGHNESS.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.alphaMode field

Caller-writable. Selects opaque, masked, or blended rendering with an ALPHA_* integer constant and defaults to ALPHA_OPAQUE.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.baseColorTexture field

Caller-writable. Selects a texture returned by registerTexture, or zero for the white fallback.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.normalTexture field

Caller-writable. Selects a tangent-space normal texture, or zero for a flat normal.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.metallicRoughnessTexture field

Caller-writable. Selects a glTF metallic-roughness texture, or zero.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.occlusionTexture field

Caller-writable. Selects an occlusion texture, or zero for no occlusion.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.emissiveTexture field

Caller-writable. Selects an emissive texture, or zero for black.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.alphaCutoff field

Caller-writable. Discards base alpha below this threshold and defaults to 0.5.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.baseR field

Caller-writable. Multiplies the base-color texture's red channel.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.baseG field

Caller-writable. Multiplies the base-color texture's green channel.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.baseB field

Caller-writable. Multiplies the base-color texture's blue channel.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.baseA field

Caller-writable. Multiplies the base-color texture's alpha channel.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.emissiveR field

Caller-writable. Multiplies emissive red.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.emissiveG field

Caller-writable. Multiplies emissive green.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.emissiveB field

Caller-writable. Multiplies emissive blue.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.metallic field

Caller-writable. Multiplies sampled metallic and defaults to 1.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.roughness field

Caller-writable. Multiplies sampled roughness and defaults to 1.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.normalScale field

Caller-writable. Scales tangent-space normal xy and defaults to 1.

tecs.gfx.Renderer.MeshDomain.MaterialOptions.occlusionStrength field

Caller-writable. Scales sampled occlusion and defaults to 1.

tecs.gfx.Renderer.MeshDomain.RegisteredPrimitive record

Contains the complete component bundle for one registered model primitive.

record tecs.gfx.Renderer.MeshDomain.RegisteredPrimitive
    transform: ecs.Transform3D
    mesh: components.Mesh
    bounds: components.Bounds3D
    material: components.MeshMaterial
end

tecs.gfx.Renderer.MeshDomain.RegisteredPrimitive.transform field

Caller-writable. Contains the static scene transform decoded from glTF.

tecs.gfx.Renderer.MeshDomain.RegisteredPrimitive.mesh field

Caller-writable. Selects the primitive's resident geometry.

tecs.gfx.Renderer.MeshDomain.RegisteredPrimitive.bounds field

Caller-writable. Supplies its local-space bounding sphere.

tecs.gfx.Renderer.MeshDomain.RegisteredPrimitive.material field

Caller-writable. Selects its resident PBR material.

tecs.gfx.Renderer.MeshDomain.MATERIALMETALLICROUGHNESS field

Read-only. Selects metallic-roughness PBR material dispatch.

tecs.gfx.Renderer.MeshDomain.MATERIAL_UNLIT field

Read-only. Selects unlit material dispatch.

tecs.gfx.Renderer.MeshDomain.ALPHA_OPAQUE field

Read-only. Selects an opaque material that ignores base alpha.

tecs.gfx.Renderer.MeshDomain.ALPHA_OPAQUE: integer

tecs.gfx.Renderer.MeshDomain.ALPHA_MASK field

Read-only. Selects an opaque material that discards below alphaCutoff.

tecs.gfx.Renderer.MeshDomain.ALPHA_MASK: integer

tecs.gfx.Renderer.MeshDomain.ALPHA_BLEND field

Read-only. Selects a material drawn in the sorted forward lane.

tecs.gfx.Renderer.MeshDomain.ALPHA_BLEND: integer

tecs.gfx.Renderer.MeshDomain.camera field

Caller-writable. Controls the perspective view used by this domain.

tecs.gfx.Renderer.MeshDomain.capacity field

Read-only. Reports the mesh-instance capacity fixed at creation.

tecs.gfx.Renderer.MeshDomain.capacity: integer

tecs.gfx.Renderer.MeshDomain.vertexCapacity field

Read-only. Reports the vertex capacity fixed at creation.

tecs.gfx.Renderer.MeshDomain.indexCapacity field

Read-only. Reports the 32-bit index capacity fixed at creation.

tecs.gfx.Renderer.MeshDomain.count field

Read-only. Reports the instances resident after the last extraction.

tecs.gfx.Renderer.MeshDomain.count: integer

tecs.gfx.Renderer.MeshDomain.dropped field

Read-only. Reports the instances the last extraction could not fit.

tecs.gfx.Renderer.MeshDomain.dropped: integer

tecs.gfx.Renderer.MeshDomain.rewritten field

Read-only. Reports the instances rewritten by the last extraction.

tecs.gfx.Renderer.MeshDomain.rewritten: integer

tecs.gfx.Renderer.MeshDomain.meshCount field

Read-only. Reports meshes registered for immutable residency.

tecs.gfx.Renderer.MeshDomain.meshCount: integer

tecs.gfx.Renderer.MeshDomain.vertexCount field

Read-only. Reports vertices registered for immutable residency.

tecs.gfx.Renderer.MeshDomain.vertexCount: integer

tecs.gfx.Renderer.MeshDomain.indexCount field

Read-only. Reports indices registered for immutable residency.

tecs.gfx.Renderer.MeshDomain.indexCount: integer

tecs.gfx.Renderer.MeshDomain.materialCount field

Read-only. Reports resident material slots, including the neutral built-in slot zero.

tecs.gfx.Renderer.MeshDomain.textureCount field

Read-only. Reports unique images uploaded to the mesh texture array.

tecs.gfx.Renderer.MeshDomain.textureCount: integer

tecs.gfx.Renderer.MeshDomain.transparency field

Read-only. Reports whether this domain owns the optional transparent command and pipeline resources.

tecs.gfx.Renderer.MeshDomain.transparency: boolean

tecs.gfx.Renderer.MeshDomain.vertices field

Engine-owned. Exposes immutable vertex storage to the opaque mesh pass. Ordinary game code should ignore it.

tecs.gfx.Renderer.MeshDomain.indices field

Engine-owned. Exposes immutable 32-bit index storage to the opaque mesh pass. Ordinary game code should ignore it.

tecs.gfx.Renderer.MeshDomain.instances field

Engine-owned. Exposes mesh instances to the opaque draw and GPU cull passes. Ordinary game code should ignore it.

tecs.gfx.Renderer.MeshDomain.materials field

Engine-owned. Exposes the resident material table to the mesh fragment stage. Ordinary game code should ignore it.

tecs.gfx.Renderer.MeshDomain:material Instance

Returns a component for material data already registered by name.

function tecs.gfx.Renderer.MeshDomain.material(
    self, name: string
): components.MeshMaterial
Arguments
Name Type Description
self MeshDomain
name string The caller supplies the stable registered name.
Returns
Type Description
components.MeshMaterial Returns a material component carrying the resident slot.

tecs.gfx.Renderer.MeshDomain:mesh Instance

Returns components for geometry already registered under a name.

function tecs.gfx.Renderer.MeshDomain.mesh(
    self, name: string
): components.Mesh, components.Bounds3D
Arguments
Name Type Description
self MeshDomain
name string The caller supplies the registered mesh name.
Returns
Type Description
components.Mesh Returns a mesh component carrying the resident slot.
components.Bounds3D Returns its asset-derived local bounding sphere.

tecs.gfx.Renderer.MeshDomain:registerMaterial Instance

Registers one immutable mesh material and returns its ECS reference.

Registering the same normalized name again returns the original slot. Texture fields are integer identities returned by registerTexture; zero selects the semantic fallback without consuming a texture layer.

function tecs.gfx.Renderer.MeshDomain.registerMaterial(
    self, options: MeshMaterialOptions
): components.MeshMaterial
Arguments
Name Type Description
self MeshDomain
options MeshMaterialOptions The caller supplies a stable name and optional PBR inputs.
Returns
Type Description
components.MeshMaterial Returns a material component ready to spawn.

tecs.gfx.Renderer.MeshDomain:registerMesh Instance

Registers immutable CPU geometry in this domain.

function tecs.gfx.Renderer.MeshDomain.registerMesh(
    self, mesh: assets.Mesh
): components.Mesh, components.Bounds3D
Arguments
Name Type Description
self MeshDomain
mesh assets.Mesh The caller supplies CPU geometry that this call consumes.
Returns
Type Description
components.Mesh Returns a mesh component ready to spawn.
components.Bounds3D Returns its asset-derived local bounding sphere.

tecs.gfx.Renderer.MeshDomain:registerModel Instance

Registers every image, material, and primitive in a decoded static model.

Registration consumes the model's CPU geometry and image holds. The returned records are caller-owned templates: spawn each record's transform, mesh, bounds, and material beside Tint and Renderable3D.

function tecs.gfx.Renderer.MeshDomain.registerModel(
    self, model: assets.Model
): {RegisteredPrimitive}
Arguments
Name Type Description
self MeshDomain
model assets.Model The caller supplies a ready assets.Model that this call consumes.
Returns
Type Description
{RegisteredPrimitive} Returns one registered record per primitive instance in the glTF scene selected by the file.

tecs.gfx.Renderer.MeshDomain:registerTexture Instance

Uploads one decoded image into mesh-domain texture residency.

Images share one linearly filtered array. Registration consumes the caller's image hold and returns a compact integer used by material options. Texture count is independent from triangle and instance counts.

function tecs.gfx.Renderer.MeshDomain.registerTexture(
    self, image: assets.Image
): integer
Arguments
Name Type Description
self MeshDomain
image assets.Image The caller supplies decoded pixels that this call consumes.
Returns
Type Description
integer Returns a positive texture identity local to this domain.

tecs.gfx.Renderer.MeshOptions record

record tecs.gfx.Renderer.MeshOptions
    capacity: integer
    vertexCapacity: integer
    indexCapacity: integer
    materialCapacity: integer
    textureWidth: integer
    textureHeight: integer
    textureLayers: integer
    packTextures: boolean
    transparency: boolean
end

tecs.gfx.Renderer.MeshOptions.capacity field

Caller-writable. Sets the maximum resident mesh-instance count and defaults to 65,536.

tecs.gfx.Renderer.MeshOptions.capacity: integer

tecs.gfx.Renderer.MeshOptions.vertexCapacity field

Caller-writable. Sets the immutable geometry ceiling in vertices and defaults to 1,048,576.

tecs.gfx.Renderer.MeshOptions.indexCapacity field

Caller-writable. Sets the immutable geometry ceiling in 32-bit indices and defaults to 3,145,728.

tecs.gfx.Renderer.MeshOptions.materialCapacity field

Caller-writable. Sets the material-table ceiling, including the built-in neutral slot, and defaults to 1,024.

tecs.gfx.Renderer.MeshOptions.textureWidth field

Caller-writable. Sets the width of every mesh texture-array layer and defaults to 1,024 pixels.

tecs.gfx.Renderer.MeshOptions.textureHeight field

Caller-writable. Sets the height of every mesh texture-array layer and defaults to 1,024 pixels.

tecs.gfx.Renderer.MeshOptions.textureLayers field

Caller-writable. Sets the fixed mesh texture-array layer count and defaults to 16.

tecs.gfx.Renderer.MeshOptions.packTextures field

Caller-writable. Packs multiple images into each texture layer and defaults to true.

tecs.gfx.Renderer.MeshOptions.transparency field

Caller-writable. Enables the independently allocated transparent mesh lane and defaults to false.

tecs.gfx.Renderer.sprites field

Read-only. Provides the concrete 2D rendering lane, or nil when creation disabled it.

tecs.gfx.Renderer.meshes field

Read-only. Provides the concrete 3D rendering lane, or nil when creation omitted mesh options.

tecs.gfx.Renderer.deferred field

Read-only. Provides the renderer-owned deferred graph and targets.

tecs.gfx.Renderer.deferred: Deferred

tecs.gfx.Renderer.newRenderer Static

Builds a renderer and its enabled rendering domains.

function tecs.gfx.Renderer.newRenderer(
    device: loader.CPtr,
    swapchainFormat: integer,
    options: RendererOptions
): Renderer
Arguments
Name Type Description
device loader.CPtr The engine supplies the GPU device that owns renderer resources.
swapchainFormat integer The engine supplies the presentation texture format.
options RendererOptions The caller supplies fixed creation options or nil for defaults.
Returns
Type Description
Renderer Returns a caller-owned renderer that destroy releases.

tecs.gfx.Renderer:captureTexture Instance

Returns the composited image from the last frame.

function tecs.gfx.Renderer.captureTexture(self): Texture
Arguments
Name Type Description
self Renderer
Returns
Type Description
Texture Returns the renderer-owned scene target.

tecs.gfx.Renderer:depthSortCollapse Instance

Returns the world units that collapse onto one depth value.

function tecs.gfx.Renderer.depthSortCollapse(self): number
Arguments
Name Type Description
self Renderer
Returns
Type Description
number Returns zero when the depth format preserves the full layer sort.

tecs.gfx.Renderer:destroy Instance

Releases the domains before the graph they record into.

function tecs.gfx.Renderer.destroy(self)
Arguments
Name Type Description
self Renderer
Returns

None.

tecs.gfx.Renderer:device Instance

Returns the GPU device shared by all domains.

function tecs.gfx.Renderer.device(self): loader.CPtr
Arguments
Name Type Description
self Renderer
Returns
Type Description
loader.CPtr Returns the engine-owned device.

tecs.gfx.Renderer:extractSeconds Instance

Returns the seconds consumed by the last domain extraction.

function tecs.gfx.Renderer.extractSeconds(self): number
Arguments
Name Type Description
self Renderer
Returns
Type Description
number Returns elapsed seconds, or zero while measurement is inactive.

tecs.gfx.Renderer:install Instance

Registers every rendering domain on a world.

function tecs.gfx.Renderer.install(self, world: types.World)
Arguments
Name Type Description
self Renderer
world types.World The caller supplies the world this renderer reads.
Returns

None.

tecs.gfx.Renderer:rebuildPipelines Instance

Rebuilds every domain pipeline from current shader sources.

function tecs.gfx.Renderer.rebuildPipelines(self)
Arguments
Name Type Description
self Renderer
Returns

None.

tecs.gfx.Renderer:render Instance

Prepares every domain and executes the renderer-owned frame graph.

function tecs.gfx.Renderer.render(self, frame: Frame)
Arguments
Name Type Description
self Renderer
frame Frame The engine supplies an open frame that it submits afterwards.
Returns

None.

tecs.gfx.Renderer:saveScreenshot Instance

Writes the composited image from the last frame as a PNG.

function tecs.gfx.Renderer.saveScreenshot(
    self, path: string
): boolean, string
Arguments
Name Type Description
self Renderer
path string The caller supplies the destination path.
Returns
Type Description
boolean Returns whether capture, encoding, and writing succeeded.
string Returns the failure reason when the first return is false.

tecs.gfx.Renderer:screenshot Instance

Encodes the composited image from the last frame as PNG bytes.

function tecs.gfx.Renderer.screenshot(self): string, string
Arguments
Name Type Description
self Renderer
Returns
Type Description
string Returns PNG bytes, or nil when readback or encoding fails.
string Returns the failure reason when the first return is nil.

tecs.gfx.Sprite record

Samples a texture instead of drawing flat color.

image is an index from imageId, which names the image; slot is the texture-array layer the renderer resolved that name to. Both are here because extraction reads the slot for every row it writes and wants a field, not a lookup, while a snapshot needs something a slot cannot give it. Snapshots store only the name.

A negative slot means unresolved. The renderer fills it in the first time it writes the row, so a Sprite restored from a snapshot or built by hand resolves once rather than once per frame. Pointing a live Sprite at another image therefore means writing a negative slot along with the new image, or the row keeps drawing the layer the old name resolved to.

The UV rect selects a region, so an atlas is the same thing as a whole image with the rect set to the full range. Read-only. Exposes the sprite component, which samples a texture instead of drawing flat color. image is an imageId index, and 0 means no image; u0, v0, u1, v1 select the region, defaulting to the whole of it, so an atlas entry and a whole image are the same thing. slot is the texture-array layer the renderer resolved image to, and a negative value means unresolved: pointing a live Sprite at another image means writing a negative slot along with the new image, or the row keeps drawing the old layer. Only the image name survives a snapshot.

record tecs.gfx.Sprite is Component
    image: number
    u0: number
    v0: number
    u1: number
    v1: number
    slot: number
end

Interfaces

Interface
Component

tecs.gfx.Sprite.image field

Caller-writable. Selects an image by its imageId index. Zero selects no image.

tecs.gfx.Sprite.image: number

tecs.gfx.Sprite.u0 field

Caller-writable. Sets the left edge of the sampled UV rectangle.

tecs.gfx.Sprite.u0: number

tecs.gfx.Sprite.v0 field

Caller-writable. Sets the top edge of the sampled UV rectangle.

tecs.gfx.Sprite.v0: number

tecs.gfx.Sprite.u1 field

Caller-writable. Sets the right edge of the sampled UV rectangle.

tecs.gfx.Sprite.u1: number

tecs.gfx.Sprite.v1 field

Caller-writable. Sets the bottom edge of the sampled UV rectangle.

tecs.gfx.Sprite.v1: number

tecs.gfx.Sprite.slot field

Engine-owned. Stores the resolved texture-array slot. Set it to a negative value when changing image; otherwise ordinary game code should ignore this field.

tecs.gfx.Sprite.slot: number

tecs.gfx.Text record

Lays a string out into glyph instances.

The entity's Transform2D places the top-left corner of the text block and orients and scales the whole block, and its Tint, if it has one, colors every glyph. Both are ordinary components on an ordinary entity, so a text moves, parents, tweens, and layers like anything else, and a Clip keeps its glyphs inside a rectangle exactly as it would any other quad.

Write through world:getMut(entity, Text). A write through world:get leaves the column clean and the glyphs stale. Read-only. Exposes the text component.

record tecs.gfx.Text is Component
    text: string
    font: Font
    size: number
    align: string
    wrapWidth: number
    width: number
    height: number
end

Interfaces

Interface
Component

tecs.gfx.Text.text field

Caller-writable. Sets the laid-out string. A newline starts a line and wrapWidth may introduce additional line breaks.

tecs.gfx.Text.text: string

tecs.gfx.Text.font field

Caller-writable. Selects the font that supplies the glyphs. Without one, the text draws nothing.

tecs.gfx.Text.font: Font

tecs.gfx.Text.size field

Caller-writable. Sets the em size in world units.

tecs.gfx.Text.size: number

tecs.gfx.Text.align field

Caller-writable. Selects "left", "center", or "right" alignment within the block's widest line.

tecs.gfx.Text.align: string

tecs.gfx.Text.wrapWidth field

Caller-writable. Sets the maximum line width in world units. Zero disables wrapping. Retained UI writes this field for a wrapping intrinsic text leaf after Taffy chooses its available width.

tecs.gfx.Text.wrapWidth: number

tecs.gfx.Text.width field

Engine-owned. Reports the width of the last layout in world units. Assigning it has no effect.

tecs.gfx.Text.width: number

tecs.gfx.Text.height field

Engine-owned. Reports the height of the last layout in world units. Assigning it has no effect.

tecs.gfx.Text.height: number

tecs.gfx.TextOptions record

Configures textPlugin.

record tecs.gfx.TextOptions
    renderer: Renderer
end

tecs.gfx.TextOptions.renderer field

Caller-writable. Selects the renderer that receives glyph images and instances.

tecs.gfx.Tint record

Controls base color and how much of the background remains visible.

Alpha selects the drawing pass. At one, the opaque entity enters the G-buffer and participates in deferred lighting. Below one, the forward pass draws it after compositing, blends straight alpha, and lights it.

A value rather than a component, because a fade is the thing this is for and a fade through a component would cause a structural change per entity per frame: adding and removing a tag moves a row between archetypes, which is the most expensive thing here. Alpha already changes as a float. One value also prevents conflicting transparency state.

What crossing one costs is what the forward pass cannot do. A blended entity writes no depth, so it hides nothing behind it and nothing reading the G-buffer can see it: it casts no shadow, and its material's emission reaches its own color and no pass that reads the emission attachment. The forward list is also shorter than the instance buffer, so a scene with more blended entities than it holds draws the ones earliest in the buffer and drops the rest. An entity meant to be solid should say so with an alpha of exactly one.

The opaque mesh domain reads rgb as its untextured base color. It ignores alpha until a mesh forward lane exists, so a mesh remains opaque at every alpha value. Read-only. Exposes the base-color component. Each channel ranges from 0 to 1 and defaults to opaque white. The alpha decides which pass draws the entity: exactly 1 goes through the G-buffer and is lit once for the whole scene, anything below 1 goes through the forward pass instead and writes no depth. When the forward list fills, the renderer drops later entries. Use exactly 1 for solid content.

record tecs.gfx.Tint is Component
    r: number
    g: number
    b: number
    a: number
end

Interfaces

Interface
Component

tecs.gfx.Tint.r field

Caller-writable. Sets the red channel from zero to one.

tecs.gfx.Tint.r: number

tecs.gfx.Tint.g field

Caller-writable. Sets the green channel from zero to one.

tecs.gfx.Tint.g: number

tecs.gfx.Tint.b field

Caller-writable. Sets the blue channel from zero to one.

tecs.gfx.Tint.b: number

tecs.gfx.Tint.a field

Caller-writable. Sets sprite coverage from transparent at zero to opaque at one. The opaque mesh lane currently ignores it.

tecs.gfx.Tint.a: number

tecs.gfx.TTFOptions record

Configures newTTF.

record tecs.gfx.TTFOptions
    source: string
    name: string
    size: number
    raster: FontRaster
end

tecs.gfx.TTFOptions.source field

Caller-writable. Sets a TrueType or OpenType path. Relative paths are resolved against the asset root.

tecs.gfx.TTFOptions.source: string

tecs.gfx.TTFOptions.name field

Caller-writable. Sets the snapshot identity. It defaults to source.

tecs.gfx.TTFOptions.name: string

tecs.gfx.TTFOptions.size field

Caller-writable. Sets the glyph raster point size. It defaults to 48.

tecs.gfx.TTFOptions.size: number

tecs.gfx.TTFOptions.raster field

Caller-writable. Selects "sdf" for scalable text or "alpha" for crisp text drawn at the loaded size. It defaults to "sdf".

Functions

tecs.gfx.glyphAt Static

Returns a glyph's world x, y, width, and height.

Reads the instance produced for rendering, so it reports the drawn placement.

function tecs.gfx.glyphAt(
    world: World, entity: integer, index: integer
): number, number, number, number

Arguments

Name Type Description
world World The world that contains the text entity.
entity integer An entity carrying Text.
index integer A one-based produced-glyph index. Layout operations with no drawable rectangle, including spaces and newlines, take no index.

Returns

Type Description
number World x of the glyph center, or nil when no glyph exists.
number World y of the glyph center, or nil with the first return.
number Glyph width in world units, or nil with the first return.
number Glyph height in world units, or nil with the first return.

tecs.gfx.imageId Static

Returns the index of an image name and assigns one on first use.

The function normalizes names lexically, so "a/b.png" and "a/./b.png" identify one image. It preserves case and .. and does not touch the filesystem.

function tecs.gfx.imageId(name: string): integer

Arguments

Name Type Description
name string Must be non-empty; an empty or nil name errors rather than interning.

Returns

Type Description
integer An index from 1 upwards, stable for the life of the process and meaningless outside it. 0 is never returned and is what a Sprite carries until something names an image.

tecs.gfx.imageName Static

Returns the name represented by an image index.

function tecs.gfx.imageName(id: integer): string

Arguments

Name Type Description
id integer An index previously handed out by imageId.

Returns

Type Description
string The normalized name, or nil when the index names nothing.

tecs.gfx.measureIntrinsic Static

Returns the preferred and minimum-content metrics for a text item.

The minimum-content width is the widest whitespace-delimited run. The function shapes only while called and does not change authored fields. Retained UI calls it only when the text or its intrinsic settings are dirty.

function tecs.gfx.measureIntrinsic(item: Text): number, number, number

Arguments

Name Type Description
item Text A Text value with a font.

Returns

Type Description
number Preferred width with wrapping disabled.
number Preferred height with wrapping disabled.
number Minimum-content width of the widest unbroken run.

tecs.gfx.measureText Static

Returns a text item's width and height in world units.

Uses the same layout as the plugin without adding or changing an entity.

function tecs.gfx.measureText(
    item: Text, wrapWidth: number
): number, number

Arguments

Name Type Description
item Text A Text value to read. It need not belong to an entity.
wrapWidth number The caller may override item.wrapWidth for this measurement without changing the retained authored value.

Returns

Type Description
number Width at item.size, before Transform2D scale. Returns zero for a missing item, font, or string.
number Height on the same terms, counting complete line boxes.

tecs.gfx.meshId Static

Returns the process-local index of a normalized mesh asset name.

function tecs.gfx.meshId(name: string): integer

Arguments

Name Type Description
name string A non-empty mesh asset name or path.

Returns

Type Description
integer A positive index stable for the life of the process.

tecs.gfx.meshMaterialId Static

Returns the process-local identity of a mesh material name.

function tecs.gfx.meshMaterialId(name: string): integer

Arguments

Name Type Description
name string A non-empty stable material name.

Returns

Type Description
integer A positive index stable for the life of the process.

tecs.gfx.meshMaterialName Static

Returns the name represented by a mesh material index.

function tecs.gfx.meshMaterialName(id: integer): string

Arguments

Name Type Description
id integer An index previously returned by meshMaterialId.

Returns

Type Description
string The normalized name, or nil when the index names nothing.

tecs.gfx.meshName Static

Returns the normalized asset name represented by a mesh index.

function tecs.gfx.meshName(id: integer): string

Arguments

Name Type Description
id integer An index previously returned by meshId.

Returns

Type Description
string The normalized name, or nil when the index names nothing.

tecs.gfx.textLayouts Static

Returns how many texts the world has laid out.

function tecs.gfx.textLayouts(world: World): integer

Arguments

Name Type Description
world World A world with or without the text plugin.

Returns

Type Description
integer A count that only increases, or zero before plugin installation. The count measures rows laid out rather than frames.

tecs.gfx.textPlugin Static

Creates the plugin that lays out text for a renderer.

function tecs.gfx.textPlugin(options: TextOptions): function(World)

Arguments

Name Type Description
options TextOptions Requires renderer.

Returns

Type Description
function(World) A world plugin. Each world gets its own producer run while sharing process-wide fonts.