packages feed

gelatin-shaders (empty) → 0.1.0.0

raw patch · 13 files changed

+1175/−0 lines, 13 filesdep +basedep +bytestringdep +filepathsetup-changed

Dependencies added: base, bytestring, filepath, gelatin

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Schell Scivally (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Schell Scivally nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ gelatin-shaders.cabal view
@@ -0,0 +1,33 @@+name:                gelatin-shaders+version:             0.1.0.0+synopsis:            Gelatin's OpenGL shaders.+description:         Gelatin's OpenGL shaders. Please see README.md+homepage:            https://github.com/schell/gelatin-shaders#readme+license:             BSD3+license-file:        LICENSE+author:              Schell Scivally+maintainer:          schell@zyghost.com+copyright:           Schell Scivally+category:            Web+build-type:          Simple+cabal-version:       >=1.10+data-files:          shaders/*.frag,+                     shaders/*.vert+stability:           experimental++library+  hs-source-dirs:      src+  exposed-modules:     Gelatin.Shaders.Common+                     , Gelatin.Shaders.Simple2D+                     , Gelatin.Shaders.TypeLevel+                     , Gelatin.Shaders+  other-modules:       Paths_gelatin_shaders+  build-depends:       base                  >=4.8  && <4.11+                     , gelatin               >=0.1  && <0.2+                     , bytestring            >=0.10 && <0.11+                     , filepath              >=1.4  && <1.5+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/schell/gelatin-shaders
+ shaders/simple2d.frag view
@@ -0,0 +1,196 @@+#version 330 core++in vec4 fcolor;+in vec2 fuv;+in vec3 fbez;+in vec2 fbezuv;++out vec4 fragColor;++uniform int primitive;+uniform bool hasUV;+uniform sampler2D sampler;+uniform sampler2D mainTex;+uniform sampler2D maskTex;+uniform float thickness;+uniform float feather;+uniform float sumlength;+uniform vec2 cap;+uniform float alpha;+uniform vec4 mult;++uniform vec4 replaceColor;+uniform bool shouldColorReplace;++// Primitive types+const int PrimTri  = 0;+const int PrimBez  = 1;+const int PrimLine = 2;+const int PrimMask = 4;++// Types for rendering line caps+const float CapNone   = 0;+const float CapButt   = 1;+const float CapSquare = 2;+const float CapRound  = 3;+const float CapTriOut = 4;+const float CapTriIn  = 5;++// Colors a fragment based solely on either an input color or a texture.+vec4 coord_fragment(bool isUV,+                    sampler2D s,+                    vec4 clr,+                    vec2 uvs) {+  if (isUV) {+    return texture(s, uvs.st);+  } else {+    return clr;+  }+}++// Colors a fragment using Loop-Blinn curve rendering.+vec4 bez_fragment(bool isUV,+                  sampler2D s,+                  vec3 bz,+                  vec4 clr,+                  vec2 uvs) {+    vec2 p = bz.xy;+    // when cw is true, winding is clockwise and we're drawing outside the+    // curve.+    bool cw = bool(bz.z);+    // gradients+    vec2 px = dFdx(p);+    vec2 py = dFdy(p);+    // chain rule+    float fx = (2*p.x)*px.x - px.y;+    float fy = (2*p.x)*py.x - py.y;+    // signed distance+    float sd = (p.x*p.x - p.y) / sqrt(fx*fx + fy*fy);+    // linear alpha+    float alpha = 0.5 - sd;+    alpha = cw ? 1 - alpha : alpha;+    // find the resulting fragment color+    float a = 0;++    if (alpha > 1) {+        a = 1;+    } else if (alpha < 0) {+        discard;+    } else {+        // we are right on the boundary, interpolate the color intensity.+        a = alpha;+    }++    vec4 color = vec4(0);+    if (isUV) {+        color = texture(s, uvs.st);+    } else {+        color = clr;+    }+    return vec4(color.rgb, color.a * a);+}++// Renders a polyline cap fragment.+float capd(float type, float u, float v, float t ) {+    // None+    if ( type == CapNone) discard;+    // Round+    else if (type == CapRound) return sqrt(u*u+v*v);+    // Triangle out+    else if (type == CapTriOut) return (u+abs(v));+    // Triangle in+    else if (type == CapTriIn) return max(abs(v),(t+u-abs(v)));+    // Square+    else if (type == CapSquare) return max(u,v);+    // Butt+    else if (type == CapButt) return max(u+t,v);+    discard;+}++vec4 line_fragment(float thick,+                   float fthr,+                   float slen,+                   vec2 cp,+                   bool isUV,+                   sampler2D s,+                   vec4 clr,+                   vec2 bzuv,+                   vec2 uvs) {+    float u = bzuv.x;+    float v = bzuv.y;+    float l = slen;+    float dx = abs(min(u, u - l));+    float dy = abs(v);+    float d = dy;++    vec4 color = vec4(0);+    if (isUV) {+        color = texture(s, uvs.st);+    } else {+        color = clr;+    }++    float t = thick/2.0 - fthr;++    if (u < 0) {+        // fragment is in the start cap+        d = capd(cp.x, abs(u), dy, t);+    } else if (u > slen) {+        // fragment is in the end cap+        d = capd(cp.y, u - l, dy, t);+    }++    d -= t;+    if (d < 0.0) {+        return color;+    } else {+        d /= fthr;+        return vec4(color.rgb, exp(-d*d)*color.a);+    }+}++// Colors a fragment using two textures, one the input texture and one as the+// alpha masking texture.+vec4 mask_fragment(sampler2D main,+                   sampler2D mask,+                   vec2 uvs) {+    vec4 color = texture(main, uvs.st);+    vec4 msk  = texture(mask, uvs.st);+    return vec4(color.rgb, color.a * msk.a);+}++// Runs a color op on the fragment.+vec4 color_op_fragment(vec4 c, float a, vec4 m) {+  vec4 c1 = vec4(0);+  if (shouldColorReplace) {+    // Use a replacement color multiplied by the current red channel value.+    c1 = vec4(replaceColor.r, replaceColor.g, replaceColor.b, replaceColor.a * c.r) * m;+  } else {+    c1 = c * m;+  }+  return vec4(c1.rgb, c1.a * a);+}++void main() {+  vec4 out_color = vec4(0);+  switch (primitive) {+    case PrimTri:+      out_color = coord_fragment(hasUV, sampler, fcolor, fuv);+      break;+    case PrimBez:+      out_color = bez_fragment(hasUV, sampler, fbez, fcolor, fuv);+      break;+    case PrimLine: {+      out_color = line_fragment(thickness, feather, sumlength, cap, hasUV,+                                sampler, fcolor, fbezuv, fuv);+      break;+    }+    case PrimMask:+      out_color = mask_fragment(mainTex, maskTex, fuv);+      break;+    default:+      break;+  }++  fragColor = color_op_fragment(out_color, alpha, mult);+}
+ shaders/simple2d.vert view
@@ -0,0 +1,89 @@+#version 330 core++in vec2 position;+in vec4 color;+in vec2 uv;+in vec3 bez;+in vec2 bezuv;+in vec2 next;+in vec2 previous;++out vec4 fcolor;+out vec2 fuv;+out vec3 fbez;+out vec2 fbezuv;++uniform int primitive;+uniform mat4 projection;+uniform mat4 modelview;+uniform bool hasUV;+uniform sampler2D sampler;+uniform sampler2D mainTex;+uniform sampler2D maskTex;+uniform float thickness;++// Primitive types+const int PrimTri  = 0;+const int PrimBez  = 1;+const int PrimLine = 2;+const int PrimMask = 4;++// Projects a polyline segment into screen coordinates.+vec4 project_line(mat4 pj,+                  mat4 mv,+                  float thick,+                  vec2 pos,+                  vec2 bzuv,+                  vec2 nxt,+                  vec2 prev) {+  vec2 a = prev;+  vec2 b = pos;+  vec2 c = nxt;+  vec2 ab = normalize(b - a);+  vec2 bc = normalize(c - b);+  vec2 tangent = normalize(ab + bc);+  vec2 extrusion = vec2(-tangent.y, tangent.x);+  float direction = sign(bzuv.y);+  float len = thick;++  // find the length of the miter line+  vec2 perpab = vec2(-ab.y,ab.x);+  len = len / dot(extrusion, perpab);++  vec2 delta = extrusion * len * direction;+  return pj * mv * vec4(pos + delta, 0.0, 1.0);+}++// Projects a plain point into screen coords.+// Used for alpha masking and "regular" uv mapping and coloring.+vec4 project_position(mat4 pj, mat4 mv, vec2 pos) {+    return pj * mv * vec4(pos.xy, 0.0, 1.0);+}++void main () {+  // Figure out what kind of projection to use.+  vec4 out_position = vec4(0);++  switch (primitive) {+    case PrimTri:+    case PrimBez:+    case PrimMask:+      out_position = project_position(projection, modelview, position);+      break;++    case PrimLine: {+      out_position = project_line(projection, modelview, thickness, position,+                                  bezuv, next, previous);+      break;+    }+    default:+    out_position = project_position(projection, modelview, position);+  }++  fcolor = color;+  fuv = uv;+  fbez = bez;+  fbezuv = bezuv;++  gl_Position = out_position;+}
+ shaders/simple2dwebgl.frag view
@@ -0,0 +1,193 @@+#extension GL_OES_standard_derivatives : enable++precision highp float;+precision highp int;++varying vec4 fcolor;+varying vec2 fuv;+varying vec3 fbez;+varying vec2 fbezuv;++uniform int primitive;+uniform bool hasUV;+uniform sampler2D sampler;+uniform sampler2D mainTex;+uniform sampler2D maskTex;+uniform float thickness;+uniform float feather;+uniform float sumlength;+uniform vec2 cap;+uniform float alpha;+uniform vec4 mult;++uniform vec4 replaceColor;+uniform bool shouldColorReplace;++// Primitive types+const int PrimTri  = 0;+const int PrimBez  = 1;+const int PrimLine = 2;+const int PrimMask = 4;++// Types for rendering line caps+const float CapNone   = 0.0;+const float CapButt   = 1.0;+const float CapSquare = 2.0;+const float CapRound  = 3.0;+const float CapTriOut = 4.0;+const float CapTriIn  = 5.0;++// Colors a fragment based solely on either an input color or a texture.+vec4 coord_fragment(bool isUV,+                    sampler2D s,+                    vec4 clr,+                    vec2 uvs) {+  if (isUV) {+    return texture2D(s, uvs.st);+  } else {+    return clr;+  }+}++// Colors a fragment using Loop-Blinn curve rendering.+vec4 bez_fragment(bool isUV,+                  sampler2D s,+                  vec3 bz,+                  vec4 clr,+                  vec2 uvs) {+    vec2 p = bz.xy;+    // when cw is true, winding is clockwise and we're drawing outside the+    // curve.+    bool cw = bool(bz.z);+    // gradients+    vec2 px = dFdx(p);+    vec2 py = dFdy(p);+    // chain rule+    float fx = (2.0*p.x)*px.x - px.y;+    float fy = (2.0*p.x)*py.x - py.y;+    // signed distance+    float sd = (p.x*p.x - p.y) / sqrt(fx*fx + fy*fy);+    // linear alpha+    float alpha = 0.5 - sd;+    alpha = cw ? 1.0 - alpha : alpha;+    // find the resulting fragment color+    float a = 0.0;++    if (alpha > 1.0) {+      a = 1.0;+    } else if (alpha < 0.0) {+      discard;+    } else {+      // we are right on the boundary, interpolate the color intensity.+      a = alpha;+    }++    vec4 color = vec4(0);+    if (isUV) {+      color = texture2D(s, uvs.st);+    } else {+      color = clr;+    }+    return vec4(color.rgb, color.a * a);+}++// Renders a polyline cap fragment.+float capd(float type, float u, float v, float t ) {+    // None+    if ( type == CapNone) discard;+    // Round+    else if (type == CapRound) return sqrt(u*u+v*v);+    // Triangle out+    else if (type == CapTriOut) return (u+abs(v));+    // Triangle in+    else if (type == CapTriIn) return max(abs(v),(t+u-abs(v)));+    // Square+    else if (type == CapSquare) return max(u,v);+    // Butt+    else if (type == CapButt) return max(u+t,v);+    discard;+}++vec4 line_fragment(float thick,+                   float fthr,+                   float slen,+                   vec2 cp,+                   bool isUV,+                   sampler2D s,+                   vec4 clr,+                   vec2 bzuv,+                   vec2 uvs) {+    float u = bzuv.x;+    float v = bzuv.y;+    float l = slen;+    float dx = abs(min(u, u - l));+    float dy = abs(v);+    float d = dy;++    vec4 color = vec4(0);+    if (isUV) {+        color = texture2D(s, uvs.st);+    } else {+        color = clr;+    }++    float t = thick/2.0 - fthr;++    if (u < 0.0) {+        // fragment is in the start cap+        d = capd(cp.x, abs(u), dy, t);+    } else if (u > slen) {+        // fragment is in the end cap+        d = capd(cp.y, u - l, dy, t);+    }++    d -= t;+    if (d < 0.0) {+        return color;+    } else {+        d /= fthr;+        return vec4(color.rgb, exp(-d*d)*color.a);+    }+}++// Colors a fragment using two textures, one the input texture and one as the+// alpha masking texture.+vec4 mask_fragment(sampler2D main,+                   sampler2D mask,+                   vec2 uvs) {+    vec4 color = texture2D(main, uvs.st);+    vec4 msk  = texture2D(mask, uvs.st);+    return vec4(color.rgb, color.a * msk.a);+}++// Runs a color op on the fragment.+vec4 color_op_fragment(vec4 c, float a, vec4 m) {+  vec4 c1 = vec4(0);+  if (shouldColorReplace) {+    // Use a replacement color multiplied by the current red channel value.+    c1 = vec4(replaceColor.r, replaceColor.g, replaceColor.b, replaceColor.a * c.r) * m;+  } else {+    c1 = c * m;+  }+  return vec4(c1.rgb, c1.a * a);+}++void main() {+  vec4 out_color = vec4(0);+  if (primitive == PrimTri) {+      out_color = coord_fragment(hasUV, sampler, fcolor, fuv);+  }+  if (primitive == PrimBez) {+      out_color = bez_fragment(hasUV, sampler, fbez, fcolor, fuv);++  }+  if (primitive == PrimLine) {+      out_color = line_fragment(thickness, feather, sumlength, cap, hasUV,+                                sampler, fcolor, fbezuv, fuv);+  }+  if (primitive == PrimMask) {+      out_color = mask_fragment(mainTex, maskTex, fuv);+  }++  gl_FragColor = color_op_fragment(out_color, alpha, mult);+}
+ shaders/simple2dwebgl.vert view
@@ -0,0 +1,83 @@+precision highp float;+precision highp int;++attribute vec2 position;+attribute vec4 color;+attribute vec2 uv;+attribute vec3 bez;+attribute vec2 bezuv;+attribute vec2 next;+attribute vec2 previous;++varying vec4 fcolor;+varying vec2 fuv;+varying vec3 fbez;+varying vec2 fbezuv;++uniform int primitive;+uniform mat4 projection;+uniform mat4 modelview;+uniform bool hasUV;+uniform sampler2D sampler;+uniform sampler2D mainTex;+uniform sampler2D maskTex;+uniform float thickness;++// Primitive types+const int PrimTri  = 0;+const int PrimBez  = 1;+const int PrimLine = 2;+const int PrimMask = 4;++// Projects a polyline segment into screen coordinates.+vec4 project_line(mat4 pj,+                  mat4 mv,+                  float thick,+                  vec2 pos,+                  vec2 bzuv,+                  vec2 nxt,+                  vec2 prev) {+  vec2 a = prev;+  vec2 b = pos;+  vec2 c = nxt;+  vec2 ab = normalize(b - a);+  vec2 bc = normalize(c - b);+  vec2 tangent = normalize(ab + bc);+  vec2 extrusion = vec2(-tangent.y, tangent.x);+  float direction = sign(bzuv.y);+  float len = thick;++  // find the length of the miter line+  vec2 perpab = vec2(-ab.y,ab.x);+  len = len / dot(extrusion, perpab);++  vec2 delta = extrusion * len * direction;+  return pj * mv * vec4(pos + delta, 0.0, 1.0);+}++// Projects a plain point into screen coords.+// Used for alpha masking and "regular" uv mapping and coloring.+vec4 project_position(mat4 pj, mat4 mv, vec2 pos) {+    return pj * mv * vec4(pos.xy, 0.0, 1.0);+}++void main () {+  // Figure out what kind of projection to use.+  vec4 out_position = vec4(0);++  if (primitive == PrimTri || primitive == PrimBez || primitive == PrimMask) {+    out_position = project_position(projection, modelview, position);+  } else if (primitive == PrimLine) {+    out_position = project_line(projection, modelview, thickness, position,+                                bezuv, next, previous);+  } else {+    out_position = project_position(projection, modelview, position);+  }++  fcolor = color;+  fuv = uv;+  fbez = bez;+  fbezuv = bezuv;++  gl_Position = out_position;+}
+ shaders/simple3d.frag view
@@ -0,0 +1,196 @@+#version 300 core++in vec4 fcolor;+in vec2 fuv;+in vec3 fbez;+in vec2 fbezuv;++out vec4 fragColor;++uniform int primitive;+uniform bool hasUV;+uniform sampler2D sampler;+uniform sampler2D mainTex;+uniform sampler2D maskTex;+uniform float thickness;+uniform float feather;+uniform float sumlength;+uniform vec2 cap;+uniform float alpha;+uniform vec4 mult;++uniform vec4 replaceColor;+uniform bool shouldColorReplace;++// Primitive types+const int PrimTri  = 0;+const int PrimBez  = 1;+const int PrimLine = 2;+const int PrimMask = 4;++// Types for rendering line caps+const float CapNone   = 0;+const float CapButt   = 1;+const float CapSquare = 2;+const float CapRound  = 3;+const float CapTriOut = 4;+const float CapTriIn  = 5;++// Colors a fragment based solely on either an input color or a texture.+vec4 coord_fragment(bool isUV,+                    sampler2D s,+                    vec4 clr,+                    vec2 uvs) {+  if (isUV) {+    return texture(s, uvs.st);+  } else {+    return clr;+  }+}++// Colors a fragment using Loop-Blinn curve rendering.+vec4 bez_fragment(bool isUV,+                  sampler2D s,+                  vec3 bz,+                  vec4 clr,+                  vec2 uvs) {+    vec2 p = bz.xy;+    // when cw is true, winding is clockwise and we're drawing outside the+    // curve.+    bool cw = bool(bz.z);+    // gradients+    vec2 px = dFdx(p);+    vec2 py = dFdy(p);+    // chain rule+    float fx = (2*p.x)*px.x - px.y;+    float fy = (2*p.x)*py.x - py.y;+    // signed distance+    float sd = (p.x*p.x - p.y) / sqrt(fx*fx + fy*fy);+    // linear alpha+    float alpha = 0.5 - sd;+    alpha = cw ? 1 - alpha : alpha;+    // find the resulting fragment color+    float a = 0;++    if (alpha > 1) {+        a = 1;+    } else if (alpha < 0) {+        discard;+    } else {+        // we are right on the boundary, interpolate the color intensity.+        a = alpha;+    }++    vec4 color = vec4(0);+    if (isUV) {+        color = texture(s, uvs.st);+    } else {+        color = clr;+    }+    return vec4(color.rgb, color.a * a);+}++// Renders a polyline cap fragment.+float capd(float type, float u, float v, float t ) {+    // None+    if ( type == CapNone) discard;+    // Round+    else if (type == CapRound) return sqrt(u*u+v*v);+    // Triangle out+    else if (type == CapTriOut) return (u+abs(v));+    // Triangle in+    else if (type == CapTriIn) return max(abs(v),(t+u-abs(v)));+    // Square+    else if (type == CapSquare) return max(u,v);+    // Butt+    else if (type == CapButt) return max(u+t,v);+    discard;+}++vec4 line_fragment(float thick,+                   float fthr,+                   float slen,+                   vec2 cp,+                   bool isUV,+                   sampler2D s,+                   vec4 clr,+                   vec2 bzuv,+                   vec2 uvs) {+    float u = bzuv.x;+    float v = bzuv.y;+    float l = slen;+    float dx = abs(min(u, u - l));+    float dy = abs(v);+    float d = dy;++    vec4 color = vec4(0);+    if (isUV) {+        color = texture(s, uvs.st);+    } else {+        color = clr;+    }++    float t = thick/2.0 - fthr;++    if (u < 0) {+        // fragment is in the start cap+        d = capd(cp.x, abs(u), dy, t);+    } else if (u > slen) {+        // fragment is in the end cap+        d = capd(cp.y, u - l, dy, t);+    }++    d -= t;+    if (d < 0.0) {+        return color;+    } else {+        d /= fthr;+        return vec4(color.rgb, exp(-d*d)*color.a);+    }+}++// Colors a fragment using two textures, one the input texture and one as the+// alpha masking texture.+vec4 mask_fragment(sampler2D main,+                   sampler2D mask,+                   vec2 uvs) {+    vec4 color = texture(main, uvs.st);+    vec4 msk  = texture(mask, uvs.st);+    return vec4(color.rgb, color.a * msk.a);+}++// Runs a color op on the fragment.+vec4 color_op_fragment(vec4 c, float a, vec4 m) {+  vec4 c1 = vec4(0);+  if (shouldColorReplace) {+    // Use a replacement color multiplied by the current red channel value.+    c1 = vec4(replaceColor.r, replaceColor.g, replaceColor.b, replaceColor.a * c.r) * m;+  } else {+    c1 = c * m;+  }+  return vec4(c1.rgb, c1.a * a);+}++void main() {+  vec4 out_color = vec4(0);+  switch (primitive) {+    case PrimTri:+      out_color = coord_fragment(hasUV, sampler, fcolor, fuv);+      break;+    case PrimBez:+      out_color = bez_fragment(hasUV, sampler, fbez, fcolor, fuv);+      break;+    case PrimLine: {+      out_color = line_fragment(thickness, feather, sumlength, cap, hasUV,+                                sampler, fcolor, fbezuv, fuv);+      break;+    }+    case PrimMask:+      out_color = mask_fragment(mainTex, maskTex, fuv);+      break;+    default:+      break;+  }++  fragColor = color_op_fragment(out_color, alpha, mult);+}
+ shaders/simple3d.vert view
@@ -0,0 +1,89 @@+#version 300 core++in vec3 position;+in vec4 color;+in vec2 uv;+in vec3 bez;+in vec2 bezuv;+in vec3 next;+in vec3 previous;++out vec4 fcolor;+out vec2 fuv;+out vec3 fbez;+out vec2 fbezuv;++uniform int primitive;+uniform mat4 projection;+uniform mat4 modelview;+uniform bool hasUV;+uniform sampler2D sampler;+uniform sampler2D mainTex;+uniform sampler2D maskTex;+uniform float thickness;++// Primitive types+const int PrimTri  = 0;+const int PrimBez  = 1;+const int PrimLine = 2;+const int PrimMask = 4;++// Projects a polyline segment into screen coordinates.+vec4 project_line(mat4 pj,+                  mat4 mv,+                  float thick,+                  vec3 pos,+                  vec2 bzuv,+                  vec2 nxt,+                  vec2 prev) {+  vec3 a = prev;+  vec3 b = pos;+  vec3 c = nxt;+  vec3 ab = normalize(b - a);+  vec3 bc = normalize(c - b);+  vec3 tangent = normalize(ab + bc);+  vec3 extrusion = vec2(-tangent.y, tangent.x);+  float direction = sign(bzuv.y);+  float len = thick;++  // find the length of the miter line+  vec2 perpab = vec2(-ab.y,ab.x);+  len = len / dot(extrusion, perpab);++  vec2 delta = extrusion * len * direction;+  return pj * mv * vec4(pos + delta, 0.0, 1.0);+}++// Projects a plain point into screen coords.+// Used for alpha masking and "regular" uv mapping and coloring.+vec4 project_position(mat4 pj, mat4 mv, vec2 pos) {+    return pj * mv * vec4(pos.xy, 0.0, 1.0);+}++void main () {+  // Figure out what kind of projection to use.+  vec4 out_position = vec4(0);++  switch (primitive) {+    case PrimTri:+    case PrimBez:+    case PrimMask:+      out_position = project_position(projection, modelview, position);+      break;++    case PrimLine: {+      out_position = project_line(projection, modelview, thickness, position,+                                  bezuv, next, previous);+      break;+    }+    default:+    out_position = project_position(projection, modelview, position);+  }++  fcolor = color;+  fuv = uv;+  fbez = bez;+  fbezuv = bezuv;++  gl_Position = out_position;+}
+ src/Gelatin/Shaders.hs view
@@ -0,0 +1,25 @@+module Gelatin.Shaders+  ( module S+  , simple2dVertFilePath+  , simple2dFragFilePath+  , simple2dVertWebGLFilePath+  , simple2dFragWebGLFilePath+  ) where++import           Gelatin.Shaders.Common    as S+import           Gelatin.Shaders.Simple2D  as S+import           Gelatin.Shaders.TypeLevel as S+import           Paths_gelatin_shaders     as S+import           System.FilePath++simple2dVertFilePath :: IO FilePath+simple2dVertFilePath = getDataFileName $ "shaders" </> "simple2d.vert"++simple2dFragFilePath :: IO FilePath+simple2dFragFilePath = getDataFileName $ "shaders" </> "simple2d.frag"++simple2dVertWebGLFilePath :: IO FilePath+simple2dVertWebGLFilePath = getDataFileName $ "shaders" </> "simple2dwebgl.vert"++simple2dFragWebGLFilePath :: IO FilePath+simple2dFragWebGLFilePath = getDataFileName $ "shaders" </> "simple2dwebgl.frag"
+ src/Gelatin/Shaders/Common.hs view
@@ -0,0 +1,93 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}+{-# LANGUAGE TypeSynonymInstances  #-}+module Gelatin.Shaders.Common+  ( VertexShader+  , FragmentShader+  , Uniform+  , Attribute+  , AttributeToggling(..)+  , AttributeBuffering(..)+  , IsShaderType(..)+  , ShaderSteps(..)+  ) where++import           Data.Proxy                (Proxy (..))+--------------------------------------------------------------------------------+import           Gelatin.Shaders.TypeLevel+--------------------------------------------------------------------------------+-- $shader Defining shaders using (mostly) just types+--------------------------------------------------------------------------------+data VertexShader+data FragmentShader++data ShaderType = ShaderTypeVertex | ShaderTypeFragment++class IsShaderType a b where+  getShaderType :: Proxy a -> b++instance IsShaderType VertexShader ShaderType where+  getShaderType _ = ShaderTypeVertex++instance IsShaderType FragmentShader ShaderType where+  getShaderType _ = ShaderTypeFragment++instance (IsShaderType t b, IsShaderType ts [b])+  => IsShaderType (t ': ts) [b] where+  getShaderType _ = getShaderType (Proxy :: Proxy t) : getShaderType (Proxy :: Proxy ts)++instance IsShaderType '[] [x] where+  getShaderType _ = []++-- | A glsl uniform type.+data Uniform name val++instance GetLits name String => GetLits (Uniform name val) String where+  getSymbols _ = getSymbols (Proxy :: Proxy name)++-- | A glsl attribute type.+data Attribute name val loc++instance (GetLits name String, GetLits loc Integer)+  => GetLits (Attribute name val loc) (String, Integer) where+  getSymbols _ =+    let name  = getSymbols (Proxy :: Proxy name)+        loc   = getSymbols (Proxy :: Proxy loc)+    in (name, loc)++-- | Used to resolve typeclass instances for generating enable/disable attribute+-- functions.+data AttributeToggling a++-- | Used to resolve typeclass instances for generating attribute buffering+-- functions.+data AttributeBuffering a++-- | A shader step is a step in the shader compilation process. This means that+-- `ShaderSteps '[VertexShader, FragmentShader] [ByteString]` is a list of+-- vertex and fragment shader source code that needs to be compiled.+-- `ShaderSteps '[VertexShader, FragmentShader] GLuint` most likely means a list+-- of vertex and fragment shaders that need to be linked.+data ShaderSteps t v = ShaderSteps { unShaderSteps :: [v] }++-- | This is some future work in progress.+class MonadShader a where+  data M a :: * -> *++  data Program a+  readProgram :: (M a) (Program a)++  data Uniforms a+  updateUniforms :: Uniforms a -> (M a) ()++  data Attributes a+  enableAttributes  :: Attributes a -> (M a) ()+  disableAttributes :: Attributes a -> (M a) ()+  bufferAttributes  :: Attributes a -> (M a) ()
+ src/Gelatin/Shaders/Simple2D.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE DataKinds     #-}+{-# LANGUAGE TypeOperators #-}+module Gelatin.Shaders.Simple2D where++import           Gelatin++import           Gelatin.Shaders.Common+import           Gelatin.Shaders.TypeLevel++-- | TODO: Most of this stuff is shader specific and shoud be moved to a+-- different part of the repo.++--------------------------------------------------------------------------------+-- $layout+-- Attributes layout locations are unique and global.+--------------------------------------------------------------------------------+type APosition = Attribute "position" (V2 Float) 0+type AColor    = Attribute "color"    (V4 Float) 1+type AUV       = Attribute "uv"       (V2 Float) 2+type ABez      = Attribute "bez"      (V3 Float) 3+type ABezUV    = Attribute "bezuv"    (V2 Float) 4+type APrev     = Attribute "prev"     (V2 Float) 5+type ANext     = Attribute "next"     (V2 Float) 6++type Simple2DAttribs = '[APosition, AColor, AUV, ABez, ABezUV, APrev, ANext]+type Simple2DAttribToggles = TypeMap AttributeToggling Simple2DAttribs+type Simple2DAttribBuffers = TypeMap AttributeBuffering Simple2DAttribs++--------------------------------------------------------------------------------+-- $uniforms+-- Uniform Helper Types+--------------------------------------------------------------------------------+data PrimType = PrimTri+              | PrimBez+              | PrimLine+              | PrimMask+              deriving (Show, Eq, Enum, Ord, Bounded)+--------------------------------------------------------------------------------+-- Updating uniforms+--------------------------------------------------------------------------------+type UPrimType           = Uniform "primitive"          PrimType+type UProjection         = Uniform "projection"         (M44 Float)+type UModelView          = Uniform "modelview"          (M44 Float)+type UThickness          = Uniform "thickness"          Float+type UFeather            = Uniform "feather"            Float+type USumLength          = Uniform "sumlength"          Float+type ULineCaps           = Uniform "cap"                (LineCap,LineCap)+type UHasUV              = Uniform "hasUV"              Bool+type USampler            = Uniform "sampler"            Int+type UMainTex            = Uniform "mainTex"            Int+type UMaskTex            = Uniform "maskTex"            Int+type UAlpha              = Uniform "alpha"              Float+type UMult               = Uniform "mult"               (V4 Float)+type UShouldReplaceColor = Uniform "shouldColorReplace" Bool+type UReplaceColor       = Uniform "replaceColor"       (V4 Float)++type Simple2DUniforms = '[ UPrimType+                         , UProjection+                         , UModelView+                         , UThickness+                         , UFeather+                         , USumLength+                         , ULineCaps+                         , UHasUV+                         , USampler+                         , UMainTex+                         , UMaskTex+                         , UAlpha+                         , UMult+                         , UShouldReplaceColor+                         , UReplaceColor+                         ]++type Simple2DShaders = '[VertexShader, FragmentShader]
+ src/Gelatin/Shaders/TypeLevel.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-}++module Gelatin.Shaders.TypeLevel+  ( -- * Type level combinators+    (:&)(..)+    -- * Generating symbol values on type lists+  , GetLits(..)+    -- * Generating function class+  , HasGenFunc(..)+    -- * Mapping types+  , TypeMap+  ) where++import           Data.Proxy   (Proxy (..))+import           GHC.TypeLits (KnownNat, KnownSymbol, natVal, symbolVal)+--------------------------------------------------------------------------------+-- Type level combinators+--------------------------------------------------------------------------------+-- | A heterogenious list.+data a :& b = a :& b+infixr 8 :&++class GetLits a t where+  getSymbols :: Proxy a -> t++instance GetLits '[] [t] where+  getSymbols _ = []++instance (GetLits a t, GetLits as [t]) => GetLits (a ': as) [t] where+  getSymbols _ = getSymbols (Proxy :: Proxy a) : getSymbols (Proxy :: Proxy as)++instance KnownSymbol a => GetLits a String where+  getSymbols = symbolVal++instance KnownNat a => GetLits a Integer where+  getSymbols = natVal+--------------------------------------------------------------------------------+-- Generating a function from a type+--------------------------------------------------------------------------------+class HasGenFunc a where+  type GenFunc a  :: *+  genFunction :: Proxy a -> GenFunc a++instance (HasGenFunc a, HasGenFunc b) => HasGenFunc (a :& b) where+  type GenFunc (a :& b) = GenFunc a :& GenFunc b+  genFunction _ =+    let a = (Proxy :: Proxy a)+        b = (Proxy :: Proxy b)+    in genFunction a :& genFunction b++instance HasGenFunc '[] where+  type GenFunc '[] = ()+  genFunction _ = ()++instance (HasGenFunc a, HasGenFunc as) => HasGenFunc (a ': as) where+  type GenFunc (a ': as) = GenFunc a :& GenFunc as+  genFunction _ =+    let a  = (Proxy :: Proxy a)+        as = (Proxy :: Proxy as)+    in genFunction a :& genFunction as++type family TypeMap (a :: * -> *) (xs :: [*]) :: [*]+type instance TypeMap t '[] = '[]+type instance TypeMap t (x ': xs) = t x ': TypeMap t xs