gg: document all draw functions (#13931)

pull/13942/head
Larpon 2022-04-04 17:09:19 +02:00 committed by GitHub
parent 5369379738
commit aa9e2ebb25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 103 additions and 39 deletions

View File

@ -7,8 +7,11 @@ import sokol
import sokol.sgl import sokol.sgl
import math import math
//---- pixel // draw_pixel draws one pixel on the screen.
//
// NOTE calling this function frequently is very *inefficient*,
// for drawing shapes it's recommended to draw whole primitives with
// functions like `draw_rect_empty` or `draw_triangle_empty` etc.
[inline] [inline]
pub fn (ctx &Context) draw_pixel(x f32, y f32, c gx.Color) { pub fn (ctx &Context) draw_pixel(x f32, y f32, c gx.Color) {
if c.a != 255 { if c.a != 255 {
@ -21,7 +24,11 @@ pub fn (ctx &Context) draw_pixel(x f32, y f32, c gx.Color) {
sgl.end() sgl.end()
} }
// Sets pixels from an array of points [x, y, x2, y2, etc...] // draw_pixels draws pixels from an array of points [x, y, x2, y2, etc...]
//
// NOTE calling this function frequently is very *inefficient*,
// for drawing shapes it's recommended to draw whole primitives with
// functions like `draw_rect_empty` or `draw_triangle_empty` etc.
[direct_array_access; inline] [direct_array_access; inline]
pub fn (ctx &Context) draw_pixels(points []f32, c gx.Color) { pub fn (ctx &Context) draw_pixels(points []f32, c gx.Color) {
assert points.len % 2 == 0 assert points.len % 2 == 0
@ -40,9 +47,7 @@ pub fn (ctx &Context) draw_pixels(points []f32, c gx.Color) {
sgl.end() sgl.end()
} }
//---- line // draw_line draws a line between the points `x,y` and `x2,y2` in color `c`.
// Draws a line between the points provided
pub fn (ctx &Context) draw_line(x f32, y f32, x2 f32, y2 f32, c gx.Color) { pub fn (ctx &Context) draw_line(x f32, y f32, x2 f32, y2 f32, c gx.Color) {
$if macos { $if macos {
if ctx.native_rendering { if ctx.native_rendering {
@ -68,7 +73,7 @@ pub fn (ctx &Context) draw_line(x f32, y f32, x2 f32, y2 f32, c gx.Color) {
sgl.end() sgl.end()
} }
// Draws a line between the points provided with the PenConfig // draw_line_with_config draws a line between the points `x,y` and `x2,y2` using `PenConfig`.
pub fn (ctx &Context) draw_line_with_config(x f32, y f32, x2 f32, y2 f32, config PenConfig) { pub fn (ctx &Context) draw_line_with_config(x f32, y f32, x2 f32, y2 f32, config PenConfig) {
if config.color.a != 255 { if config.color.a != 255 {
sgl.load_pipeline(ctx.timage_pip) sgl.load_pipeline(ctx.timage_pip)
@ -119,10 +124,8 @@ pub fn (ctx &Context) draw_line_with_config(x f32, y f32, x2 f32, y2 f32, config
sgl.pop_matrix() sgl.pop_matrix()
} }
//---- polyline // draw_poly_empty draws the outline of a polygon, given an array of points, and a color.
// NOTE that the points must be given in clockwise winding order.
// draw_empty_poly draws the borders of a polygon, given an array of points, and a color.
// Note that the points must be given in clockwise order.
pub fn (ctx &Context) draw_poly_empty(points []f32, c gx.Color) { pub fn (ctx &Context) draw_poly_empty(points []f32, c gx.Color) {
assert points.len % 2 == 0 assert points.len % 2 == 0
len := points.len / 2 len := points.len / 2
@ -142,7 +145,8 @@ pub fn (ctx &Context) draw_poly_empty(points []f32, c gx.Color) {
} }
// draw_convex_poly draws a convex polygon, given an array of points, and a color. // draw_convex_poly draws a convex polygon, given an array of points, and a color.
// Note that the points must be given in clockwise order. // NOTE that the points must be given in clockwise winding order.
// The contents of the `points` array should be `x` and `y` coordinate pairs.
pub fn (ctx &Context) draw_convex_poly(points []f32, c gx.Color) { pub fn (ctx &Context) draw_convex_poly(points []f32, c gx.Color) {
assert points.len % 2 == 0 assert points.len % 2 == 0
len := points.len / 2 len := points.len / 2
@ -168,8 +172,9 @@ pub fn (ctx &Context) draw_convex_poly(points []f32, c gx.Color) {
sgl.end() sgl.end()
} }
//---- rectangle // draw_rect_empty draws the outline of a rectangle.
// `x`,`y` is the top-left corner of the rectangle.
// `w` is the width, `h` is the height and `c` is the color of the outline.
pub fn (ctx &Context) draw_rect_empty(x f32, y f32, w f32, h f32, c gx.Color) { pub fn (ctx &Context) draw_rect_empty(x f32, y f32, w f32, h f32, c gx.Color) {
if c.a != 255 { if c.a != 255 {
sgl.load_pipeline(ctx.timage_pip) sgl.load_pipeline(ctx.timage_pip)
@ -184,6 +189,9 @@ pub fn (ctx &Context) draw_rect_empty(x f32, y f32, w f32, h f32, c gx.Color) {
sgl.end() sgl.end()
} }
// draw_rect_filled draws a filled rectangle.
// `x`,`y` is the top-left corner of the rectangle.
// `w` is the width, `h` is the height and `c` is the color of the fill.
pub fn (ctx &Context) draw_rect_filled(x f32, y f32, w f32, h f32, c gx.Color) { pub fn (ctx &Context) draw_rect_filled(x f32, y f32, w f32, h f32, c gx.Color) {
$if macos { $if macos {
if ctx.native_rendering { if ctx.native_rendering {
@ -204,6 +212,10 @@ pub fn (ctx &Context) draw_rect_filled(x f32, y f32, w f32, h f32, c gx.Color) {
} }
// draw_rounded_rect_empty draws the outline of a rounded rectangle // draw_rounded_rect_empty draws the outline of a rounded rectangle
// `x`,`y` is the top-left corner of the rectangle.
// `w` is the width, `h` is the height.
// `radius` is the radius of the corner-rounding in pixels.
// `c` is the color of the outline.
pub fn (ctx &Context) draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius f32, c gx.Color) { pub fn (ctx &Context) draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius f32, c gx.Color) {
mut theta := f32(0) mut theta := f32(0)
mut xx := f32(0) mut xx := f32(0)
@ -262,7 +274,11 @@ pub fn (ctx &Context) draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius
sgl.end() sgl.end()
} }
// draw_rounded_rect_filled draws a filled rounded rectangle // draw_rounded_rect_filled draws a filled rounded rectangle.
// `x`,`y` is the top-left corner of the rectangle.
// `w` is the width, `h` is the height .
// `radius` is the radius of the corner-rounding in pixels.
// `c` is the color of the outline.
pub fn (ctx &Context) draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radius f32, c gx.Color) { pub fn (ctx &Context) draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radius f32, c gx.Color) {
sgl.c4b(c.r, c.g, c.b, c.a) sgl.c4b(c.r, c.g, c.b, c.a)
sgl.begin_triangle_strip() sgl.begin_triangle_strip()
@ -331,8 +347,11 @@ pub fn (ctx &Context) draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radiu
sgl.end() sgl.end()
} }
//---- triangle // draw_triangle_empty draws the outline of a triangle.
// `x`,`y` defines the first point
// `x2`,`y2` defines the second point
// `x3`,`y3` defines the third point
// `c` is the color of the outline.
pub fn (ctx &Context) draw_triangle_empty(x f32, y f32, x2 f32, y2 f32, x3 f32, y3 f32, c gx.Color) { pub fn (ctx &Context) draw_triangle_empty(x f32, y f32, x2 f32, y2 f32, x3 f32, y3 f32, c gx.Color) {
if c.a != 255 { if c.a != 255 {
sgl.load_pipeline(ctx.timage_pip) sgl.load_pipeline(ctx.timage_pip)
@ -347,6 +366,11 @@ pub fn (ctx &Context) draw_triangle_empty(x f32, y f32, x2 f32, y2 f32, x3 f32,
sgl.end() sgl.end()
} }
// draw_triangle_filled draws a filled triangle.
// `x`,`y` defines the first point
// `x2`,`y2` defines the second point
// `x3`,`y3` defines the third point
// `c` is the color of the outline.
pub fn (ctx &Context) draw_triangle_filled(x f32, y f32, x2 f32, y2 f32, x3 f32, y3 f32, c gx.Color) { pub fn (ctx &Context) draw_triangle_filled(x f32, y f32, x2 f32, y2 f32, x3 f32, y3 f32, c gx.Color) {
if c.a != 255 { if c.a != 255 {
sgl.load_pipeline(ctx.timage_pip) sgl.load_pipeline(ctx.timage_pip)
@ -359,20 +383,24 @@ pub fn (ctx &Context) draw_triangle_filled(x f32, y f32, x2 f32, y2 f32, x3 f32,
sgl.end() sgl.end()
} }
//---- square // draw_square_empty draws the outline of a square.
// `x`,`y` is the top-left corner of the square.
// `s` is the length of each side of the square.
// `c` is the color of the outline.
[inline] [inline]
pub fn (ctx &Context) draw_square_empty(x f32, y f32, s f32, c gx.Color) { pub fn (ctx &Context) draw_square_empty(x f32, y f32, s f32, c gx.Color) {
ctx.draw_rect_empty(x, y, s, s, c) ctx.draw_rect_empty(x, y, s, s, c)
} }
// draw_square_filled draws a filled square.
// `x`,`y` is the top-left corner of the square.
// `s` is the length of each side of the square.
// `c` is the fill color.
[inline] [inline]
pub fn (ctx &Context) draw_square_filled(x f32, y f32, s f32, c gx.Color) { pub fn (ctx &Context) draw_square_filled(x f32, y f32, s f32, c gx.Color) {
ctx.draw_rect_filled(x, y, s, s, c) ctx.draw_rect_filled(x, y, s, s, c)
} }
//---- circle
// The table here is derived by looking at the result of vlib/gg/testdata/tweak_circles.vv // The table here is derived by looking at the result of vlib/gg/testdata/tweak_circles.vv
// and then choosing the most circle-ish drawing with the minimum number of segments. // and then choosing the most circle-ish drawing with the minimum number of segments.
const small_circle_segments = [0, 2, 4, 6, 6, 8, 8, 13, 10, 18, 12, 12, 10, 13, 16, 15, 16]! const small_circle_segments = [0, 2, 4, 6, 6, 8, 8, 13, 10, 18, 12, 12, 10, 13, 16, 15, 16]!
@ -389,7 +417,10 @@ fn radius_to_segments(r f32) int {
return int(math.ceil(2 * math.pi * r / 8)) return int(math.ceil(2 * math.pi * r / 8))
} }
// draw_circle_empty draws an empty circle // draw_circle_empty draws the outline of a circle.
// `x`,`y` defines the center of the circle.
// `radius` defines the radius of the circle.
// `c` is the color of the outline.
pub fn (ctx &Context) draw_circle_empty(x f32, y f32, radius f32, c gx.Color) { pub fn (ctx &Context) draw_circle_empty(x f32, y f32, radius f32, c gx.Color) {
if c.a != 255 { if c.a != 255 {
sgl.load_pipeline(ctx.timage_pip) sgl.load_pipeline(ctx.timage_pip)
@ -414,12 +445,19 @@ pub fn (ctx &Context) draw_circle_empty(x f32, y f32, radius f32, c gx.Color) {
sgl.end() sgl.end()
} }
// draw_circle_filled draws a filled circle // draw_circle_filled draws a filled circle.
// `x`,`y` defines the center of the circle.
// `radius` defines the radius of the circle.
// `c` is the fill color.
pub fn (ctx &Context) draw_circle_filled(x f32, y f32, radius f32, c gx.Color) { pub fn (ctx &Context) draw_circle_filled(x f32, y f32, radius f32, c gx.Color) {
ctx.draw_circle_with_segments(x, y, radius, radius_to_segments(radius), c) ctx.draw_circle_with_segments(x, y, radius, radius_to_segments(radius), c)
} }
// draw_circle_with_segments draws a circle with a specific number of segments (affects how smooth/round the circle is) // draw_circle_with_segments draws a filled circle with a specific number of segments.
// `x`,`y` defines the center of the circle.
// `radius` defines the radius of the circle.
// `segments` affects how smooth/round the circle is.
// `c` is the fill color.
pub fn (ctx &Context) draw_circle_with_segments(x f32, y f32, radius f32, segments int, c gx.Color) { pub fn (ctx &Context) draw_circle_with_segments(x f32, y f32, radius f32, segments int, c gx.Color) {
if c.a != 255 { if c.a != 255 {
sgl.load_pipeline(ctx.timage_pip) sgl.load_pipeline(ctx.timage_pip)
@ -442,10 +480,16 @@ pub fn (ctx &Context) draw_circle_with_segments(x f32, y f32, radius f32, segmen
sgl.end() sgl.end()
} }
pub fn (ctx &Context) draw_circle_line(x f32, y f32, r int, segments int, c gx.Color) { // draw_circle_line draws the outline of a circle with a specific number of segments.
// `x`,`y` defines the center of the circle.
// `radius` defines the radius of the circle.
// `segments` affects how smooth/round the circle is.
// `c` is the color of the outline.
pub fn (ctx &Context) draw_circle_line(x f32, y f32, radius int, segments int, c gx.Color) {
$if macos { $if macos {
if ctx.native_rendering { if ctx.native_rendering {
C.darwin_draw_circle(x - r + 1, ctx.height - (y + r + 3), r, c) C.darwin_draw_circle(x - radius + 1, ctx.height - (y + radius + 3), radius,
c)
return return
} }
} }
@ -455,7 +499,7 @@ pub fn (ctx &Context) draw_circle_line(x f32, y f32, r int, segments int, c gx.C
sgl.c4b(c.r, c.g, c.b, c.a) sgl.c4b(c.r, c.g, c.b, c.a)
nx := x * ctx.scale nx := x * ctx.scale
ny := y * ctx.scale ny := y * ctx.scale
nr := r * ctx.scale nr := radius * ctx.scale
mut theta := f32(0) mut theta := f32(0)
mut xx := f32(0) mut xx := f32(0)
mut yy := f32(0) mut yy := f32(0)
@ -469,8 +513,6 @@ pub fn (ctx &Context) draw_circle_line(x f32, y f32, r int, segments int, c gx.C
sgl.end() sgl.end()
} }
//---- slice
// draw_slice_empty draws the outline of a circle slice/pie // draw_slice_empty draws the outline of a circle slice/pie
pub fn (ctx &Context) draw_slice_empty(x f32, y f32, outer_radius f32, start_angle f32, end_angle f32, segments int, c gx.Color) { pub fn (ctx &Context) draw_slice_empty(x f32, y f32, outer_radius f32, start_angle f32, end_angle f32, segments int, c gx.Color) {
if c.a != 255 { if c.a != 255 {
@ -500,6 +542,12 @@ pub fn (ctx &Context) draw_slice_empty(x f32, y f32, outer_radius f32, start_ang
} }
// draw_slice_filled draws a filled circle slice/pie // draw_slice_filled draws a filled circle slice/pie
// `x`,`y` defines the end point of the slice (center of the circle that the slice is part of).
// `radius` defines the radius ("length") of the slice.
// `start_angle` is the radians at which the slice starts.
// `end_angle` is the radians at which the slice ends.
// `segments` affects how smooth/round the slice is.
// `c` is the fill color.
pub fn (ctx &Context) draw_slice_filled(x f32, y f32, radius f32, start_angle f32, end_angle f32, segments int, c gx.Color) { pub fn (ctx &Context) draw_slice_filled(x f32, y f32, radius f32, start_angle f32, end_angle f32, segments int, c gx.Color) {
if c.a != 255 { if c.a != 255 {
sgl.load_pipeline(ctx.timage_pip) sgl.load_pipeline(ctx.timage_pip)
@ -526,9 +574,14 @@ pub fn (ctx &Context) draw_slice_filled(x f32, y f32, radius f32, start_angle f3
sgl.end() sgl.end()
} }
//---- arc // draw_arc_empty draws the outline of an arc.
// `x`,`y` defines the end point of the arc (center of the circle that the arc is part of).
// draw_arc_empty draws the outline of an arc // `inner_radius` defines the radius of the arc (length from the center point where the arc is drawn).
// `thickness` defines how wide the arc is drawn.
// `start_angle` is the radians at which the arc starts.
// `end_angle` is the radians at which the arc ends.
// `segments` affects how smooth/round the arc is.
// `c` is the color of the arc/outline.
pub fn (ctx &Context) draw_arc_empty(x f32, y f32, inner_radius f32, thickness f32, start_angle f32, end_angle f32, segments int, c gx.Color) { pub fn (ctx &Context) draw_arc_empty(x f32, y f32, inner_radius f32, thickness f32, start_angle f32, end_angle f32, segments int, c gx.Color) {
if start_angle == end_angle || inner_radius <= 0.0 { if start_angle == end_angle || inner_radius <= 0.0 {
return return
@ -584,7 +637,14 @@ pub fn (ctx &Context) draw_arc_empty(x f32, y f32, inner_radius f32, thickness f
sgl.end() sgl.end()
} }
// draw_arc_filled draws a filled arc // draw_arc_filled draws a filled arc.
// `x`,`y` defines the central point of the arc (center of the circle that the arc is part of).
// `inner_radius` defines the radius of the arc (length from the center point where the arc is drawn).
// `thickness` defines how wide the arc is drawn.
// `start_angle` is the radians at which the arc starts.
// `end_angle` is the radians at which the arc ends.
// `segments` affects how smooth/round the arc is.
// `c` is the fill color of the arc.
pub fn (ctx &Context) draw_arc_filled(x f32, y f32, inner_radius f32, thickness f32, start_angle f32, end_angle f32, segments int, c gx.Color) { pub fn (ctx &Context) draw_arc_filled(x f32, y f32, inner_radius f32, thickness f32, start_angle f32, end_angle f32, segments int, c gx.Color) {
if start_angle == end_angle || inner_radius <= 0.0 { if start_angle == end_angle || inner_radius <= 0.0 {
return return
@ -623,9 +683,11 @@ pub fn (ctx &Context) draw_arc_filled(x f32, y f32, inner_radius f32, thickness
sgl.end() sgl.end()
} }
//---- ellipse // draw_ellipse_empty draws the outline of an ellipse.
// `x`,`y` defines the center of the ellipse.
// draw_ellipse_empty draws the outline of an ellipse, with a center at x,y // `rw` defines the *width* radius of the ellipse.
// `rh` defines the *height* radius of the ellipse.
// `c` is the color of the outline.
pub fn (ctx &Context) draw_ellipse_empty(x f32, y f32, rw f32, rh f32, c gx.Color) { pub fn (ctx &Context) draw_ellipse_empty(x f32, y f32, rw f32, rh f32, c gx.Color) {
if c.a != 255 { if c.a != 255 {
sgl.load_pipeline(ctx.timage_pip) sgl.load_pipeline(ctx.timage_pip)
@ -641,7 +703,11 @@ pub fn (ctx &Context) draw_ellipse_empty(x f32, y f32, rw f32, rh f32, c gx.Colo
sgl.end() sgl.end()
} }
// draw_ellipse_filled - draws an opaque elipse, with a center at x,y , filled with the color `c` // draw_ellipse_filled draws an opaque elipse.
// `x`,`y` defines the center of the ellipse.
// `rw` defines the *width* radius of the ellipse.
// `rh` defines the *height* radius of the ellipse.
// `c` is the fill color.
pub fn (ctx &Context) draw_ellipse_filled(x f32, y f32, rw f32, rh f32, c gx.Color) { pub fn (ctx &Context) draw_ellipse_filled(x f32, y f32, rw f32, rh f32, c gx.Color) {
if c.a != 255 { if c.a != 255 {
sgl.load_pipeline(ctx.timage_pip) sgl.load_pipeline(ctx.timage_pip)
@ -658,8 +724,6 @@ pub fn (ctx &Context) draw_ellipse_filled(x f32, y f32, rw f32, rh f32, c gx.Col
sgl.end() sgl.end()
} }
//---- bezier
// draw_cubic_bezier draws a cubic Bézier curve, also known as a spline, from four points. // draw_cubic_bezier draws a cubic Bézier curve, also known as a spline, from four points.
// The four points is provided as one `points` array which contains a stream of point pairs (x and y coordinates). // The four points is provided as one `points` array which contains a stream of point pairs (x and y coordinates).
// Thus a cubic Bézier could be declared as: `points := [x1, y1, control_x1, control_y1, control_x2, control_y2, x2, y2]`. // Thus a cubic Bézier could be declared as: `points := [x1, y1, control_x1, control_y1, control_x2, control_y2, x2, y2]`.