var render = use('render') var graphics = use('graphics') var math = use('math') var util = use('util') var os = use('os') var geometry = use('geomtry') 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