summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chickadee/graphics/path.scm72
1 files changed, 68 insertions, 4 deletions
diff --git a/chickadee/graphics/path.scm b/chickadee/graphics/path.scm
index f97ca4a..f6bfcdb 100644
--- a/chickadee/graphics/path.scm
+++ b/chickadee/graphics/path.scm
@@ -1221,9 +1221,74 @@
;;; Rendering
;;;
+(define-vertex-shader stroke-vertex
+ ((in vec2 position)
+ (in vec2 tex)
+ (in float stroke-length)
+ (out vec2 frag-tex)
+ (out float frag-stroke-length)
+ (uniform mat4 mvp)
+ (uniform vec4 color))
+ ;; Short-circuit because the fragments will just be discarded
+ ;; anyway.
+ (if (<= (-> color w) 0.0)
+ (outputs
+ (vertex:position (vec4 0.0 0.0 0.0 1.0)))
+ (outputs
+ (vertex:position (* mvp (vec4 (-> position x) (-> position y) 0.0 1.0)))
+ (frag-tex tex)
+ (frag-stroke-length stroke-length))))
+
+(define-fragment-shader stroke-fragment
+ ((in vec2 frag-tex)
+ (in float frag-stroke-length)
+ (out vec4 frag-color)
+ (uniform vec4 color)
+ (uniform float feather)
+ (uniform int stroke-closed)
+ (uniform float stroke-width)
+ (uniform int stroke-cap)
+ (uniform float stroke-miter-limit))
+ (if (<= (-> color w) 0.0)
+ (outputs)
+ (let* ((infinity (/ 1.0 0.0))
+ (hw (/ stroke-width 2.0))
+ (u (-> frag-tex x))
+ (v (-> frag-tex y))
+ (dx (if (< u 0.0) (abs u) (- u frag-stroke-length)))
+ (dy (abs v))
+ ;; Signed distance function that applies end cap styles.
+ (d (if (or (< u 0.0) (> u frag-stroke-length))
+ (case stroke-cap
+ ((0) ; none
+ infinity)
+ ((1) ; butt (hehe)
+ (max (- (+ dx hw) (* 2.0 feather)) dy))
+ ((2) ; square
+ (max dx dy))
+ ((3) ; round
+ (sqrt (+ (* dx dx) (* dy dy))))
+ ((4) ; triangle out
+ (+ dx dy))
+ ((5) ; triangle in
+ (max dy (- hw (+ feather dx) dy)))
+ (else ; unknown
+ 0.0))
+ dy))
+ (color* (if (<= d hw)
+ color
+ (vec4 (-> color x)
+ (-> color y)
+ (-> color z)
+ (* (-> color w)
+ (- 1.0 (/ (- d hw) feather)))))))
+ (if (<= (-> color w) 0.0)
+ (outputs)
+ (outputs
+ (frag-color color*))))))
+
(define-graphics-variable stroke-shader
- (load-shader (scope-datadir "shaders/path-stroke-vert.glsl")
- (scope-datadir "shaders/path-stroke-frag.glsl")))
+ (compile-shader stroke-vertex stroke-fragment))
(define-vertex-shader fill-vertex
((in vec2 position)
@@ -1258,8 +1323,7 @@
0.0 1.0)))
(mix color end-color t)))))
(if (<= (-> color w) 0.0)
- (outputs
- (frag-color (vec4 1.0 1.0 1.0 1.0)))
+ (outputs)
(outputs
(frag-color
(case mode