diff options
Diffstat (limited to 'chickadee/graphics/path.scm')
-rw-r--r-- | chickadee/graphics/path.scm | 117 |
1 files changed, 61 insertions, 56 deletions
diff --git a/chickadee/graphics/path.scm b/chickadee/graphics/path.scm index 34e7f3c..0ab7131 100644 --- a/chickadee/graphics/path.scm +++ b/chickadee/graphics/path.scm @@ -1,5 +1,5 @@ ;;; Chickadee Game Toolkit -;;; Copyright © 2020 David Thompson <davet@gnu.org> +;;; Copyright © 2020, 2021 David Thompson <davet@gnu.org> ;;; ;;; Chickadee is free software: you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published @@ -24,13 +24,14 @@ (define-module (chickadee graphics path) #:use-module (chickadee array-list) #:use-module (chickadee config) - #:use-module (chickadee graphics) + #:use-module (chickadee graphics buffer) #:use-module (chickadee graphics color) + #:use-module (chickadee graphics engine) #:use-module (chickadee graphics gl) + #:use-module (chickadee graphics multisample) #:use-module (chickadee graphics polygon) #:use-module (chickadee graphics shader) #:use-module (chickadee graphics stencil) - #:use-module (chickadee graphics buffer) #:use-module (chickadee math) #:use-module (chickadee math bezier) #:use-module (chickadee math matrix) @@ -1092,10 +1093,11 @@ ;;; Rendering ;;; -(define path-shader - (delay - (load-shader (scope-datadir "shaders/path-vert.glsl") - (scope-datadir "shaders/path-frag.glsl")))) +(define-graphics-variable path-shader + (load-shader (scope-datadir "shaders/path-vert.glsl") + (scope-datadir "shaders/path-frag.glsl"))) + +(define-graphics-variable mvp-matrix (make-null-matrix4)) (define stencil-flip (make-stencil-test #:on-pass 'invert)) @@ -1105,30 +1107,31 @@ #:function 'not-equal)) (define *debug?* #f) -(define *mvp* (make-null-matrix4)) ;; TODO: gradients (define* (draw-filled-path filled-path matrix) - (let ((counts (filled-path-counts filled-path)) + (let ((shader (graphics-variable-ref path-shader)) + (mvp (graphics-variable-ref mvp-matrix)) + (counts (filled-path-counts filled-path)) (offsets (filled-path-offsets filled-path)) (n (filled-path-count filled-path)) (quad-geometry (filled-path-quad-geometry filled-path)) (stencil-geometry (filled-path-stencil-geometry filled-path))) - (matrix4-mult! *mvp* matrix (current-projection)) + (matrix4-mult! mvp matrix (current-projection)) ;; Wireframe debug mode. (when *debug?* - (with-polygon-mode line-polygon-mode + (with-graphics-state ((polygon-mode line-polygon-mode)) (let loop ((i 0)) (when (< i n) - (gpu-apply* (force path-shader) - (geometry-vertex-array stencil-geometry) - (u32vector-ref offsets i) - (u32vector-ref counts i) - #:mvp (current-projection) - #:mode 0) + (shader-apply* shader + (geometry-vertex-array stencil-geometry) + (u32vector-ref offsets i) + (u32vector-ref counts i) + #:mvp (current-projection) + #:mode 0) (loop (+ i 1)))))) ;; Anti-alias the edges of the fill. - (with-multisample #t + (with-graphics-state ((multisample? #t)) ;; Render fan to stencil buffer. Each time a triangle is ;; rasterized, it flips the values in the stencil buffer for ;; those fragments. So, the first time a triangle is rendered, @@ -1140,51 +1143,53 @@ ;; ;; For more information, see: ;; http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/opengl/gpupathrender.pdf - (with-color-mask null-color-mask - (with-stencil-test stencil-flip - (let loop ((i 0)) - (when (< i n) - (gpu-apply* (force path-shader) - (geometry-vertex-array stencil-geometry) - (u32vector-ref offsets i) - (u32vector-ref counts i) - #:mvp *mvp* - #:mode 0) - (loop (+ i 1)))))) + (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))))) ;; 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. - (with-stencil-test stencil-cover-and-clear - (with-blend-mode (filled-path-blend-mode filled-path) - (gpu-apply (force path-shader) - (geometry-vertex-array quad-geometry) - #:mvp *mvp* - #:mode 0 - #:color (filled-path-color filled-path))))))) + (with-graphics-state ((stencil-test stencil-cover-and-clear) + (blend-mode (filled-path-blend-mode filled-path))) + (shader-apply shader + (geometry-vertex-array quad-geometry) + #:mvp mvp + #:mode 0 + #:color (filled-path-color filled-path)))))) ;; TODO: dashed stroke ;; TODO: miter styles and miter limit (define* (draw-stroked-path stroked-path matrix) - (matrix4-mult! *mvp* matrix (current-projection)) - (with-blend-mode (stroked-path-blend-mode stroked-path) - (let ((geometry (stroked-path-geometry stroked-path))) - (gpu-apply* (force path-shader) - (geometry-vertex-array geometry) - 0 - (geometry-index-count geometry) - #:mvp *mvp* - #:color (stroked-path-color stroked-path) - #:mode 1 - #:feather (stroked-path-feather stroked-path) - #:stroke-cap (match (stroked-path-cap stroked-path) - (#f 0) ; no cap - ('butt 1) - ('square 2) - ('round 3) - ('triangle-out 4) - ('triangle-in 5) - (x (error "unsupported line cap style" x))) - #:stroke-width (stroked-path-width stroked-path))))) + (let ((shader (graphics-variable-ref path-shader)) + (mvp (graphics-variable-ref mvp-matrix))) + (matrix4-mult! mvp matrix (current-projection)) + (with-graphics-state ((blend-mode (stroked-path-blend-mode stroked-path))) + (let ((geometry (stroked-path-geometry stroked-path))) + (shader-apply* shader + (geometry-vertex-array geometry) + 0 + (geometry-index-count geometry) + #:mvp mvp + #:color (stroked-path-color stroked-path) + #:mode 1 + #:feather (stroked-path-feather stroked-path) + #:stroke-cap (match (stroked-path-cap stroked-path) + (#f 0) ; no cap + ('butt 1) + ('square 2) + ('round 3) + ('triangle-out 4) + ('triangle-in 5) + (x (error "unsupported line cap style" x))) + #:stroke-width (stroked-path-width stroked-path)))))) ;;; |