diff options
-rw-r--r-- | chickadee/render/shapes.scm | 86 |
1 files changed, 85 insertions, 1 deletions
diff --git a/chickadee/render/shapes.scm b/chickadee/render/shapes.scm index 9c89928..db54e3d 100644 --- a/chickadee/render/shapes.scm +++ b/chickadee/render/shapes.scm @@ -25,6 +25,7 @@ (define-module (chickadee render shapes) #:use-module (ice-9 match) #:use-module (srfi srfi-4) + #:use-module (chickadee math bezier) #:use-module (chickadee math matrix) #:use-module (chickadee math rect) #:use-module (chickadee math vector) @@ -33,7 +34,9 @@ #:use-module (chickadee render shader) #:use-module (chickadee render buffer) #:export (draw-filled-rect - draw-line)) + draw-line + draw-bezier-curve + draw-bezier-path)) ;; TODO: Make a generic polygon renderer, include batching, etc. (define draw-filled-rect @@ -291,3 +294,84 @@ may use SHADER to override the built-in line segment shader." ('round 3) ('triangle-out 4) ('triangle-in 5)))))))) + +;; XXX: This is going to be hopelessly slow until I implement batching +;; for lines and shapes. +(define draw-bezier-curve + (let ((start #v(0.0 0.0)) + (end #v(0.0 0.0)) + (tmp #f) + (rect (make-rect 0.0 0.0 0.0 0.0))) + (lambda* (bezier #:key + (segments 32) + control-points? + tangents? + (control-point-size 8.0) + (color white) + (control-point-color yellow) + (tangent-color yellow) + (thickness 0.5) + (feather 1.0) + matrix) + "Draw the curve defined by BEZIER using a resolution of n SEGMENTS." + (define (draw-segment start end color) + (draw-line start end + #:thickness thickness + #:feather feather + #:cap 'none + #:color color)) + (define (draw-control-point p) + (let ((hs (/ control-point-size 2.0))) + (set-rect-x! rect (- (vec2-x p) hs)) + (set-rect-y! rect (- (vec2-y p) hs)) + (set-rect-width! rect control-point-size) + (set-rect-height! rect control-point-size) + (draw-filled-rect rect control-point-color #:matrix matrix))) + (bezier-curve-point-at! start bezier 0.0) + (let loop ((i 1)) + (when (<= i segments) + (bezier-curve-point-at! end bezier (exact->inexact (/ i segments))) + (draw-segment start end color) + ;; Make the previous end point is now the new start point + ;; for the next iteration. + (set! tmp start) + (set! start end) + (set! end tmp) + (loop (+ i 1)))) + (when tangents? + (draw-segment (bezier-curve-p0 bezier) + (bezier-curve-p1 bezier) + tangent-color) + (draw-segment (bezier-curve-p3 bezier) + (bezier-curve-p2 bezier) + tangent-color)) + (when control-points? + (draw-control-point (bezier-curve-p0 bezier)) + (draw-control-point (bezier-curve-p1 bezier)) + (draw-control-point (bezier-curve-p2 bezier)) + (draw-control-point (bezier-curve-p3 bezier)))))) + +(define* (draw-bezier-path path #:key + (segments 32) + control-points? + tangents? + (control-point-size 8.0) + (color white) + (control-point-color yellow) + (tangent-color yellow) + (thickness 0.5) + (feather 1.0) + matrix) + (for-each (lambda (bezier) + (draw-bezier-curve bezier + #:segments segments + #:control-points? control-points? + #:tangents? tangents? + #:control-point-size control-point-size + #:color color + #:control-point-color control-point-color + #:tangent-color tangent-color + #:thickness 0.5 + #:feather feather + #:matrix matrix)) + path)) |