Skip to content

Add the DrawingImmediate library to the standard. #16

Description

@biggaboy212

Standard Name

DrawingImmediate

Overview

DrawingImmediate is an immediate-mode rendering library that provides low-level primitives for drawing overlays.

Problem Statement

DrawingImmediate solves the following problems that you can get by using the current standardized Drawing library which is retained-mode:

  • Retained-mode object systems requiring manual cleanup
  • Memory leaks caused by persistent drawing objects
  • Performance overhead from property updates on retained objects

As well as the benefits of having a immediately-made drawing object in relation to API ease.

Note that they solve different things and have different purposes, this isn't a deprecation request.

Proposed Signature

<library> DrawingImmediate

DrawingImmediate.GetPaint(z_index: number?): Signal<DrawingImmediateContext>

DrawingImmediate.Line(
    p1: Vector2,
    p2: Vector2,
    color: Color3,
    opacity: number,
    thickness: number
): ()

DrawingImmediate.Circle(
    center: Vector2,
    radius: number,
    color: Color3,
    opacity: number,
    num_sides: number,
    thickness: number
): ()

DrawingImmediate.FilledCircle(
    center: Vector2,
    radius: number,
    color: Color3,
    opacity: number,
    num_sides: number
): ()

DrawingImmediate.Triangle(
    p1: Vector2,
    p2: Vector2,
    p3: Vector2,
    color: Color3,
    opacity: number,
    thickness: number
): ()

DrawingImmediate.FilledTriangle(
    p1: Vector2,
    p2: Vector2,
    p3: Vector2,
    color: Color3,
    opacity: number
): ()

DrawingImmediate.Rectangle(
    top_left: Vector2,
    size: Vector2,
    color: Color3,
    opacity: number,
    rounding: number,
    thickness: number
): ()

DrawingImmediate.FilledRectangle(
    top_left: Vector2,
    size: Vector2,
    color: Color3,
    opacity: number,
    rounding: number
): ()

DrawingImmediate.Quad(
    p1: Vector2,
    p2: Vector2,
    p3: Vector2,
    p4: Vector2,
    color: Color3,
    opacity: number,
    thickness: number
): ()

DrawingImmediate.FilledQuad(
    p1: Vector2,
    p2: Vector2,
    p3: Vector2,
    p4: Vector2,
    color: Color3,
    opacity: number
): ()

DrawingImmediate.Text(
    position: Vector2,
    font: DrawFont,
    font_size: number,
    color: Color3,
    opacity: number,
    text: string,
    center: boolean
): ()

DrawingImmediate.OutlinedText(
    position: Vector2,
    font: DrawFont,
    font_size: number,
    color: Color3,
    opacity: number,
    outline_color: Color3,
    outline_opacity: number,
    text: string,
    center: boolean
): ()

Type Definitions

type Signal<T...> = RBXScriptSignal? -- Reference `Signal.new` check to learn what is valid for this

type DrawFont = Drawing.Fonts

type DrawingImmediateContext = {
    Line: (p1: Vector2, p2: Vector2, color: Color3, opacity: number, thickness: number) -> (),
    Circle: (center: Vector2, radius: number, color: Color3, opacity: number, num_sides: number, thickness: number) -> (),
    FilledCircle: (center: Vector2, radius: number, color: Color3, opacity: number, num_sides: number) -> (),
    Triangle: (p1: Vector2, p2: Vector2, p3: Vector2, color: Color3, opacity: number, thickness: number) -> (),
    FilledTriangle: (p1: Vector2, p2: Vector2, p3: Vector2, color: Color3, opacity: number) -> (),
    Rectangle: (top_left: Vector2, size: Vector2, color: Color3, opacity: number, rounding: number, thickness: number) -> (),
    FilledRectangle: (top_left: Vector2, size: Vector2, color: Color3, opacity: number, rounding: number) -> (),
    Quad: (p1: Vector2, p2: Vector2, p3: Vector2, p4: Vector2, color: Color3, opacity: number, thickness: number) -> (),
    FilledQuad: (p1: Vector2, p2: Vector2, p3: Vector2, p4: Vector2, color: Color3, opacity: number) -> (),
    Text: (position: Vector2, font: DrawFont, font_size: number, color: Color3, opacity: number, text: string, center: boolean) -> (),
    OutlinedText: (position: Vector2, font: DrawFont, font_size: number, color: Color3, opacity: number, outline_color: Color3, outline_opacity: number, text: string, center: boolean) -> ()
}

Behavior Specification

  • Is immediate-mode, meaning the object you call are only rendered immediately, and not any frames after.
  • No persisent objects should be created
  • DrawingImmediate renderobjects should only be rendered inside a GetPaint created Painter.

Example Usage

local camera = workspace.CurrentCamera

DrawingImmediate.GetPaint(0):Connect(function()
	DrawingImmediate.Circle(
        camera.ViewportSize / 2, 300, 
        Color3.new(1, 1, 1), 
        1, 
        64, 
        2
    )
end)

Implementation Notes

Although this function cannot be visually tested: Alike to how Myriad tests the Drawing library, we can test for the correct API structure, as well as make sure it's not being implemented internally (using ScreenGui)

To extend on above, you should not use ScreenGui for your implementation of Drawing and DrawingImmediate, use a external, non roblox-dependant method, such as DirectX, OpenGL, Vulkan, etc.

Submission Checklist

  • The API signature uses explicit Luau types.
  • The proposal describes expected runtime behavior.
  • Example usage is included.
  • You have verified it's behavior with other implementations, if possible.

Metadata

Metadata

Assignees

Labels

New StandardAdds a standard to what myriad tests for in our Standards test.Standards TestThe issue relates to the standards test

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions