render: shapes: Add simple (but slow) bezier curve rendering.
authorDavid Thompson <dthompson2@worcester.edu>
Wed, 29 Aug 2018 21:53:35 +0000 (17:53 -0400)
committerDavid Thompson <dthompson2@worcester.edu>
Wed, 29 Aug 2018 21:53:35 +0000 (17:53 -0400)
* chickadee/render/shapes.scm (draw-bezier-curve, draw-bezier-path):
  New procedures.

chickadee/render/shapes.scm

index 9c89928..db54e3d 100644 (file)
@@ -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))