Skip to content

luxe API (2025.1.2)


luxe: draw module


Draw

import "luxe: draw" for Draw

Draw is a service API that offers drawing to a context (canvas) in an efficient way. Things like lines, circles, paths and so on are what it provides. The terms canvas and context will be used interchangeably.

It is important to note that Draw is a commit based API. A brief tutorial on using it can be found here: 2D drawing tutorial.

Draw can be used to draw game content with, but is also a great tool for debug visualization. Many problems are a lot clearer when their details are drawn in the world, which Draw is very useful for.

The context can be drawn to once or updated frequently. For example you might draw a grid to the context, and then leave it there which is a very efficient way to draw many lines.

  • create(set: Any)
  • create(set: RenderSet, tri_basis: String, text_basis: String, line_basis: String)
  • destroy(context: Any)
  • valid(context: Any)
  • clear(context: Any)
  • commit(context: Any)
  • rect(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, style: Any)
  • rect_detailed(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, radius: Any, smoothness: Any, style: Any)
  • quad_detailed(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, radius: Any, smoothness: Any, color: Any)
  • quad(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, color: Any)
  • ngon(context: Any, ox: Any, oy: Any, oz: Any, rx: Any, ry: Any, sides: Any, angle: Any, style: Any)
  • ngon_solid(context: Any, ox: Any, oy: Any, oz: Any, rx: Any, ry: Any, sides: Any, angle: Any, color: Any)
  • ring(context: Any, ox: Any, oy: Any, oz: Any, rx: Any, ry: Any, start_angle: Any, end_angle: Any, smoothness: Any, style: Any)
  • ring(context: Any, ox: Any, oy: Any, oz: Any, radius: Any, smoothness: Any, style: Any)
  • circle(context: Any, ox: Any, oy: Any, oz: Any, radius: Any, smoothness: Any, color: Any)
  • circle(context: Any, ox: Any, oy: Any, oz: Any, rx: Any, ry: Any, start_angle: Any, end_angle: Any, smoothness: Any, color: Any)
  • line(context: Any, x1: Any, y1: Any, x2: Any, y2: Any, z: Any, style: Any)
  • path(context: Any, points: Any, style: Any, closed: Any)
  • path3D(context: Any, points: Any, style: Any, closed: Any)
  • line3D(context: Draw, start: Vec, end: Vec, style: PathStyle)
  • bounds3D(context: Any, geometry: Any, style: Any)
  • aabb3D(context: Any, center: Any, radius: Any, style: Any)
  • plane3D(context: Draw, pos: Vec, normal: Vec, radius: Num, style: PathStyle)
  • plus3D(context: Draw, pos: Vec, radius: Num, style: PathStyle)
  • ring3D(context: Draw, pos: Vec3, radius: Vec2, start_angle: Num, end_angle: Num, smoothness: Num, style: PathStyle)
  • plus(context: Draw, pos: Vec, radius: Num, style: PathStyle)
  • camera(context: Draw, camera: Entity, style: PathStyle)
  • frustum(context: Draw, corners: List, style: PathStyle)
  • text(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, string: Any, size: Any, font: Any, color: Any, align: Any, align_vertical: Any)
  • text(context: Any, x: Any, y: Any, z: Any, string: Any, size: Any, font: Any, color: Any, align: Any, align_vertical: Any)
  • text(context: Any, x: Any, y: Any, z: Any, string: Any, size: Any, color: Any)
  • image(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, material: Any)
  • image(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, color: Any, uv: Any, material: Any)
  • cross(context: Any, x: Any, y: Any, z: Any, radius: Any, angle: Any, style: Any)
  • sphere3D_slice(context: Draw, pos: Vec3, radius: Vec2, start_angle: Num, end_angle: Num, layers: Num, style: PathStyle)

Draw.create(set: Any) returns unknown

Creates a new drawing context to draw with. The set passed in is a RenderSet, which you normally get from a World via World.render_set(world). This would place the canvas in the world to be rendered at the same time, as part of the world.

var canvas = Draw.create(World.render_set(app.world))

Draw.create(set: RenderSet, tri_basis: String, text_basis: String, line_basis: String) returns unknown

Creates a new drawing context to draw with. The set passed in is a RenderSet, which you normally get from a World via World.render_set(world). This would place the canvas in the world to be rendered at the same time, as part of the world.

  • tri_basis
  • Triangle Material Basis for the geometry
  • default luxe: material_basis/solid
  • text_basis
  • Text Material Basis
  • default luxe: material_basis/font
  • line_basis
  • Line Material Basis for 3D line geometry
  • default luxe: material_basis/debug_line3d

    var canvas = Draw.create(World.render_set(app.world), "luxe: material_basis/solid", "luxe: material_basis/font", "luxe: material_basis/debug_line3d")

Draw.destroy(context: Any) returns unknown

Destroy a previously created context.

var canvas = Draw.create(World.render_set(app.world))
...
Draw.destroy(canvas)

Draw.valid(context: Any) returns unknown

Returns true if the context is valid (and hasn't been destroyed).

var canvas = Draw.create(World.render_set(app.world))
var canvas = Draw.create(World.render_set(app.world))
Log.print(Draw.valid(canvas)) //true
Draw.destroy(canvas)
Log.print(Draw.valid(canvas)) //false

Draw.clear(context: Any) returns unknown

Clears the context of any drawn content. This clears both committed and uncommitted data.

Draw.clear(draw)

Draw.commit(context: Any) returns unknown

Commit the content that has been drawn to the context.

When using the Draw API, you can submit a bunch of drawing to happen, but it won't show up until it is committed.

You can think of the draw calls as a queue, commit will process that queue, and the canvas contents will be updated. The content will stay there until commit is called again.

Calling commit with nothing in the queue will clear the contents (see also Draw.clear).

var canvas = Draw.create(World.render_set(app.world))
//draw a red box rotated 45 degrees
Draw.quad(canvas, 0, 0, 0, 100, 100, 45, [1, 0, 0, 1])
Draw.commit(canvas)

Draw.rect(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, style: Any) returns unknown

Draws a rectangle outline using style (PathStyle) at x,y, with depth z, with width of w and height of h. The rectangle will be rotated angle degrees.

var depth = 0
var angle = 45
var style = PathStyle.new()
    style.color = [1,0,0,1]
    style.thickness = 2
Draw.rect(canvas, 0, 0, depth, 100, 100, angle, style)

Draw.rect_detailed(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, radius: Any, smoothness: Any, style: Any) returns unknown

Draws a detailed rectangle outline using style (PathStyle) at x,y, with depth z, with width of w and height of h. The rectangle will be rotated angle degrees.

"Detailed" means that the corners can be configured using the radius and smoothness values. This allows drawing rounded rectangles, rectangles with inverted rounded corners, and with flat corners. The radius controls the amount inset from the edges. With a smoothness of 0, the corners will be angled/flat.

The order is [bottom left, bottom right, top right, top left] for radius + smoothness.

var depth = 0
var angle = 0
var style = PathStyle.new()
var radius = [16, 16, 16, 16]
var smoothness = [2, 2, 2, 2]
Draw.rect_detailed(_ctx, 64, 64, depth, 256, 128, angle, radius, smoothness, style)

Draw.quad_detailed(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, radius: Any, smoothness: Any, color: Any) returns unknown

Draws a detailed rectangle using color at x,y, with depth z, with width of w and height of h. The rectangle will be rotated angle degrees.

"Detailed" means that the corners can be configured using the radius and smoothness values. This allows drawing rounded rectangles, rectangles with inverted rounded corners, and with flat corners. The radius controls the amount inset from the edges. With a smoothness of 0, the corners will be angled/flat.

The order is [bottom left, bottom right, top right, top left] for radius + smoothness.

var depth = 0
var angle = 0
var color = [0,0,0,1]
var radius = [16, 16, 16, 16]
var smoothness = [2, 2, 2, 2]
Draw.quad_detailed(_ctx, 64, 64, depth, 256, 128, angle, radius, smoothness, color)

Draw.quad(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, color: Any) returns unknown

Draws a solid rectangle using color at x,y, with depth z, with width of w and height of h. The rectangle will be rotated angle degrees.

//draw a black solid rectangle
var depth = 0
var angle = 45
Draw.quad(canvas, 0, 0, depth, 100, 100, angle, [0,0,0,1])

Draw.ngon(context: Any, ox: Any, oy: Any, oz: Any, rx: Any, ry: Any, sides: Any, angle: Any, style: Any) returns unknown

Draw an ngon (like a triangle, hexagon, pentagon etc) outline at ox,oy at depth oz. The rx and ry radius values control the size of the shape around its origin. The number of sides controls how many sides the polygon will have (3 for a triangle, 6 for a hexagon). sides must be bigger than 3 to make sense for this function, it will be clamped to 3.

var depth = 0
var sides = 3
var radius = 32
var angle = 45
var style = PathStyle.new()
Draw.ngon(canvas, 128, 128, depth, radius, radius, sides, angle, style)

Draw.ngon_solid(context: Any, ox: Any, oy: Any, oz: Any, rx: Any, ry: Any, sides: Any, angle: Any, color: Any) returns unknown

Draw a solid ngon (like a triangle, hexagon, pentagon etc) at ox,oy at depth oz. The rx and ry radius values control the size of the shape around its origin. The number of sides controls how many sides the polygon will have (3 for a triangle, 6 for a hexagon). sides must be bigger than 3 to make sense for this function.

:todo: this naming will change soon to be consistent across all draw APIs.

var depth = 0
var sides = 3
var radius = 32
var angle = 45
Draw.ngon_solid(canvas, 128, 128, depth, radius, radius, sides, angle, Color.pink)

Draw.ring(context: Any, ox: Any, oy: Any, oz: Any, rx: Any, ry: Any, start_angle: Any, end_angle: Any, smoothness: Any, style: Any) returns unknown

Draw a circle outline at ox,oy at depth oz. rx and ry control separate radius values for x and y axis, to draw an ellipse.

start_angle and end_angle specify in degrees allow drawing an open arc, instead of a closed circle. A closed circle has start_angle as 0 and end_angle as 360. These angles match "the unit circle" in mathematics, where 0 is to the right, and 90 is pointing up.

:todo: smoothness controls how smooth the circle will be.

var depth = 0
var start_angle = 0
var end_angle = 270
var smoothness = 2
var style = PathStyle.new()
Draw.ring(canvas, 128, 128, depth, 32, 16, start_angle, end_angle, smoothness, style)

Draw.ring(context: Any, ox: Any, oy: Any, oz: Any, radius: Any, smoothness: Any, style: Any) returns unknown

Similar to ring with a single radius for both x and y.

Draw.circle(context: Any, ox: Any, oy: Any, oz: Any, radius: Any, smoothness: Any, color: Any) returns unknown

Draw a solid circle at ox,oy at depth oz, using color and radius in size. :todo: smoothness controls how smooth the circle will be.

var depth = 0
var smoothness = 2
Draw.circle(canvas, 128, 128, depth, 32, smoothness, [1,0,0,1])

Draw.circle(context: Any, ox: Any, oy: Any, oz: Any, rx: Any, ry: Any, start_angle: Any, end_angle: Any, smoothness: Any, color: Any) returns unknown

Draw a solid circle at ox,oy at depth oz. rx and ry control separate radius values for x and y axis, to draw an ellipse.

start_angle and end_angle specify in degrees allow drawing an open area, like a pie chart (or pacman) instead of a closed circle. A closed circle has start_angle as 0 and end_angle as 360. These angles match "the unit circle" in mathematics, where 0 is to the right, and 90 is pointing up.

:todo: smoothness controls how smooth the circle will be.

var depth = 0
var start_angle = 0
var end_angle = 270
var smoothness = 2
Draw.circle(canvas, 128, 128, depth, 32, 16, start_angle, end_angle, smoothness, Color.black)

Draw.line(context: Any, x1: Any, y1: Any, x2: Any, y2: Any, z: Any, style: Any) returns unknown

Draw a line from x1,y1 to x2,y2 at depth z using style (PathStyle).

var depth = 0
var style = PathStyle.new()
Draw.line(canvas, 0,0, 100,100, depth, style)

Draw.path(context: Any, points: Any, style: Any, closed: Any) returns unknown

Draw a path consisting of a list of points.

If closed is true it is expected that the first and last point in points have the same positions.

points is a List of [x, y] or [x,y,z] points. If z is not specified for a point it will be 0. Note that this is a 2D drawing function atm, so different z values may not be what you expect.

var style = PathStyle.new()
var points = [
  [0,0],
  [100,100],
  [120,50],
  [0,0]
]
Draw.path(canvas, points, style, true)

Draw.path3D(context: Any, points: Any, style: Any, closed: Any) returns unknown

Draw a 3D path consisting of a list of points.

If closed is true it is expected that the first and last point in points have the same positions.

points is a List of [x,y,z] points.

var style = PathStyle.new()
var points = [
  [0,0,0],
  [100,100,100],
  [120,50,100],
  [0,0,0]
]
Draw.path3D(canvas, points, style, true)

Draw.line3D(context: Draw, start: Vec, end: Vec, style: PathStyle) returns unknown

Draw a 3D line from start to end using style.

var style = PathStyle.new()
Draw.line3D(canvas, [100,100,100], [120,50,100], style)

Draw.bounds3D(context: Any, geometry: Any, style: Any) returns unknown

no docs found

Draw.aabb3D(context: Any, center: Any, radius: Any, style: Any) returns unknown

no docs found

Draw.plane3D(context: Draw, pos: Vec, normal: Vec, radius: Num, style: PathStyle) returns unknown

no docs found

Draw.plus3D(context: Draw, pos: Vec, radius: Num, style: PathStyle) returns unknown

Draw a 3D plus at pos with size radius using style.

var style = PathStyle.new()
Draw.plus3D(canvas, [100,100,100], 4, style)

Draw.ring3D(context: Draw, pos: Vec3, radius: Vec2, start_angle: Num, end_angle: Num, smoothness: Num, style: PathStyle) returns unknown

Draw a 3D ring at pos with radius [radius_x, radius_y] using style.

var style = PathStyle.new()
Draw.ring3D(canvas, [100,100,100], [4, 4], 0, 360, smoothness, style)

Draw.plus(context: Draw, pos: Vec, radius: Num, style: PathStyle) returns unknown

Draw a 2D plus at pos with size radius using style.

var style = PathStyle.new()
Draw.plus(canvas, [100,100], 20, style)

Draw.camera(context: Draw, camera: Entity, style: PathStyle) returns unknown

Draw a 3D camera frustum for the given camera entity using style.

var style = PathStyle.new()
Draw.camera(canvas, camera, style)

Draw.frustum(context: Draw, corners: List, style: PathStyle) returns unknown

Draw a 3D camera frustum for the given 8 corner points using style. (You can get one from Camera.get_frustum(entity) for example, but can use Draw.camera as well).

var style = PathStyle.new()
var corners = [
  near_top_left, 
  near_top_right, 
  near_bottom_left, 
  near_bottom_right,
  far_top_left, 
  far_top_right, 
  far_bottom_left, 
  far_bottom_right,
]
Draw.frustum(canvas, corners, style)

Draw.text(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, string: Any, size: Any, font: Any, color: Any, align: Any, align_vertical: Any) returns unknown

Draw the specified string at x,y and depth z. w and h specify the bounds for the text, bottom left origin, y going up. The size specifies the text size, and color the color. font is a font asset, e.g Asset.font("luxe: font/lato"). align and align_vertical control alignment within the bounds, using the TextAlign enums such as TextAlign.left.

var depth = 0
var size = 24
var red = [1,0,0,1]
Draw.text(canvas, 32, 32, depth, 100, 32, "hello", size, Asset.font("luxe: font/lato"), red, TextAlign.center, TextAlign.bottom)

Draw.text(context: Any, x: Any, y: Any, z: Any, string: Any, size: Any, font: Any, color: Any, align: Any, align_vertical: Any) returns unknown

Draw the specified string at x,y and depth z. The size specifies the text size, and color the color. font is a font asset, e.g Asset.font("luxe: font/lato"). align and align_vertical control alignment relative to the specified position, using the TextAlign enums such as TextAlign.left.

var depth = 0
var size = 24
var red = [1,0,0,1]
Draw.text(canvas, 32, 32, depth, "hello", size, Asset.font("luxe: font/lato"), red, TextAlign.center, TextAlign.bottom)

Draw.text(context: Any, x: Any, y: Any, z: Any, string: Any, size: Any, color: Any) returns unknown

Draw the specified string at x,y, z. The size specifies the text size, and color the color.

var depth = 0
var size = 24
var red = [1,0,0,1]
Draw.text(canvas, 32, 32, depth, "hello", size, red)

Draw.image(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, material: Any) returns unknown

Draw an image with the specified material at x,y and depth z. The image will be rotated by angle degrees.

var depth = 0
var angle = 30
var material = Assets.material("luxe: material/logo.sprite")
Draw.image(canvas, 128, 128, depth, 64, 64, angle, material)

Draw.image(context: Any, x: Any, y: Any, z: Any, w: Any, h: Any, angle: Any, color: Any, uv: Any, material: Any) returns unknown

Draw an image with the specified material at x,y and depth z. The image will be rotated by angle degrees.

The uv value specifies a fixed rectangle like [left, top, right, bottom] in the 0..1 range, where [0,0,1,1] is the default and displays the full image. A uv value of [0.5, 0, 1, 0.5] would draw the top right corner of the image only. A uv value of [0, 0, 4, 4] would tile the image 4 times (as long as the material has a repeat mode for the image).

var depth = 0
var angle = 30
var material = Assets.material("luxe: material/logo.sprite")
var uv = [0, 0.5, 0, 1] //bottom right
Draw.image(canvas, 128, 128, depth, 64, 64, angle, uv, material)

Draw.cross(context: Any, x: Any, y: Any, z: Any, radius: Any, angle: Any, style: Any) returns unknown

Draws a cross, an x shape

Draw.sphere3D_slice(context: Draw, pos: Vec3, radius: Vec2, start_angle: Num, end_angle: Num, layers: Num, style: PathStyle) returns unknown

Draw a 3D sphere made from layered circles with layers number of circles and radius radius. Make the start_angle 0 and the end_angle 360 to make a full sphere, or 0/180 for a half sphere.

Draw.sphere3D_slice(canvas, [0, 2, 0], 1, 0, 360, 16, PathStyle.new())

LineCap

import "luxe: draw" for LineCap

The end of a line is called a "cap", when drawing paths, this determines the type of cap that a line will have. :todo: images


LineCap.butt returns unknown

This cap is as if there was no cap, the line is just ended. The default.

var style = PathStyle.new()
    style.cap = LineCap.butt

LineCap.round returns unknown

A round cap is a half circle at the end of the line.

var style = PathStyle.new()
    style.cap = LineCap.round

LineCap.square returns unknown

A square cap is a square at the end of the line.

var style = PathStyle.new()
    style.cap = LineCap.square

LineCap.from_string(value: Any) returns unknown

Convert a string to a LineCap value.

Log.print(LineCap.round == LineCap.from_string("round")) //true

LineJoin

import "luxe: draw" for LineJoin

When drawing a path, a series of lines will be drawn and joined together. The join of each connection can be configured when drawing paths using LineJoin. :todo: images


LineJoin.bevel returns unknown

The default join is a bevel, which is a flat join.

var style = PathStyle.new()
    style.join = LineJoin.bevel

LineJoin.round returns unknown

A round join is a semi circle that makes the corner rounded.

var style = PathStyle.new()
    style.join = LineJoin.round

LineJoin.miter returns unknown

A miter join is a sharp triangle join that has a limit value (which falls back to bevel).

var style = PathStyle.new()
    style.join = LineJoin.miter
    style.miter_limit = 8

LineJoin.from_string(value: Any) returns unknown

Convert a string to a LineJoin value.

Log.print(LineJoin.round == LineJoin.from_string("round")) //true

PathStyle

import "luxe: draw" for PathStyle


PathStyle.array returns unknown

no docs found

PathStyle.color returns unknown

Returns the color of the path style.

var style = PathStyle.new()
var color = style.color //the default color

PathStyle.alpha(value: Any) returns unknown

no docs found

PathStyle.color(value: Any) returns unknown

no docs found

PathStyle.thickness(value: Any) returns unknown

no docs found

PathStyle.color=(value : Any) returns unknown

Set the color for the style.

var style = PathStyle.new()
style.color = [0, 0, 0, 1] //black

PathStyle.alpha returns unknown

Returns the alpha from the color of the path style.

var style = PathStyle.new()
var color = style.alpha //the alpha value of the default color

PathStyle.alpha=(value : Any) returns unknown

Set the alpha of the color for the style.

var style = PathStyle.new()
style.alpha = 0.5 //half alpha

PathStyle.thickness returns unknown

Returns the thickness of the path style.

var style = PathStyle.new()
Log.print(style.thickness) //1

PathStyle.thickness=(value : Any) returns unknown

Set the thickness of the path style.

var style = PathStyle.new()
style.thickness = 4

PathStyle.feather returns unknown

Returns the feather value for the path style. Note: not used much at the moment.

var style = PathStyle.new()
var feather = style.feather

PathStyle.feather=(value : Any) returns unknown

Set the feather value for the path style. Note: not used much at the moment.

var style = PathStyle.new()
style.feather = 2

PathStyle.cap returns unknown

Returns the LineCap type for the path style.

var style = PathStyle.new()
var cap = style.cap

PathStyle.cap=(value : Any) returns unknown

Set the LineCap type for the path style.

var style = PathStyle.new()
style.cap = LineCap.round

PathStyle.join returns unknown

Returns the LineJoin type for the path style.

var style = PathStyle.new()
var join = style.join

PathStyle.join=(value : Any) returns unknown

Set the LineJoin type for the path style.

var style = PathStyle.new()
style.cap = LineJoin.round

PathStyle.miter_limit returns unknown

Returns the miter limit for the path style. Only relevant if the join type is LineJoin.miter.

var style = PathStyle.new()
var limit = style.miter_limit

PathStyle.miter_limit=(value : Any) returns unknown

Set the miter limit for the path style. Only relevant if the join type is LineJoin.miter.

var style = PathStyle.new()
style.miter_limit = 8

PathStyle.new() returns PathStyle

Create a new PathStyle instance.

var style = PathStyle.new()
style.color = [1,0,0,1]
style.thickness = 2
style.join = LineJoin.round
//use style
//...
style.thickness = 1
//use style again...