Files
cell/scripts/modules/draw2d.js
John Alanbrook b8328657df
Some checks failed
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
Build and Deploy / build-linux (push) Has been cancelled
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
add camera test
2025-04-14 22:46:07 -05:00

266 lines
8.9 KiB
JavaScript

var render = use('render')
var graphics = use('graphics')
var math = use('math')
var util = use('util')
var os = use('os')
var geometry = use('geometry')
var draw = {}
draw[prosperon.DOC] = `
A collection of 2D drawing functions that operate in screen space. Provides primitives
for lines, rectangles, text, sprite drawing, etc.
`
var whiteimage = {}
whiteimage.surface = graphics.make_surface([1,1])
whiteimage.surface.rect({x:0,y:0,width:1,height:1}, [1,1,1,1])
render.load_texture(whiteimage)
draw.point = function (pos, size, color = Color.blue) {
draw.rectangle({x:pos.x,y:pos.y, width:size,height:size})
}
draw.point[prosperon.DOC] = `
:param pos: A 2D position ([x, y]) where the point should be drawn.
:param size: The size of the point.
:param color: The color of the point, defaults to white.
:return: None
`
draw.line = function render_line(points, color = Color.white, thickness = 1, pipeline) {
var mesh = graphics.make_line_prim(points, thickness, 0, 0, color)
render.queue({
type: 'geometry',
mesh,
pipeline,
first_index: 0,
num_indices: mesh.num_indices,
image:whiteimage
})
}
draw.line[prosperon.DOC] = `
:param points: An array of 2D positions representing the line vertices.
:param color: The color of the line, default Color.white.
:param thickness: The line thickness, default 1.
:param pipeline: (Optional) A pipeline or rendering state object.
:return: None
`
draw.cross = function render_cross(pos, size, color = Color.red, thickness = 1, pipe) {
var a = [pos.add([0, size]), pos.add([0, -size])]
var b = [pos.add([size, 0]), pos.add([-size, 0])]
draw.line(a, color, thickness)
draw.line(b, color, thickness)
}
draw.cross[prosperon.DOC] = `
:param pos: The center of the cross as a 2D position ([x, y]).
:param size: Half the size of each cross arm.
:param color: The color of the cross, default Color.red.
:param thickness: The thickness of each line, default 1.
:param pipe: (Optional) A pipeline or rendering state object.
:return: None
`
draw.arrow = function render_arrow(start, end, color = Color.red, wingspan = 4, wingangle = 10, pipe) {
var dir = math.norm(end.sub(start))
var wing1 = [math.rotate(dir, wingangle).scale(wingspan).add(end), end]
var wing2 = [math.rotate(dir, -wingangle).scale(wingspan).add(end), end]
draw.line([start, end], color)
draw.line(wing1, color)
draw.line(wing2, color)
}
draw.arrow[prosperon.DOC] = `
:param start: The start position of the arrow ([x, y]).
:param end: The end (tip) position of the arrow ([x, y]).
:param color: The color, default Color.red.
:param wingspan: The length of each arrowhead 'wing', default 4.
:param wingangle: Wing rotation in degrees, default 10.
:param pipe: (Optional) A pipeline or rendering state object.
:return: None
`
draw.rectangle = function render_rectangle(rect, color = Color.white, pipeline) {
var T = os.make_transform()
T.rect(rect)
render.queue({
type: 'sprite',
transform: T,
color,
pipeline,
image: whiteimage
})
}
draw.rectangle[prosperon.DOC] = `
:param rect: A rectangle object with {x, y, width, height}.
:param color: The fill color, default Color.white.
:param pipeline: (Optional) A pipeline or rendering state object.
:return: None
`
var tile_def = {repeat_x:true, repeat_y:true}
draw.tile = function(image, rect, color = Color.white, tile = tile_def, pipeline) {
if (!image) throw Error('Need an image to render.')
if (typeof image === "string")
image = graphics.texture(image)
var mesh = geometry.tile(image.texture, {x:0,y:0,width:image.texture.width,height:image.texture.height}, rect, tile)
render.queue({
type:'geometry',
mesh,
image,
pipeline,
first_index:0,
num_indices:mesh.num_indices
})
}
draw.tile[prosperon.DOC] = `
:param image: An image object or string path to a texture.
:param rect: A rectangle specifying draw location/size ({x, y, width, height}).
:param color: The color tint, default Color.white.
:param tile: A tiling definition ({repeat_x, repeat_y}), default tile_def.
:param pipeline: (Optional) A pipeline or rendering state object.
:return: None
:raises Error: If no image is provided.
`
var slice9_info = {
tile_top:true,
tile_bottom:true,
tile_left:true,
tile_right:true,
tile_center_x:true,
tile_center_right:true
}
draw.slice9 = function slice9(image, rect = [0,0], slice = 0, color = Color.white, info = slice9_info, pipeline) {
if (!image) throw Error('Need an image to render.')
if (typeof image === "string")
image = graphics.texture(image)
var mesh = geometry.slice9(image.texture, rect, util.normalizeSpacing(slice), info)
render.queue({
type: 'geometry',
mesh,
image,
pipeline,
first_index:0,
num_indices:mesh.num_indices
})
}
draw.slice9[prosperon.DOC] = `
:param image: An image object or string path to a texture.
:param rect: A rectangle specifying draw location/size, default [0, 0].
:param slice: The pixel inset or spacing for the 9-slice (number or object).
:param color: The color tint, default Color.white.
:param info: A slice9 info object controlling tiling of edges/corners.
:param pipeline: (Optional) A pipeline or rendering state object.
:return: None
:raises Error: If no image is provided.
`
var std_sprite_cmd = {type:'sprite', color:[1,1,1,1]}
draw.image = function image(image, rect = [0,0], rotation = 0, color, pipeline) {
if (!image) throw Error('Need an image to render.')
if (typeof image === "string")
image = graphics.texture(image)
rect.width ??= image.texture.width
rect.height ??= image.texture.height
var cmd = Object.create(std_sprite_cmd)
cmd.image = image
cmd.rect = rect
if (pipeline) cmd.pipeline = pipeline
if (color) cmd.color = color
render.queue(cmd)
var sprite = graphics.make_sprite()
sprite.set_image(image)
sprite.set_rect(rect)
return sprite
}
draw.image[prosperon.DOC] = `
:param image: An image object or string path to a texture.
:param rect: A rectangle specifying draw location/size, default [0,0]; width/height default to image size.
:param rotation: Rotation in degrees (not currently used).
:param color: The color tint, default none.
:param pipeline: (Optional) A pipeline or rendering state object.
:return: A sprite object that was created for this draw call.
:raises Error: If no image is provided.
`
draw.images = function images(image, rects, config) {
if (!image) throw Error('Need an image to render.')
if (typeof image === "string") image = graphics.texture(image)
var bb = []
bb.width = image.texture.width
bb.height = image.texture.height
var sprites = []
for (var rect of rects) {
rect.__proto__ = bb
var sprite = graphics.make_sprite()
sprite.set_rect(rect)
sprite.set_image(image)
sprites.push(sprite)
}
var cmds = graphics.make_sprite_queue(sprites, prosperon.camera, undefined)
for (var i = 0; i < cmds.length; i++)
render.queue(cmds[i])
return sprites
}
draw.images[prosperon.DOC] = `
:param image: An image object or string path to a texture.
:param rects: An array of rectangle objects ({x, y, width, height}) to draw.
:param config: (Unused) Additional config data if needed.
:return: An array of sprite objects created and queued for rendering.
:raises Error: If no image is provided.
`
draw.sprites = function(sprites, sort = 0, pipeline) {
var cmds = graphics.make_sprite_queue(sprites, prosperon.camera, pipeline, sort)
for (var i = 0; i < cmds.length; i++)
render.queue(cmds[i])
}
draw.sprites[prosperon.DOC] = `
:param sprites: An array of sprite objects to draw.
:param sort: Sorting mode or order, default 0.
:param pipeline: (Optional) A pipeline or rendering state object.
:return: None
`
draw.circle = function render_circle(pos, radius, color, inner_radius = 1, pipeline) {
draw.rectangle({x:pos.x, y:pos.y, width:radius*2,height:radius*2}, color, circle_pipeline)
}
draw.circle[prosperon.DOC] = `
:param pos: Center of the circle ([x, y]).
:param radius: The circle radius.
:param color: The fill color of the circle, default none.
:param inner_radius: (Unused) Possibly ring thickness, default 1.
:param pipeline: (Optional) A pipeline or rendering state object.
:return: None
`
var sysfont = graphics.get_font('fonts/c64.ttf', 8)
draw.text = function text(text, rect, font = sysfont, size = 0, color = Color.white, wrap = 0, pipeline) {
if (typeof font === 'string') font = graphics.get_font(font)
var mesh = graphics.make_text_buffer(text, rect, 0, color, wrap, font)
render.queue({
type: 'geometry',
mesh,
image: font,
texture: font.texture,
pipeline,
first_index:0,
num_indices:mesh.num_indices
})
}
draw.text[prosperon.DOC] = `
:param text: The string to draw.
:param rect: A rectangle specifying draw position (and possibly wrapping area).
:param font: A font object or string path, default sysfont.
:param size: (Unused) Possibly intended for scaling the font size.
:param color: The text color, default Color.white.
:param wrap: Pixel width for text wrapping, default 0 (no wrap).
:param pipeline: (Optional) A pipeline or rendering state object.
:return: None
`
return draw