# `CauldronGPU.Stream`
[🔗](https://github.com/jaman/cauldron/blob/v0.3.3/cauldron_gpu/lib/cauldron_gpu/stream.ex#L1)

The binary change stream the renderer reads: a sequence of operations, each a one-byte
code and its fields, little-endian. `encode/1` turns changes into it.

A change is one of:

  * `:tick` — the changes that follow belong to a new game tick; poses are
    interpolated from the previous tick's
  * `{:mesh, id, %CauldronGPU.Mesh{}}`, `{:drop_mesh, id}`
  * `{:texture, id, %CauldronGPU.Texture{}}`, `{:drop_texture, id}`
  * `{:canvas, id, %CauldronGPU.Canvas{}}` — a texture the renderer draws into, dropped
    as a texture is
  * `{:material, id, %CauldronGPU.Material{}}`, `{:drop_material, id}`
  * `{:instance, id, %CauldronGPU.Instance{}}`
  * `{:move, id, %CauldronGPU.Transform{}}` or `{:move, id, transform, snap: true}`
  * `{:pose, id, %CauldronGPU.Pose{}}` — bends instance `id`'s mesh until the next pose
  * `{:remove_instance, id}`
  * `{:light, id, %CauldronGPU.Light{}}`, `{:remove_light, id}`
  * `%CauldronGPU.Camera{}`
  * `%CauldronGPU.Environment{}`
  * `{:light_styles, [scale | {r, g, b}]}` — the brightness of light styles 0, 1, …, a
    number for all three colours or one each (1.0 normal, up to 64 styles; styles not
    listed stay as they were, 1.0 at first)
  * `{:overlay, texture_handle | nil}` — a picture drawn over the finished frame, stretched
    to it, see-through by its alpha (a HUD, menus); `nil` removes it.
    `{:overlay, texture_handle, :premultiplied}` takes its colours as already multiplied by
    its alpha, so a pixel with colour and no alpha adds its colour (an additive HUD)
  * `{:screen_tint, {r, g, b, a}}` — the finished frame's display colours blended towards
    the display colour `{r, g, b}` by `a`; the overlay is blended over display colours too
  * `{:layers, [layer]}` — the 2D layers drawn each frame, in order, until the next
    `:layers` change; a layer is a `CauldronGPU.SpriteLayer` or a
    `CauldronGPU.ColumnLayer`, and `{:layers, []}` removes them
  * `{:effects, [effect]}` with effects `:ray_traced_shadows`, `:ray_traced_reflections`,
    `:ray_traced_global_illumination`, `:ray_traced_ambient_occlusion`, `:upscaling`,
    `:frame_generation`; a renderer that cannot provide one ignores it

Ids are integers from 1 to 2³²−1. Positions and directions follow
`CauldronGPU.Transform`'s frame.

# `change`

```elixir
@type change() ::
  :tick
  | {:mesh, id(), CauldronGPU.Mesh.t()}
  | {:drop_mesh, id()}
  | {:texture, id(), CauldronGPU.Texture.t()}
  | {:drop_texture, id()}
  | {:canvas, id(), CauldronGPU.Canvas.t()}
  | {:layers, [CauldronGPU.SpriteLayer.t() | CauldronGPU.ColumnLayer.t()]}
  | {:material, id(), CauldronGPU.Material.t()}
  | {:drop_material, id()}
  | {:instance, id(), CauldronGPU.Instance.t()}
  | {:move, id(), CauldronGPU.Transform.t()}
  | {:move, id(), CauldronGPU.Transform.t(), keyword()}
  | {:pose, id(), CauldronGPU.Pose.t()}
  | {:remove_instance, id()}
  | {:light, id(), CauldronGPU.Light.t()}
  | {:remove_light, id()}
  | CauldronGPU.Camera.t()
  | CauldronGPU.Environment.t()
  | {:light_styles, [number() | {number(), number(), number()}]}
  | {:overlay, CauldronGPU.Handle.t() | nil}
  | {:overlay, CauldronGPU.Handle.t(), :premultiplied}
  | {:screen_tint, {number(), number(), number(), number()}}
  | {:effects, [atom()]}
```

# `id`

```elixir
@type id() :: pos_integer()
```

# `drop_op`

```elixir
@spec drop_op(CauldronGPU.Handle.kind()) :: non_neg_integer()
```

The operation code that drops an object of `kind`.

# `encode`

```elixir
@spec encode([change()]) :: iodata()
```

The stream for `changes`, as iodata.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
