render
This package implements a batched 2D rendering pipeline. It serves as the primary interface for drawing sprites, text and geometric primitives, automatically handling coordinate space transformations and draw call batching.
Features:
- Automated asset pipeline: Utilizes a build-time generated texture atlas and
auto-generated sprite and font enums (
SpriteNameandFontNameinbonsai:generatedpackage) for type-safe, optimized asset access. - Batched rendering: Automatically batches draw calls (up to
MAX_QUADS) to minimize GPU overhead, with manual control viaflushBatch. - Coordinate systems: Easy switching between world space (gameplay) and screen space (UI) using
helper functions:
setWorldSpaceandsetScreenSpace. - Text drawing: Integrated TTF font support with utilities like
drawTextWithDropShadowanddrawTextSimple. - Scissoring: Built-in support for clipping regions via
ScissorState.
ATLAS_PATH
Section titled “ATLAS_PATH”ATLAS_PATH :: "bonsai/core/render/atlas/atlas.png"Path relative to project root pointing to the generated sprite atlas.
Atlas :: struct { view: sokol_gfx.View, image: sokol_gfx.Image,}Represents the global sprite atlas.
BINDING_GLOBAL_UNIFORMS
Section titled “BINDING_GLOBAL_UNIFORMS”BINDING_GLOBAL_UNIFORMS :: 0Constants prefixed with BINDING define the binding index used for uniform data. By default 0 is occupied by
ShaderGlobals and 1 is left for custom shader uniform data.
CLEAR_COLOR
Section titled “CLEAR_COLOR”CLEAR_COLOR :: colors.BLACKDefault clear color (background).
Canvas
Section titled “Canvas”Canvas :: struct { image: sokol_gfx.Image, depthImage: sokol_gfx.Image, readerView: sokol_gfx.View, attachments: sokol_gfx.Attachments, sampler: sokol_gfx.Sampler, id: CanvasId, size: gmath.Vector2,}Wraps all data needed for each Canvas object. Each has unique CanvasId.
Shouldn’t be modified directly.
CanvasId
Section titled “CanvasId”CanvasId :: distinct i32A handle used to identify a loaded Canvas
CoordSpace
Section titled “CoordSpace”CoordSpace :: struct { projectionMatrix: gmath.Matrix4, cameraMatrix: gmath.Matrix4, // Model matrix of the camera viewProjectionMatrix: gmath.Matrix4, // Projection * Inverse(Camera) (view matrix)}Defines the matrices used for coordinate transformation in a render pass.
DEFAULT_UV
Section titled “DEFAULT_UV”DEFAULT_UV :: gmath.Vector4 {0, 0, 1, 1}Default UV coordinates covering the full texture (0,0 to 1,1).
DrawFrame
Section titled “DrawFrame”DrawFrame :: struct { reset: struct { // Dynamic arrays of quads bucketed by DrawLayer quads: [DrawLayer][dynamic]Quad,
// The active coordinate space (camera, projection) coordSpace: CoordSpace,
// Current layer being drawn to activeDrawLayer: DrawLayer,
// Current scissor/clipping rectangle activeScissor: gmath.Rectangle,
// Global flags applied to all subsequent quads in the batch activeFlags: QuadFlags,
// Shader uniform data shaderData: ShaderGlobals,
// Tracks which layers need Y-sorting sortedLayers: bit_set[DrawLayer], },}A container for all data required to render a single frame.
DrawLayer
Section titled “DrawLayer”DrawLayer :: enum u8 { nil, background, shadow, playspace, vfx, ui, tooltip, pauseMenu, top,}Defines the rendering order (Z-sorting).
Font :: struct { texture: sokol_gfx.Image, view: sokol_gfx.View, characterData: [96]stb_truetype.bakedchar, name: string,}Represents a loaded and baked font ready for rendering.
LOCATION_POSITION
Section titled “LOCATION_POSITION”LOCATION_POSITION :: 0Constants prefixed with LOCATION define the memory layout relation between the CPU Vertex struct
and the GPU shader attributes (layout(location = X)).
MAX_QUADS
Section titled “MAX_QUADS”MAX_QUADS :: 8192Maximum number of quads per batch flush.
Quad :: [4]VertexA visual quad composed of 4 vertices.
QuadFlags
Section titled “QuadFlags”QuadFlags :: enum u8 { flag1 = (1 << 0), flag2 = (1 << 1),}Bit flags for special rendering behaviors in the shader.
RenderContext
Section titled “RenderContext”RenderContext :: struct { passAction: sokol_gfx.Pass_Action, inPass: bool, bindings: sokol_gfx.Bindings, shaders: [dynamic]Shader, defaultShaderId: ShaderId, activeShaderId: ShaderId, customUniformsData: [1024]byte, customUniformsSize: uint, canvases: [dynamic]Canvas, defaultCanvasId: CanvasId, activeCanvasId: CanvasId, defaultCanvasSampler: sokol_gfx.Sampler,}Internal context holding the global Sokol GFX state.
Manages active bindings (atlas/font) and stores the list of loaded Shaders
ScissorState
Section titled “ScissorState”ScissorState :: struct { enabled: bool, coordinates: gmath.Vector4,}Tracks the state of the scissor test (clipping).
Shader
Section titled “Shader”Shader :: struct { pipeline: sokol_gfx.Pipeline, id: ShaderId,}Wraps a compiled Sokol pipeline and its ID.
ShaderDescriptionFunction
Section titled “ShaderDescriptionFunction”ShaderDescriptionFunction :: proc (backend: sokol_gfx.Backend) -> sokol_gfx.Shader_Desc //Function signature for the auto-generated shader descriptors created by sokol-shdc.
ShaderGlobals
Section titled “ShaderGlobals”ShaderGlobals :: struct #align (16) { uViewProjectionMatrix: gmath.Matrix4,}Uniform block data uploaded to the GPU for the global shader state.
ShaderId
Section titled “ShaderId”ShaderId :: distinct i32A handle used to identify a loaded Shader
Vertex
Section titled “Vertex”Vertex :: struct #packed { position: gmath.Vector3, color: gmath.Vector4, uv: gmath.Vector2, localUv: gmath.Vector2, size: gmath.Vector2, textureIndex: u8, drawLayer: u8, quadFlags: QuadFlags, // u8 _: [1]u8, // Padding to align next Vector4 to 4 byte boundary colorOverride: gmath.Vector4, parameters: gmath.Vector4,}Represents a single vertex in the sprite batcher.
clearScissor
Section titled “clearScissor”clearScissor :: proc ()Disables the scissor test.
destroyCanvas
Section titled “destroyCanvas”destroyCanvas :: proc (id: CanvasId)Destroys the GPU resources associated with the Canvas.
drawCanvas
Section titled “drawCanvas”drawCanvas :: proc ( id: CanvasId, position: gmath.Vector2 = {0, 0}, rotation: f32 = 0.0, pivot: gmath.Pivot = .bottomLeft, scale: gmath.Vector2 = {1, 1}, size: Maybe(gmath.Vector2) = nil, transform := gmath.Matrix4(1), color := colors.WHITE, drawLayer := DrawLayer.nil, sortKey: f32 = 0.0,)Draws the contents of a Canvas onto the screen (or current target) at the given position.
This triggers an immediate batch flush because it requires switching textures.
drawCircle
Section titled “drawCircle”drawCircle :: proc ( center: gmath.Vector2, radius: f32, color: gmath.Color, segments: uint = 32, drawLayer := DrawLayer.nil, sortKey: f32 = 0.0,)Draws a filled circle.
drawCircleLines
Section titled “drawCircleLines”drawCircleLines :: proc ( center: gmath.Vector2, radius: f32, color: gmath.Color, segments: uint = 32, thickness: f32 = 1.0, drawLayer := DrawLayer.nil, sortKey: f32 = 0.0,)Draws the outline of a circle using line segments.
Internally it just calls the drawRegularPolygonLines
function with a high default count of segments.
drawLine
Section titled “drawLine”drawLine :: proc ( start: gmath.Vector2, end: gmath.Vector2, color: gmath.Color, thickness: f32 = 1.0, drawLayer := DrawLayer.nil, sortKey: f32 = 0.0,)Draws a line between start and end with a specified thickness.
drawPolygon
Section titled “drawPolygon”drawPolygon :: proc ( points: []gmath.Vector2, color: gmath.Color, drawLayer := DrawLayer.nil, sortKey: f32 = 0.0,)Draws a filled generic polygon. Expects points to be listed in a counter-clockwise order.
drawPolygonLines
Section titled “drawPolygonLines”drawPolygonLines :: proc ( points: []gmath.Vector2, color: gmath.Color, thickness: f32 = 1.0, drawLayer := DrawLayer.nil, sortKey: f32 = 0.0,)Draws the outline of a polygon. Expects points to be listed in a counter-clockwise order.
drawQuadProjected
Section titled “drawQuadProjected”drawQuadProjected :: proc ( positions: [4]gmath.Vector2, colors: [4]gmath.Color, uvs: [4]gmath.Vector2, textureIndex: u8, quadSize: gmath.Vector2, colorOverride: gmath.Color, drawLayer: DrawLayer = DrawLayer.nil, flags: QuadFlags, parameters := gmath.Vector4{}, sortKey: f32 = 0.0,)Core function for pushing a quad into the draw list.
drawRectangle
Section titled “drawRectangle”drawRectangle :: proc ( rectangle: gmath.Rectangle, rotation: f32 = 0.0, // in radians sprite := generated.SpriteName.nil, uv := DEFAULT_UV, color := colors.WHITE, colorOverride := gmath.Color{}, drawLayer := DrawLayer.nil, flags := QuadFlags{}, parameters := gmath.Vector4{}, cropTop: f32 = 0.0, cropLeft: f32 = 0.0, cropBottom: f32 = 0.0, cropRight: f32 = 0.0, sortKey: f32 = 0.0, isCullingEnabled := false,)Draws a simple Rectangle.
drawRectangleLines
Section titled “drawRectangleLines”drawRectangleLines :: proc ( rectangle: gmath.Rectangle, color: gmath.Color, thickness: f32 = 1.0, rotation: f32 = 0.0, // in radians drawLayer := DrawLayer.nil, sortKey: f32 = 0.0, isCullingEnabled := false,)Draws the outline of a Rectangle.
The border grows outwards from the rectangle edges.
drawRectangleTransform
Section titled “drawRectangleTransform”drawRectangleTransform :: proc ( transform: gmath.Matrix4, size: gmath.Vector2, sprite := generated.SpriteName.nil, uv := DEFAULT_UV, textureIndex: u8 = 0, animationIndex := 0, color := colors.WHITE, colorOverride := gmath.Color{}, drawLayer := DrawLayer.nil, flags := QuadFlags{}, parameters := gmath.Vector4{}, cropTop: f32 = 0.0, cropLeft: f32 = 0.0, cropBottom: f32 = 0.0, cropRight: f32 = 0.0, sortKey: f32 = 0.0,)Low-level function that pushes the final quad vertex data to the batcher.
drawRegularPolygon
Section titled “drawRegularPolygon”drawRegularPolygon :: proc ( center: gmath.Vector2, radius: f32, sides: uint, color: gmath.Color, rotation: f32 = 0.0, drawLayer := DrawLayer.nil, sortKey: f32 = 0.0,)Draws a filled regular N-gon.
drawRegularPolygonLines
Section titled “drawRegularPolygonLines”drawRegularPolygonLines :: proc ( center: gmath.Vector2, radius: f32, sides: uint, color: gmath.Color, thickness: f32 = 1.0, rotation: f32 = 0.0, drawLayer := DrawLayer.nil, sortKey: f32 = 0.0,)Draws the outline of a regular N-gon.
drawSprite
Section titled “drawSprite”drawSprite :: proc { _drawSpriteVector3Rotation, _drawSpriteF32Rotation,}Main function for drawing game entities.
Supports rotation, animations, pivoting and camera culling.
Accepts either a f32 or a Vector3
as the rotation. If a f32 is provided, the sprite is rotated on the Z axis.
drawSpriteInRectangle
Section titled “drawSpriteInRectangle”drawSpriteInRectangle :: proc ( sprite: generated.SpriteName, position: gmath.Vector2, size: gmath.Vector2, transform := gmath.Matrix4(1), color := colors.WHITE, colorOverride := gmath.Color{}, drawLayer := DrawLayer.nil, flags := QuadFlags(0), paddingPercent: f32 = 0.1,)Helper to draw a sprite scaled to fit inside a target rectangle. Maintains aspect ratio (letterboxing).
drawText
Section titled “drawText”drawText :: drawTextWithDropShadowDefault text drawing alias (includes drop shadow).
drawTextSimple
Section titled “drawTextSimple”drawTextSimple :: proc { _drawTextSimpleVector3Angle, _drawTextSimpleF32Angle,}Draws text without a drop shadow.
Retrieves the font using the automatically generated FontName enum.
Accepts either a f32 or a Vector3
as the rotation. If a f32 is provided, the text is rotated on the Z axis.
drawTextSimpleFont
Section titled “drawTextSimpleFont”drawTextSimpleFont :: proc { _drawTextSimpleFontVector3Angle, _drawTextSimpleFontF32Angle,}Internal primitive for drawing a single line of text.
Calculates layout, pivots, and batches the quads.
Accepts either a f32 or a Vector3
as the rotation. If a f32 is provided, the text is rotated on the Z axis.
drawTextWithDropShadow
Section titled “drawTextWithDropShadow”drawTextWithDropShadow :: proc { _drawTextWithDropShadowVector3Angle, _drawTextWithDropShadowF32Angle,}Draws text with a hard-coded drop shadow for contrast**.
Retrieves the font using the automatically generated FontName enum.
Accepts either a f32 or a Vector3
as the rotation. If a f32 is provided, the text is rotated on the Z axis.
drawTriangle
Section titled “drawTriangle”drawTriangle :: proc ( point1, point2, point3: gmath.Vector2, color: gmath.Color, drawLayer := DrawLayer.nil, sortKey: f32 = 0.0,)Draws a filled triangle. Expects points to be listed in a counter-clockwise order.
drawTriangleLines
Section titled “drawTriangleLines”drawTriangleLines :: proc ( point1, point2, point3: gmath.Vector2, color: gmath.Color, thickness: f32 = 1.0, drawLayer := DrawLayer.nil, sortKey: f32 = 0.0,)Draws a triangle outline. Expects points to be listed in a counter-clockwise order.
flushBatch
Section titled “flushBatch”flushBatch :: proc ()Flushes all queued quads to the GPU.
Sorts layers if necessary. Warns when MAX_QUADS is exceeded.
getAtlasUv
Section titled “getAtlasUv”getAtlasUv :: proc (sprite: generated.SpriteName) -> gmath.Vector4Helper to retrieve texture info from SpriteName.
getCanvasSpace
Section titled “getCanvasSpace”getCanvasSpace :: proc (width, height: f32) -> CoordSpaceCalculates the coordinate space for a custom Canvas.
Called internally by setCanvas.
getDrawFrame
Section titled “getDrawFrame”getDrawFrame :: proc () -> ^DrawFrameReturns a pointer to the current frame’s draw data.
getFont
Section titled “getFont”getFont :: proc (fontName: generated.FontName, size: uint) -> (Font, bool)Retrieves or loads a font for a specific size. Caches the result to avoid re-baking the bitmap every frame.
getRenderContext
Section titled “getRenderContext”getRenderContext :: proc () -> ^RenderContextReturns a pointer to the RenderContext struct.
getScreenSpace
Section titled “getScreenSpace”getScreenSpace :: proc () -> CoordSpaceCalculates the coordinate space for UI/Screen elements.
getScreenSpaceProjectionMatrix
Section titled “getScreenSpaceProjectionMatrix”getScreenSpaceProjectionMatrix :: proc () -> gmath.Matrix4Generates the projection matrix for the UI.
Handles aspect ratio scaling to ensure the UI fits within the design resolution (GAME_WIDTH/GAME_HEIGHT).
getSpriteSize
Section titled “getSpriteSize”getSpriteSize :: proc (sprite: generated.SpriteName) -> gmath.Vector2Helper to retrieve size from SpriteName.
getTextSize
Section titled “getTextSize”getTextSize :: proc (fontName: generated.FontName, fontSize: uint, text: string) -> gmath.Vector2Calculates the total dimension (width, height) of a string if it were rendered.
getViewportPivot
Section titled “getViewportPivot”getViewportPivot :: proc (pivot: gmath.Pivot) -> gmath.Vector2Helper to get specific screen/viewport coordinates based on a Pivot (anchoring).
Returns a Vector2 position.
getViewportRectangle
Section titled “getViewportRectangle”getViewportRectangle :: proc () -> gmath.RectangleHelper that calculates and creates a Rectangle containing the
current viewport in Screen Space. Uses ScaleMode internally in its calculations.
getWorldSpace
Section titled “getWorldSpace”getWorldSpace :: proc () -> CoordSpaceCalculates the coordinate space for the main gameplay world. Creates a View-Projection matrix based on the camera’s position and zoom.
loadShader
Section titled “loadShader”loadShader :: proc (descriptionFunction: ShaderDescriptionFunction) -> ShaderIdCreates a new ShaderId from a sokol-shdc generated description function.
This function enforces the framework’s standard vertex layout to ensure compatibility with batching.
resetDrawFrame
Section titled “resetDrawFrame”resetDrawFrame :: proc ()Resets the DrawFrame (clears quads, resets camera) and sets the shader to default.
setCanvas
Section titled “setCanvas”setCanvas :: proc ( id: CanvasId = _renderContext.defaultCanvasId, clear: bool = true, clearColor: Maybe(gmath.Color) = nil,)Sets the current Canvas (render target).
Defaults to screen space canvas.
Arguments:
CanvasId: Handle linked to the targetedCanvas. Returned by theloadCanvasfunction.- ‘clear’: if
true- clears contents of the canvas, iffalse- preserves previously drawn content. clearColor: Clear (background) color, takes effect only ifclearistrue.
setClearColor
Section titled “setClearColor”setClearColor :: proc (col: gmath.Vector4)Sets the background clear color.
setCoordSpace
Section titled “setCoordSpace”setCoordSpace :: proc { _setCoordSpaceValue, _setCoordSpaceDefault,}Sets the coordinate space (projection/camera matrices).
Arguments:
CoordSpacestruct: Sets thedrawFrame.reset.coordSpaceto givenCoordSpace.nil: Sets thedrawFrame.reset.coordSpaceto default.
setCustomUniforms
Section titled “setCustomUniforms”setCustomUniforms :: proc (data: rawptr, size: uint)Uploads custom uniform data to the currently active shader. This triggers a batch flush to ensure previous sprites are drawn with old uniforms.
setFontTexture
Section titled “setFontTexture”setFontTexture :: proc (view: sokol_gfx.View)Changes the active font texture view.
setScissorCoordinates
Section titled “setScissorCoordinates”setScissorCoordinates :: proc (coordinates: gmath.Vector4)Sets the scissor (clipping) rectangle. Flushes the batch if the scissor state changes.
setScissorRectangle
Section titled “setScissorRectangle”setScissorRectangle :: proc (rectangle: gmath.Rectangle)Maps a screen-space rectangle to a screen-space scissor rectangle. Used for clipping rendering to specific regions (masking).
setScreenSpace
Section titled “setScreenSpace”setScreenSpace :: proc ()Flushes the current batch and switches coordinate space to screen space (UI).
Sets the active draw layer to DrawLayer.ui.
setShader
Section titled “setShader”setShader :: proc (id: ShaderId = _renderContext.defaultShaderId)Sets the active shader pipeline for subsequent draw calls. Flushes the current batch if the shader changes.
Arguments:
id: Expects theShaderIdreturned byloadShader.
setTexture
Section titled “setTexture”setTexture :: proc (view: sokol_gfx.View)Changes the active main texture view.
setWorldSpace
Section titled “setWorldSpace”setWorldSpace :: proc ()Flushes the current batch and switches coordinate space to world space (gameplay).
Sets the active draw layer to DrawLayer.background.
shutdown
Section titled “shutdown”shutdown :: proc ()Cleans up all rendering resources. Called internally by main.odin.
swapchain
Section titled “swapchain”swapchain: = sokol_glue.swapchain()loadCanvas :: proc(width: i32, height: i32) -> CanvasId {