Rendering in Mibo
Mibo’s rendering story is intentionally simple:
- Your Elmish
updatestays pure. - Your
viewfunction submits render commands to aRenderBuffer. - A renderer (
IRenderer<'Model>) executes those commands each frame.
This keeps drawing as data submission, which composes nicely as projects grow.
Renderers are just IRenderer<'Model>
A renderer is anything that implements:
type IRenderer<'Model> =
abstract member Draw: GameContext * 'Model * GameTime -> unit
You add renderers with:
Program.withRenderer (fun game -> myRenderer :> IRenderer<Model>)
Multiple renderers can be added (e.g. 3D world + 2D UI). They run in the order they were added.
The RenderBuffer pattern
Instead of drawing immediately inside update, you typically:
- allocate a buffer (owned by the renderer)
- clear it each frame
- call your
viewto fill it - optionally sort it
- execute the commands
The built-in renderers follow this pattern, and custom renderers can too.
Writing your own renderer
If you have a custom draw pipeline (special post-processing, instancing, debug overlays, etc), implement IRenderer<'Model>.
Minimal example:
type MyRenderer(game: Game) =
interface IRenderer<Model> with
member _.Draw(ctx, model, gameTime) =
// use ctx.GraphicsDevice, ctx.Content, etc
// draw based on model
()
Then install it:
Program.mkProgram init update
|> Program.withRenderer (fun game -> MyRenderer(game) :> IRenderer<Model>)
Built-in renderers
Mibo includes:
- 2D SpriteBatch renderer:
Mibo.Elmish.Graphics2D.Batch2DRenderer - 3D renderer with pass handling and primitive batching:
Mibo.Elmish.Graphics3D.Batch3DRenderer
See the dedicated pages:
type IRenderer<'Model> =
abstract Draw: 'b * 'Model * 'c -> unit
'Model
type unit = Unit
Multiple items
type MyRenderer = interface obj new: game: obj -> MyRenderer override Draw: ctx: 'a * model: 'b * gameTime: 'c -> unit
--------------------
new: game: obj -> MyRenderer
type MyRenderer = interface obj new: game: obj -> MyRenderer override Draw: ctx: 'a * model: 'b * gameTime: 'c -> unit
--------------------
new: game: obj -> MyRenderer
val game: obj
val ctx: 'a
val model: 'b
val gameTime: 'c
Mibo