summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am6
-rw-r--r--chickadee/graphics/path.scm22
-rw-r--r--data/shaders/path-fill-frag.glsl17
-rw-r--r--data/shaders/path-fill-vert.glsl22
-rw-r--r--data/shaders/path-frag.glsl93
-rw-r--r--data/shaders/path-stroke-frag.glsl77
-rw-r--r--data/shaders/path-stroke-vert.glsl (renamed from data/shaders/path-vert.glsl)17
7 files changed, 137 insertions, 117 deletions
diff --git a/Makefile.am b/Makefile.am
index 338a009..0c10d13 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -133,8 +133,10 @@ dist_fonts_DATA = \
shadersdir = $(pkgdatadir)/shaders
dist_shaders_DATA = \
- data/shaders/path-vert.glsl \
- data/shaders/path-frag.glsl \
+ data/shaders/path-fill-frag.glsl \
+ data/shaders/path-fill-vert.glsl \
+ data/shaders/path-stroke-frag.glsl \
+ data/shaders/path-stroke-vert.glsl \
data/shaders/pbr-vert.glsl \
data/shaders/pbr-frag.glsl \
data/shaders/phong-vert.glsl \
diff --git a/chickadee/graphics/path.scm b/chickadee/graphics/path.scm
index fb75efd..edce792 100644
--- a/chickadee/graphics/path.scm
+++ b/chickadee/graphics/path.scm
@@ -1087,9 +1087,13 @@
;;; Rendering
;;;
-(define-graphics-variable path-shader
- (load-shader (scope-datadir "shaders/path-vert.glsl")
- (scope-datadir "shaders/path-frag.glsl")))
+(define-graphics-variable stroke-shader
+ (load-shader (scope-datadir "shaders/path-stroke-vert.glsl")
+ (scope-datadir "shaders/path-stroke-frag.glsl")))
+
+(define-graphics-variable fill-shader
+ (load-shader (scope-datadir "shaders/path-fill-vert.glsl")
+ (scope-datadir "shaders/path-fill-frag.glsl")))
(define-graphics-variable mvp-matrix (make-null-matrix4))
@@ -1104,7 +1108,7 @@
;; TODO: gradients
(define* (draw-filled-path filled-path matrix)
- (let ((shader (graphics-variable-ref path-shader))
+ (let ((shader (graphics-variable-ref fill-shader))
(mvp (graphics-variable-ref mvp-matrix))
(counts (filled-path-counts filled-path))
(offsets (filled-path-offsets filled-path))
@@ -1120,8 +1124,7 @@
(geometry-vertex-array stencil-geometry)
(u32vector-ref offsets i)
(u32vector-ref counts i)
- #:mvp (current-projection)
- #:mode 0))))
+ #:mvp (current-projection)))))
;; Anti-alias the edges of the fill.
(with-graphics-state ((g:multisample? #t))
;; Render fan to stencil buffer. Each time a triangle is
@@ -1142,8 +1145,7 @@
(geometry-vertex-array stencil-geometry)
(u32vector-ref offsets i)
(u32vector-ref counts i)
- #:mvp mvp
- #:mode 0)))
+ #:mvp mvp)))
;; 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.
@@ -1152,13 +1154,12 @@
(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)
- (let ((shader (graphics-variable-ref path-shader))
+ (let ((shader (graphics-variable-ref stroke-shader))
(mvp (graphics-variable-ref mvp-matrix)))
(matrix4-mult! mvp matrix (current-projection))
(with-graphics-state ((g:blend-mode (stroked-path-blend-mode stroked-path)))
@@ -1169,7 +1170,6 @@
(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
diff --git a/data/shaders/path-fill-frag.glsl b/data/shaders/path-fill-frag.glsl
new file mode 100644
index 0000000..3af191f
--- /dev/null
+++ b/data/shaders/path-fill-frag.glsl
@@ -0,0 +1,17 @@
+// -*- mode: c -*-
+
+#ifdef GLSL330
+out vec4 fragColor;
+#else
+#define fragColor gl_FragColor
+#endif
+
+uniform vec4 color;
+
+void main(void) {
+ if (color.a <= 0.0) {
+ discard;
+ }
+
+ fragColor = color;
+}
diff --git a/data/shaders/path-fill-vert.glsl b/data/shaders/path-fill-vert.glsl
new file mode 100644
index 0000000..d95b71b
--- /dev/null
+++ b/data/shaders/path-fill-vert.glsl
@@ -0,0 +1,22 @@
+// -*- mode: c -*-
+
+#ifdef GLSL330
+layout (location = 0) in vec2 position;
+#elif defined(GLSL130)
+in vec2 position;
+#elif defined(GLSL120)
+attribute vec2 position;
+#endif
+
+uniform mat4 mvp;
+uniform vec4 color;
+
+void main(void) {
+ // Short-circuit because the fragments will just be discarded
+ // anyway.
+ if (color.a <= 0.0) {
+ gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+ } else {
+ gl_Position = mvp * vec4(position.xy, 0.0, 1.0);
+ }
+}
diff --git a/data/shaders/path-frag.glsl b/data/shaders/path-frag.glsl
deleted file mode 100644
index 0288ae1..0000000
--- a/data/shaders/path-frag.glsl
+++ /dev/null
@@ -1,93 +0,0 @@
-// -*- mode: c -*-
-
-#ifdef GLSL330
-out vec4 fragColor;
-#endif
-
-#ifdef GLSL120
-varying vec2 fragTex;
-varying float fragStrokeLength;
-#else
-in vec2 fragTex;
-in float fragStrokeLength;
-#endif
-
-uniform int mode;
-uniform vec4 color;
-uniform float feather;
-uniform int strokeClosed;
-uniform float strokeWidth;
-uniform int strokeCap;
-uniform int strokeMiterStyle;
-uniform float strokeMiterLimit;
-
-float infinity = 1.0 / 0.0;
-
-void main(void) {
- if (color.a <= 0.0) {
- discard;
- }
-
- // fill mode
- if(mode == 0) {
-#ifdef GLSL330
- fragColor = color;
-#else
- gl_FragColor = color;
-#endif
- } else if(mode == 1) { // stroke mode
- float hw = strokeWidth / 2.0;
- float u = fragTex.x;
- float v = fragTex.y;
- float dx;
- float dy;
- float d;
-
- // Stroke caps.
- if (u < 0 || u > fragStrokeLength) {
- if (u < 0) {
- dx = abs(u);
- } else {
- dx = u - fragStrokeLength;
- }
- dy = abs(v);
-
- if (strokeCap == 0) { // none
- d = infinity;
- } else if (strokeCap == 1) { // butt
- d = max(dx + hw - 2 * feather, dy);
- } else if (strokeCap == 2) { // square
- d = max(dx, dy);
- } else if (strokeCap == 3) { // round
- d = sqrt(dx * dx + dy * dy);
- } else if (strokeCap == 4) { // triangle out
- d = dx + dy;
- } else if (strokeCap == 5) { // triangle in
- d = max(dy, hw - feather + dx - dy);
- }
- // Stroke inner/join
- } else {
- d = abs(v);
- }
-
- if(d <= hw) {
-#ifdef GLSL330
- fragColor = color;
-#else
- gl_FragColor = color;
-#endif
- } else {
- vec4 c = vec4(color.rgb, color.a * (1.0 - ((d - hw) / feather)));
-
- if (c.a <= 0.0) {
- discard;
- }
-
-#ifdef GLSL330
- fragColor = c;
-#else
- gl_FragColor = c;
-#endif
- }
- }
-}
diff --git a/data/shaders/path-stroke-frag.glsl b/data/shaders/path-stroke-frag.glsl
new file mode 100644
index 0000000..9682c8f
--- /dev/null
+++ b/data/shaders/path-stroke-frag.glsl
@@ -0,0 +1,77 @@
+// -*- mode: c -*-
+
+#ifdef GLSL330
+out vec4 fragColor;
+#else
+#define fragColor gl_FragColor
+#endif
+
+#ifdef GLSL120
+varying vec2 fragTex;
+varying float fragStrokeLength;
+#else
+in vec2 fragTex;
+in float fragStrokeLength;
+#endif
+
+uniform vec4 color;
+uniform float feather;
+uniform int strokeClosed;
+uniform float strokeWidth;
+uniform int strokeCap;
+uniform int strokeMiterStyle;
+uniform float strokeMiterLimit;
+
+float infinity = 1.0 / 0.0;
+
+void main(void) {
+ if (color.a <= 0.0) {
+ discard;
+ }
+
+ float hw = strokeWidth / 2.0;
+ float u = fragTex.x;
+ float v = fragTex.y;
+ float dx;
+ float dy;
+ float d;
+
+ // Stroke caps.
+ if (u < 0 || u > fragStrokeLength) {
+ if (u < 0) {
+ dx = abs(u);
+ } else {
+ dx = u - fragStrokeLength;
+ }
+ dy = abs(v);
+
+ if (strokeCap == 0) { // none
+ d = infinity;
+ } else if (strokeCap == 1) { // butt
+ d = max(dx + hw - 2 * feather, dy);
+ } else if (strokeCap == 2) { // square
+ d = max(dx, dy);
+ } else if (strokeCap == 3) { // round
+ d = sqrt(dx * dx + dy * dy);
+ } else if (strokeCap == 4) { // triangle out
+ d = dx + dy;
+ } else if (strokeCap == 5) { // triangle in
+ d = max(dy, hw - feather + dx - dy);
+ }
+ // Stroke inner/join
+ } else {
+ d = abs(v);
+ }
+
+ if(d <= hw) {
+ fragColor = color;
+ } else {
+ vec4 c = vec4(color.rgb, color.a * (1.0 - ((d - hw) / feather)));
+
+ if (c.a <= 0.0) {
+ discard;
+ }
+
+ fragColor = c;
+ }
+}
diff --git a/data/shaders/path-vert.glsl b/data/shaders/path-stroke-vert.glsl
index 38fa5d2..5915010 100644
--- a/data/shaders/path-vert.glsl
+++ b/data/shaders/path-stroke-vert.glsl
@@ -28,17 +28,12 @@ uniform int mode;
uniform int strokeClosed;
void main(void) {
- // Short-circuit because the fragments will just be discarded anyway.
- if (color.a <= 0.0) {
- gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
- return;
- }
-
- // Stroke specific setup.
- if (mode == 1) {
- fragStrokeLength = strokeLength;
- }
-
+ // Short-circuit because the fragments will just be discarded anyway.
+ if (color.a <= 0.0) {
+ gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+ } else {
+ fragStrokeLength = strokeLength;
fragTex = tex;
gl_Position = mvp * vec4(position.xy, 0.0, 1.0);
+ }
}