summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2018-08-29 17:53:35 -0400
committerDavid Thompson <dthompson2@worcester.edu>2018-08-29 17:53:35 -0400
commit0a15a316d822f6c78a7fe7d11a23780adcb238d4 (patch)
tree09387b3f5a40bf92d8571afeadeb5f2d8e5ea9d2
parentb544b3c73291c4f0065e247f88fdbfcbf05906e8 (diff)
render: shapes: Add simple (but slow) bezier curve rendering.
* chickadee/render/shapes.scm (draw-bezier-curve, draw-bezier-path): New procedures.
-rw-r--r--chickadee/render/shapes.scm86
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))