diff options
Diffstat (limited to 'chickadee/graphics/path.scm')
-rw-r--r-- | chickadee/graphics/path.scm | 86 |
1 files changed, 37 insertions, 49 deletions
diff --git a/chickadee/graphics/path.scm b/chickadee/graphics/path.scm index 0ab7131..978f3ab 100644 --- a/chickadee/graphics/path.scm +++ b/chickadee/graphics/path.scm @@ -37,6 +37,7 @@ #:use-module (chickadee math matrix) #:use-module (chickadee math rect) #:use-module (chickadee math vector) + #:use-module (chickadee utils) #:use-module (gl) #:use-module (ice-9 match) #:use-module ((rnrs base) #:select (mod)) @@ -1038,42 +1039,33 @@ (set-filled-path-count! filled-path path-count) ;; TODO: Don't allocate each time. (let ((bv (make-u32vector path-count))) - (let loop ((i 0)) - (when (< i path-count) - (u32vector-set! bv i (+ (u32vector-ref counts i) 1)) - (loop (+ i 1)))) + (for-range ((i path-count)) + (u32vector-set! bv i (+ (u32vector-ref counts i) 1))) (set-filled-path-counts! filled-path bv)) (let ((bv (make-u32vector path-count))) - (let loop ((i 0)) - (when (< i path-count) - (u32vector-set! bv i (+ (u32vector-ref offsets i) i)) - (loop (+ i 1)))) + (for-range ((i path-count)) + (u32vector-set! bv i (+ (u32vector-ref offsets i) i))) (set-filled-path-offsets! filled-path bv)) ;; Create geometry for the stencil buffer. (geometry-begin! stencil-geometry) - (let loop ((i 0)) - (when (< i path-count) - (let* ((count (u32vector-ref counts i)) - (first (u32vector-ref offsets i)) - (last (+ first count -1))) - ;; Build the triangle fan for the path. This geometry - ;; will be used for a GPU-based implementation of the - ;; non-zero rule: - ;; - ;; See: https://en.wikipedia.org/wiki/Nonzero-rule - ;; - ;; Add reference point as the basis for each triangle in - ;; the fan. - (fill-vertex-append! stencil-geometry (ref-x ref-y)) - ;; Now simply copy all the points in the path into the - ;; buffer. - (let inner ((i first)) - (when (<= i last) - (fill-vertex-append! stencil-geometry - ((f32vector-ref points (* i 2)) - (f32vector-ref points (+ (* i 2) 1)))) - (inner (+ i 1))))) - (loop (+ i 1)))) + (for-range ((i path-count)) + (let* ((count (u32vector-ref counts i)) + (first (u32vector-ref offsets i))) + ;; Build the triangle fan for the path. This geometry + ;; will be used for a GPU-based implementation of the + ;; non-zero rule: + ;; + ;; See: https://en.wikipedia.org/wiki/Nonzero-rule + ;; + ;; Add reference point as the basis for each triangle in + ;; the fan. + (fill-vertex-append! stencil-geometry (ref-x ref-y)) + ;; Now simply copy all the points in the path into the + ;; buffer. + (for-range ((j (+ first count) first)) + (fill-vertex-append! stencil-geometry + ((f32vector-ref points (* j 2)) + (f32vector-ref points (+ (* j 2) 1))))))) (geometry-end! stencil-geometry) ;; Create simple quad covering the bounding box to be used for the ;; final render pass with stencil applied. @@ -1121,15 +1113,13 @@ ;; Wireframe debug mode. (when *debug?* (with-graphics-state ((polygon-mode line-polygon-mode)) - (let loop ((i 0)) - (when (< i n) - (shader-apply* shader - (geometry-vertex-array stencil-geometry) - (u32vector-ref offsets i) - (u32vector-ref counts i) - #:mvp (current-projection) - #:mode 0) - (loop (+ i 1)))))) + (for-range ((i n)) + (shader-apply* shader + (geometry-vertex-array stencil-geometry) + (u32vector-ref offsets i) + (u32vector-ref counts i) + #:mvp (current-projection) + #:mode 0)))) ;; Anti-alias the edges of the fill. (with-graphics-state ((multisample? #t)) ;; Render fan to stencil buffer. Each time a triangle is @@ -1145,15 +1135,13 @@ ;; http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/opengl/gpupathrender.pdf (with-graphics-state ((color-mask null-color-mask) (stencil-test stencil-flip)) - (let loop ((i 0)) - (when (< i n) - (shader-apply* shader - (geometry-vertex-array stencil-geometry) - (u32vector-ref offsets i) - (u32vector-ref counts i) - #:mvp mvp - #:mode 0) - (loop (+ i 1))))) + (for-range ((i n)) + (shader-apply* shader + (geometry-vertex-array stencil-geometry) + (u32vector-ref offsets i) + (u32vector-ref counts i) + #:mvp mvp + #:mode 0))) ;; Render a quad with the stencil applied. The quad is the size ;; of the path's bounding box. The stencil test will make it so ;; we only draw fragments that are part of the filled path. |