From 9a5ef19d5971488de18539eaf68e35bf590a4c5e Mon Sep 17 00:00:00 2001 From: David Thompson Date: Fri, 28 Aug 2020 07:16:51 -0400 Subject: render: Add vector path rendering module. --- data/shaders/path-frag.glsl | 93 +++++++++++++++++++++++++++++++++++++++++++++ data/shaders/path-vert.glsl | 44 +++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 data/shaders/path-frag.glsl create mode 100644 data/shaders/path-vert.glsl (limited to 'data/shaders') diff --git a/data/shaders/path-frag.glsl b/data/shaders/path-frag.glsl new file mode 100644 index 0000000..a38f1d0 --- /dev/null +++ b/data/shaders/path-frag.glsl @@ -0,0 +1,93 @@ +// -*- mode: c -*- + +#ifdef GLSL330 +out vec4 fragColor; +#endif + +#ifdef GLSL120 +attribute vec2 fragTex; +attribute 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-vert.glsl b/data/shaders/path-vert.glsl new file mode 100644 index 0000000..38fa5d2 --- /dev/null +++ b/data/shaders/path-vert.glsl @@ -0,0 +1,44 @@ +// -*- mode: c -*- + +#ifdef GLSL330 +layout (location = 0) in vec2 position; +layout (location = 1) in vec2 tex; +layout (location = 2) in float strokeLength; +#elif defined(GLSL130) +in vec2 position; +in vec2 tex; +in float strokeLength; +#elif defined(GLSL120) +attribute vec2 position; +attribute vec2 tex; +attribute float strokeLength; +#endif + +#ifdef GLSL120 +varying vec2 fragTex; +varying float fragStrokeLength; +#else +out vec2 fragTex; +out float fragStrokeLength; +#endif + +uniform mat4 mvp; +uniform vec4 color; +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; + } + + fragTex = tex; + gl_Position = mvp * vec4(position.xy, 0.0, 1.0); +} -- cgit v1.2.3