faros initial commit
authorEleni Maria Stea <estea@igalia.com>
Mon, 1 Oct 2018 13:42:01 +0000 (16:42 +0300)
committerEleni Maria Stea <estea@igalia.com>
Mon, 1 Oct 2018 13:42:01 +0000 (16:42 +0300)
22 files changed:
Makefile [new file with mode: 0644]
glsl-noise/LICENSE [new file with mode: 0644]
glsl-noise/README.md [new file with mode: 0644]
glsl-noise/classic/2d.glsl [new file with mode: 0644]
glsl-noise/classic/3d.glsl [new file with mode: 0644]
glsl-noise/classic/4d.glsl [new file with mode: 0644]
glsl-noise/package.json [new file with mode: 0644]
glsl-noise/periodic/2d.glsl [new file with mode: 0644]
glsl-noise/periodic/3d.glsl [new file with mode: 0644]
glsl-noise/periodic/4d.glsl [new file with mode: 0644]
glsl-noise/simplex/2d.glsl [new file with mode: 0644]
glsl-noise/simplex/3d.glsl [new file with mode: 0644]
glsl-noise/simplex/4d.glsl [new file with mode: 0644]
sdr/beam.f.glsl [new file with mode: 0644]
sdr/beam.v.glsl [new file with mode: 0644]
sdr/curve_top.f.glsl [new file with mode: 0644]
sdr/curve_top.v.glsl [new file with mode: 0644]
sdr/sky.f.glsl [new file with mode: 0644]
sdr/sky.v.glsl [new file with mode: 0644]
src/main.cc [new file with mode: 0644]
src/sdr.c [new file with mode: 0644]
src/sdr.h [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..a78774d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,28 @@
+
+src = $(wildcard src/*.cc)
+c_src = $(wildcard src/*.c)
+obj = $(src:.cc=.o) $(c_src:.c=.o)
+dep = $(obj:.o=.d)
+bin = faros
+
+dbg = -g
+opt = -O0
+inc = -Isrc -Isrc/shaders -Isrc/math
+
+CXX = g++
+CC = gcc
+CXXFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc)
+CFLAGS = $(CXXFLAGS)
+LDFLAGS = -lGL -lGLU -lglut -lGLEW -limago -lassimp
+
+$(bin): $(obj)
+       $(CXX) -o $@ $(obj) $(LDFLAGS)
+
+-include $(dep)
+
+%.d: %.cc
+       @$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@
+
+.PHONY: clean
+clean:
+       rm -f $(obj) $(bin) $(dep)
diff --git a/glsl-noise/LICENSE b/glsl-noise/LICENSE
new file mode 100644 (file)
index 0000000..001a9e5
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (C) 2011 by Ashima Arts (Simplex noise)
+Copyright (C) 2011 by Stefan Gustavson (Classic noise)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/glsl-noise/README.md b/glsl-noise/README.md
new file mode 100644 (file)
index 0000000..e802225
--- /dev/null
@@ -0,0 +1,30 @@
+# glsl-noise [![frozen](http://hughsk.github.io/stability-badges/dist/frozen.svg)](http://github.com/hughsk/stability-badges) #
+
+[webgl-noise](http://github.com/ashima/webgl-noise) ported to an NPM package
+so that you can require it from
+[glslify](http://github.com/chrisdickinson/glslify).
+
+[![glsl-noise](https://nodei.co/npm/glsl-noise.png?mini=true)](https://nodei.co/npm/glsl-noise)
+
+## Usage ##
+
+``` glsl
+// Require as many or as little as you need:
+#pragma glslify: snoise2 = require(glsl-noise/simplex/2d)
+#pragma glslify: snoise3 = require(glsl-noise/simplex/3d)
+#pragma glslify: snoise4 = require(glsl-noise/simplex/4d)
+#pragma glslify: cnoise2 = require(glsl-noise/classic/2d)
+#pragma glslify: cnoise3 = require(glsl-noise/classic/3d)
+#pragma glslify: cnoise4 = require(glsl-noise/classic/4d)
+#pragma glslify: pnoise2 = require(glsl-noise/periodic/2d)
+#pragma glslify: pnoise3 = require(glsl-noise/periodic/3d)
+#pragma glslify: pnoise4 = require(glsl-noise/periodic/4d)
+
+attribute vec3 position;
+
+// And just treat them as functions like
+// you normally would:
+void main() {
+  gl_FragColor = vec4(snoise3(position), 1.0);
+}
+```
diff --git a/glsl-noise/classic/2d.glsl b/glsl-noise/classic/2d.glsl
new file mode 100644 (file)
index 0000000..20b6e3e
--- /dev/null
@@ -0,0 +1,74 @@
+//
+// GLSL textureless classic 2D noise "cnoise",
+// with an RSL-style periodic variant "pnoise".
+// Author:  Stefan Gustavson (stefan.gustavson@liu.se)
+// Version: 2011-08-22
+//
+// Many thanks to Ian McEwan of Ashima Arts for the
+// ideas for permutation and gradient selection.
+//
+// Copyright (c) 2011 Stefan Gustavson. All rights reserved.
+// Distributed under the MIT license. See LICENSE file.
+// https://github.com/ashima/webgl-noise
+//
+
+vec4 mod289(vec4 x)
+{
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec4 permute(vec4 x)
+{
+  return mod289(((x*34.0)+1.0)*x);
+}
+
+vec4 taylorInvSqrt(vec4 r)
+{
+  return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+vec2 fade(vec2 t) {
+  return t*t*t*(t*(t*6.0-15.0)+10.0);
+}
+
+// Classic Perlin noise
+float cnoise(vec2 P)
+{
+  vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);
+  vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);
+  Pi = mod289(Pi); // To avoid truncation effects in permutation
+  vec4 ix = Pi.xzxz;
+  vec4 iy = Pi.yyww;
+  vec4 fx = Pf.xzxz;
+  vec4 fy = Pf.yyww;
+
+  vec4 i = permute(permute(ix) + iy);
+
+  vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ;
+  vec4 gy = abs(gx) - 0.5 ;
+  vec4 tx = floor(gx + 0.5);
+  gx = gx - tx;
+
+  vec2 g00 = vec2(gx.x,gy.x);
+  vec2 g10 = vec2(gx.y,gy.y);
+  vec2 g01 = vec2(gx.z,gy.z);
+  vec2 g11 = vec2(gx.w,gy.w);
+
+  vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
+  g00 *= norm.x;
+  g01 *= norm.y;
+  g10 *= norm.z;
+  g11 *= norm.w;
+
+  float n00 = dot(g00, vec2(fx.x, fy.x));
+  float n10 = dot(g10, vec2(fx.y, fy.y));
+  float n01 = dot(g01, vec2(fx.z, fy.z));
+  float n11 = dot(g11, vec2(fx.w, fy.w));
+
+  vec2 fade_xy = fade(Pf.xy);
+  vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
+  float n_xy = mix(n_x.x, n_x.y, fade_xy.y);
+  return 2.3 * n_xy;
+}
+
+#pragma glslify: export(cnoise)
diff --git a/glsl-noise/classic/3d.glsl b/glsl-noise/classic/3d.glsl
new file mode 100644 (file)
index 0000000..6fe889a
--- /dev/null
@@ -0,0 +1,109 @@
+//
+// GLSL textureless classic 3D noise "cnoise",
+// with an RSL-style periodic variant "pnoise".
+// Author:  Stefan Gustavson (stefan.gustavson@liu.se)
+// Version: 2011-10-11
+//
+// Many thanks to Ian McEwan of Ashima Arts for the
+// ideas for permutation and gradient selection.
+//
+// Copyright (c) 2011 Stefan Gustavson. All rights reserved.
+// Distributed under the MIT license. See LICENSE file.
+// https://github.com/ashima/webgl-noise
+//
+
+vec3 mod289(vec3 x)
+{
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec4 mod289(vec4 x)
+{
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec4 permute(vec4 x)
+{
+  return mod289(((x*34.0)+1.0)*x);
+}
+
+vec4 taylorInvSqrt(vec4 r)
+{
+  return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+vec3 fade(vec3 t) {
+  return t*t*t*(t*(t*6.0-15.0)+10.0);
+}
+
+// Classic Perlin noise
+float cnoise(vec3 P)
+{
+  vec3 Pi0 = floor(P); // Integer part for indexing
+  vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1
+  Pi0 = mod289(Pi0);
+  Pi1 = mod289(Pi1);
+  vec3 Pf0 = fract(P); // Fractional part for interpolation
+  vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
+  vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+  vec4 iy = vec4(Pi0.yy, Pi1.yy);
+  vec4 iz0 = Pi0.zzzz;
+  vec4 iz1 = Pi1.zzzz;
+
+  vec4 ixy = permute(permute(ix) + iy);
+  vec4 ixy0 = permute(ixy + iz0);
+  vec4 ixy1 = permute(ixy + iz1);
+
+  vec4 gx0 = ixy0 * (1.0 / 7.0);
+  vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;
+  gx0 = fract(gx0);
+  vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
+  vec4 sz0 = step(gz0, vec4(0.0));
+  gx0 -= sz0 * (step(0.0, gx0) - 0.5);
+  gy0 -= sz0 * (step(0.0, gy0) - 0.5);
+
+  vec4 gx1 = ixy1 * (1.0 / 7.0);
+  vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;
+  gx1 = fract(gx1);
+  vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
+  vec4 sz1 = step(gz1, vec4(0.0));
+  gx1 -= sz1 * (step(0.0, gx1) - 0.5);
+  gy1 -= sz1 * (step(0.0, gy1) - 0.5);
+
+  vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
+  vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
+  vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
+  vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
+  vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
+  vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
+  vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
+  vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);
+
+  vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
+  g000 *= norm0.x;
+  g010 *= norm0.y;
+  g100 *= norm0.z;
+  g110 *= norm0.w;
+  vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
+  g001 *= norm1.x;
+  g011 *= norm1.y;
+  g101 *= norm1.z;
+  g111 *= norm1.w;
+
+  float n000 = dot(g000, Pf0);
+  float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
+  float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
+  float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
+  float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
+  float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
+  float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
+  float n111 = dot(g111, Pf1);
+
+  vec3 fade_xyz = fade(Pf0);
+  vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
+  vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
+  float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
+  return 2.2 * n_xyz;
+}
+
+#pragma glslify: export(cnoise)
diff --git a/glsl-noise/classic/4d.glsl b/glsl-noise/classic/4d.glsl
new file mode 100644 (file)
index 0000000..3c90879
--- /dev/null
@@ -0,0 +1,169 @@
+//
+// GLSL textureless classic 4D noise "cnoise",
+// with an RSL-style periodic variant "pnoise".
+// Author:  Stefan Gustavson (stefan.gustavson@liu.se)
+// Version: 2011-08-22
+//
+// Many thanks to Ian McEwan of Ashima Arts for the
+// ideas for permutation and gradient selection.
+//
+// Copyright (c) 2011 Stefan Gustavson. All rights reserved.
+// Distributed under the MIT license. See LICENSE file.
+// https://github.com/ashima/webgl-noise
+//
+
+vec4 mod289(vec4 x)
+{
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec4 permute(vec4 x)
+{
+  return mod289(((x*34.0)+1.0)*x);
+}
+
+vec4 taylorInvSqrt(vec4 r)
+{
+  return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+vec4 fade(vec4 t) {
+  return t*t*t*(t*(t*6.0-15.0)+10.0);
+}
+
+// Classic Perlin noise
+float cnoise(vec4 P)
+{
+  vec4 Pi0 = floor(P); // Integer part for indexing
+  vec4 Pi1 = Pi0 + 1.0; // Integer part + 1
+  Pi0 = mod289(Pi0);
+  Pi1 = mod289(Pi1);
+  vec4 Pf0 = fract(P); // Fractional part for interpolation
+  vec4 Pf1 = Pf0 - 1.0; // Fractional part - 1.0
+  vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+  vec4 iy = vec4(Pi0.yy, Pi1.yy);
+  vec4 iz0 = vec4(Pi0.zzzz);
+  vec4 iz1 = vec4(Pi1.zzzz);
+  vec4 iw0 = vec4(Pi0.wwww);
+  vec4 iw1 = vec4(Pi1.wwww);
+
+  vec4 ixy = permute(permute(ix) + iy);
+  vec4 ixy0 = permute(ixy + iz0);
+  vec4 ixy1 = permute(ixy + iz1);
+  vec4 ixy00 = permute(ixy0 + iw0);
+  vec4 ixy01 = permute(ixy0 + iw1);
+  vec4 ixy10 = permute(ixy1 + iw0);
+  vec4 ixy11 = permute(ixy1 + iw1);
+
+  vec4 gx00 = ixy00 * (1.0 / 7.0);
+  vec4 gy00 = floor(gx00) * (1.0 / 7.0);
+  vec4 gz00 = floor(gy00) * (1.0 / 6.0);
+  gx00 = fract(gx00) - 0.5;
+  gy00 = fract(gy00) - 0.5;
+  gz00 = fract(gz00) - 0.5;
+  vec4 gw00 = vec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
+  vec4 sw00 = step(gw00, vec4(0.0));
+  gx00 -= sw00 * (step(0.0, gx00) - 0.5);
+  gy00 -= sw00 * (step(0.0, gy00) - 0.5);
+
+  vec4 gx01 = ixy01 * (1.0 / 7.0);
+  vec4 gy01 = floor(gx01) * (1.0 / 7.0);
+  vec4 gz01 = floor(gy01) * (1.0 / 6.0);
+  gx01 = fract(gx01) - 0.5;
+  gy01 = fract(gy01) - 0.5;
+  gz01 = fract(gz01) - 0.5;
+  vec4 gw01 = vec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
+  vec4 sw01 = step(gw01, vec4(0.0));
+  gx01 -= sw01 * (step(0.0, gx01) - 0.5);
+  gy01 -= sw01 * (step(0.0, gy01) - 0.5);
+
+  vec4 gx10 = ixy10 * (1.0 / 7.0);
+  vec4 gy10 = floor(gx10) * (1.0 / 7.0);
+  vec4 gz10 = floor(gy10) * (1.0 / 6.0);
+  gx10 = fract(gx10) - 0.5;
+  gy10 = fract(gy10) - 0.5;
+  gz10 = fract(gz10) - 0.5;
+  vec4 gw10 = vec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
+  vec4 sw10 = step(gw10, vec4(0.0));
+  gx10 -= sw10 * (step(0.0, gx10) - 0.5);
+  gy10 -= sw10 * (step(0.0, gy10) - 0.5);
+
+  vec4 gx11 = ixy11 * (1.0 / 7.0);
+  vec4 gy11 = floor(gx11) * (1.0 / 7.0);
+  vec4 gz11 = floor(gy11) * (1.0 / 6.0);
+  gx11 = fract(gx11) - 0.5;
+  gy11 = fract(gy11) - 0.5;
+  gz11 = fract(gz11) - 0.5;
+  vec4 gw11 = vec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
+  vec4 sw11 = step(gw11, vec4(0.0));
+  gx11 -= sw11 * (step(0.0, gx11) - 0.5);
+  gy11 -= sw11 * (step(0.0, gy11) - 0.5);
+
+  vec4 g0000 = vec4(gx00.x,gy00.x,gz00.x,gw00.x);
+  vec4 g1000 = vec4(gx00.y,gy00.y,gz00.y,gw00.y);
+  vec4 g0100 = vec4(gx00.z,gy00.z,gz00.z,gw00.z);
+  vec4 g1100 = vec4(gx00.w,gy00.w,gz00.w,gw00.w);
+  vec4 g0010 = vec4(gx10.x,gy10.x,gz10.x,gw10.x);
+  vec4 g1010 = vec4(gx10.y,gy10.y,gz10.y,gw10.y);
+  vec4 g0110 = vec4(gx10.z,gy10.z,gz10.z,gw10.z);
+  vec4 g1110 = vec4(gx10.w,gy10.w,gz10.w,gw10.w);
+  vec4 g0001 = vec4(gx01.x,gy01.x,gz01.x,gw01.x);
+  vec4 g1001 = vec4(gx01.y,gy01.y,gz01.y,gw01.y);
+  vec4 g0101 = vec4(gx01.z,gy01.z,gz01.z,gw01.z);
+  vec4 g1101 = vec4(gx01.w,gy01.w,gz01.w,gw01.w);
+  vec4 g0011 = vec4(gx11.x,gy11.x,gz11.x,gw11.x);
+  vec4 g1011 = vec4(gx11.y,gy11.y,gz11.y,gw11.y);
+  vec4 g0111 = vec4(gx11.z,gy11.z,gz11.z,gw11.z);
+  vec4 g1111 = vec4(gx11.w,gy11.w,gz11.w,gw11.w);
+
+  vec4 norm00 = taylorInvSqrt(vec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
+  g0000 *= norm00.x;
+  g0100 *= norm00.y;
+  g1000 *= norm00.z;
+  g1100 *= norm00.w;
+
+  vec4 norm01 = taylorInvSqrt(vec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
+  g0001 *= norm01.x;
+  g0101 *= norm01.y;
+  g1001 *= norm01.z;
+  g1101 *= norm01.w;
+
+  vec4 norm10 = taylorInvSqrt(vec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
+  g0010 *= norm10.x;
+  g0110 *= norm10.y;
+  g1010 *= norm10.z;
+  g1110 *= norm10.w;
+
+  vec4 norm11 = taylorInvSqrt(vec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
+  g0011 *= norm11.x;
+  g0111 *= norm11.y;
+  g1011 *= norm11.z;
+  g1111 *= norm11.w;
+
+  float n0000 = dot(g0000, Pf0);
+  float n1000 = dot(g1000, vec4(Pf1.x, Pf0.yzw));
+  float n0100 = dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.zw));
+  float n1100 = dot(g1100, vec4(Pf1.xy, Pf0.zw));
+  float n0010 = dot(g0010, vec4(Pf0.xy, Pf1.z, Pf0.w));
+  float n1010 = dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
+  float n0110 = dot(g0110, vec4(Pf0.x, Pf1.yz, Pf0.w));
+  float n1110 = dot(g1110, vec4(Pf1.xyz, Pf0.w));
+  float n0001 = dot(g0001, vec4(Pf0.xyz, Pf1.w));
+  float n1001 = dot(g1001, vec4(Pf1.x, Pf0.yz, Pf1.w));
+  float n0101 = dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
+  float n1101 = dot(g1101, vec4(Pf1.xy, Pf0.z, Pf1.w));
+  float n0011 = dot(g0011, vec4(Pf0.xy, Pf1.zw));
+  float n1011 = dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.zw));
+  float n0111 = dot(g0111, vec4(Pf0.x, Pf1.yzw));
+  float n1111 = dot(g1111, Pf1);
+
+  vec4 fade_xyzw = fade(Pf0);
+  vec4 n_0w = mix(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w);
+  vec4 n_1w = mix(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w);
+  vec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z);
+  vec2 n_yzw = mix(n_zw.xy, n_zw.zw, fade_xyzw.y);
+  float n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
+  return 2.2 * n_xyzw;
+}
+
+#pragma glslify: export(cnoise)
diff --git a/glsl-noise/package.json b/glsl-noise/package.json
new file mode 100644 (file)
index 0000000..97c14e3
--- /dev/null
@@ -0,0 +1,27 @@
+{
+  "name": "glsl-noise",
+  "version": "0.0.0",
+  "description": "webgl-noise shaders ported to work with glslify",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/hughsk/glsl-noise.git"
+  },
+  "keywords": [
+    "glsl",
+    "noise",
+    "shader",
+    "perlin",
+    "simplex",
+    "webgl",
+    "glslify"
+  ],
+  "author": "Ian McEwan, Ashima Arts, Stefan Gustavson",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/hughsk/glsl-noise/issues"
+  }
+}
diff --git a/glsl-noise/periodic/2d.glsl b/glsl-noise/periodic/2d.glsl
new file mode 100644 (file)
index 0000000..c267970
--- /dev/null
@@ -0,0 +1,75 @@
+//
+// GLSL textureless classic 2D noise "cnoise",
+// with an RSL-style periodic variant "pnoise".
+// Author:  Stefan Gustavson (stefan.gustavson@liu.se)
+// Version: 2011-08-22
+//
+// Many thanks to Ian McEwan of Ashima Arts for the
+// ideas for permutation and gradient selection.
+//
+// Copyright (c) 2011 Stefan Gustavson. All rights reserved.
+// Distributed under the MIT license. See LICENSE file.
+// https://github.com/ashima/webgl-noise
+//
+
+vec4 mod289(vec4 x)
+{
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec4 permute(vec4 x)
+{
+  return mod289(((x*34.0)+1.0)*x);
+}
+
+vec4 taylorInvSqrt(vec4 r)
+{
+  return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+vec2 fade(vec2 t) {
+  return t*t*t*(t*(t*6.0-15.0)+10.0);
+}
+
+// Classic Perlin noise, periodic variant
+float pnoise(vec2 P, vec2 rep)
+{
+  vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);
+  vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);
+  Pi = mod(Pi, rep.xyxy); // To create noise with explicit period
+  Pi = mod289(Pi);        // To avoid truncation effects in permutation
+  vec4 ix = Pi.xzxz;
+  vec4 iy = Pi.yyww;
+  vec4 fx = Pf.xzxz;
+  vec4 fy = Pf.yyww;
+
+  vec4 i = permute(permute(ix) + iy);
+
+  vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ;
+  vec4 gy = abs(gx) - 0.5 ;
+  vec4 tx = floor(gx + 0.5);
+  gx = gx - tx;
+
+  vec2 g00 = vec2(gx.x,gy.x);
+  vec2 g10 = vec2(gx.y,gy.y);
+  vec2 g01 = vec2(gx.z,gy.z);
+  vec2 g11 = vec2(gx.w,gy.w);
+
+  vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
+  g00 *= norm.x;
+  g01 *= norm.y;
+  g10 *= norm.z;
+  g11 *= norm.w;
+
+  float n00 = dot(g00, vec2(fx.x, fy.x));
+  float n10 = dot(g10, vec2(fx.y, fy.y));
+  float n01 = dot(g01, vec2(fx.z, fy.z));
+  float n11 = dot(g11, vec2(fx.w, fy.w));
+
+  vec2 fade_xy = fade(Pf.xy);
+  vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
+  float n_xy = mix(n_x.x, n_x.y, fade_xy.y);
+  return 2.3 * n_xy;
+}
+
+#pragma glslify: export(pnoise)
diff --git a/glsl-noise/periodic/3d.glsl b/glsl-noise/periodic/3d.glsl
new file mode 100644 (file)
index 0000000..b88ffa6
--- /dev/null
@@ -0,0 +1,109 @@
+//
+// GLSL textureless classic 3D noise "cnoise",
+// with an RSL-style periodic variant "pnoise".
+// Author:  Stefan Gustavson (stefan.gustavson@liu.se)
+// Version: 2011-10-11
+//
+// Many thanks to Ian McEwan of Ashima Arts for the
+// ideas for permutation and gradient selection.
+//
+// Copyright (c) 2011 Stefan Gustavson. All rights reserved.
+// Distributed under the MIT license. See LICENSE file.
+// https://github.com/ashima/webgl-noise
+//
+
+vec3 mod289(vec3 x)
+{
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec4 mod289(vec4 x)
+{
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec4 permute(vec4 x)
+{
+  return mod289(((x*34.0)+1.0)*x);
+}
+
+vec4 taylorInvSqrt(vec4 r)
+{
+  return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+vec3 fade(vec3 t) {
+  return t*t*t*(t*(t*6.0-15.0)+10.0);
+}
+
+// Classic Perlin noise, periodic variant
+float pnoise(vec3 P, vec3 rep)
+{
+  vec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period
+  vec3 Pi1 = mod(Pi0 + vec3(1.0), rep); // Integer part + 1, mod period
+  Pi0 = mod289(Pi0);
+  Pi1 = mod289(Pi1);
+  vec3 Pf0 = fract(P); // Fractional part for interpolation
+  vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
+  vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+  vec4 iy = vec4(Pi0.yy, Pi1.yy);
+  vec4 iz0 = Pi0.zzzz;
+  vec4 iz1 = Pi1.zzzz;
+
+  vec4 ixy = permute(permute(ix) + iy);
+  vec4 ixy0 = permute(ixy + iz0);
+  vec4 ixy1 = permute(ixy + iz1);
+
+  vec4 gx0 = ixy0 * (1.0 / 7.0);
+  vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;
+  gx0 = fract(gx0);
+  vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
+  vec4 sz0 = step(gz0, vec4(0.0));
+  gx0 -= sz0 * (step(0.0, gx0) - 0.5);
+  gy0 -= sz0 * (step(0.0, gy0) - 0.5);
+
+  vec4 gx1 = ixy1 * (1.0 / 7.0);
+  vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;
+  gx1 = fract(gx1);
+  vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
+  vec4 sz1 = step(gz1, vec4(0.0));
+  gx1 -= sz1 * (step(0.0, gx1) - 0.5);
+  gy1 -= sz1 * (step(0.0, gy1) - 0.5);
+
+  vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
+  vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
+  vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
+  vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
+  vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
+  vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
+  vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
+  vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);
+
+  vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
+  g000 *= norm0.x;
+  g010 *= norm0.y;
+  g100 *= norm0.z;
+  g110 *= norm0.w;
+  vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
+  g001 *= norm1.x;
+  g011 *= norm1.y;
+  g101 *= norm1.z;
+  g111 *= norm1.w;
+
+  float n000 = dot(g000, Pf0);
+  float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
+  float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
+  float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
+  float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
+  float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
+  float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
+  float n111 = dot(g111, Pf1);
+
+  vec3 fade_xyz = fade(Pf0);
+  vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
+  vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
+  float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
+  return 2.2 * n_xyz;
+}
+
+#pragma glslify: export(pnoise)
diff --git a/glsl-noise/periodic/4d.glsl b/glsl-noise/periodic/4d.glsl
new file mode 100644 (file)
index 0000000..a754ba4
--- /dev/null
@@ -0,0 +1,169 @@
+//
+// GLSL textureless classic 4D noise "cnoise",
+// with an RSL-style periodic variant "pnoise".
+// Author:  Stefan Gustavson (stefan.gustavson@liu.se)
+// Version: 2011-08-22
+//
+// Many thanks to Ian McEwan of Ashima Arts for the
+// ideas for permutation and gradient selection.
+//
+// Copyright (c) 2011 Stefan Gustavson. All rights reserved.
+// Distributed under the MIT license. See LICENSE file.
+// https://github.com/ashima/webgl-noise
+//
+
+vec4 mod289(vec4 x)
+{
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec4 permute(vec4 x)
+{
+  return mod289(((x*34.0)+1.0)*x);
+}
+
+vec4 taylorInvSqrt(vec4 r)
+{
+  return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+vec4 fade(vec4 t) {
+  return t*t*t*(t*(t*6.0-15.0)+10.0);
+}
+
+// Classic Perlin noise, periodic version
+float pnoise(vec4 P, vec4 rep)
+{
+  vec4 Pi0 = mod(floor(P), rep); // Integer part modulo rep
+  vec4 Pi1 = mod(Pi0 + 1.0, rep); // Integer part + 1 mod rep
+  Pi0 = mod289(Pi0);
+  Pi1 = mod289(Pi1);
+  vec4 Pf0 = fract(P); // Fractional part for interpolation
+  vec4 Pf1 = Pf0 - 1.0; // Fractional part - 1.0
+  vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+  vec4 iy = vec4(Pi0.yy, Pi1.yy);
+  vec4 iz0 = vec4(Pi0.zzzz);
+  vec4 iz1 = vec4(Pi1.zzzz);
+  vec4 iw0 = vec4(Pi0.wwww);
+  vec4 iw1 = vec4(Pi1.wwww);
+
+  vec4 ixy = permute(permute(ix) + iy);
+  vec4 ixy0 = permute(ixy + iz0);
+  vec4 ixy1 = permute(ixy + iz1);
+  vec4 ixy00 = permute(ixy0 + iw0);
+  vec4 ixy01 = permute(ixy0 + iw1);
+  vec4 ixy10 = permute(ixy1 + iw0);
+  vec4 ixy11 = permute(ixy1 + iw1);
+
+  vec4 gx00 = ixy00 * (1.0 / 7.0);
+  vec4 gy00 = floor(gx00) * (1.0 / 7.0);
+  vec4 gz00 = floor(gy00) * (1.0 / 6.0);
+  gx00 = fract(gx00) - 0.5;
+  gy00 = fract(gy00) - 0.5;
+  gz00 = fract(gz00) - 0.5;
+  vec4 gw00 = vec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
+  vec4 sw00 = step(gw00, vec4(0.0));
+  gx00 -= sw00 * (step(0.0, gx00) - 0.5);
+  gy00 -= sw00 * (step(0.0, gy00) - 0.5);
+
+  vec4 gx01 = ixy01 * (1.0 / 7.0);
+  vec4 gy01 = floor(gx01) * (1.0 / 7.0);
+  vec4 gz01 = floor(gy01) * (1.0 / 6.0);
+  gx01 = fract(gx01) - 0.5;
+  gy01 = fract(gy01) - 0.5;
+  gz01 = fract(gz01) - 0.5;
+  vec4 gw01 = vec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
+  vec4 sw01 = step(gw01, vec4(0.0));
+  gx01 -= sw01 * (step(0.0, gx01) - 0.5);
+  gy01 -= sw01 * (step(0.0, gy01) - 0.5);
+
+  vec4 gx10 = ixy10 * (1.0 / 7.0);
+  vec4 gy10 = floor(gx10) * (1.0 / 7.0);
+  vec4 gz10 = floor(gy10) * (1.0 / 6.0);
+  gx10 = fract(gx10) - 0.5;
+  gy10 = fract(gy10) - 0.5;
+  gz10 = fract(gz10) - 0.5;
+  vec4 gw10 = vec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
+  vec4 sw10 = step(gw10, vec4(0.0));
+  gx10 -= sw10 * (step(0.0, gx10) - 0.5);
+  gy10 -= sw10 * (step(0.0, gy10) - 0.5);
+
+  vec4 gx11 = ixy11 * (1.0 / 7.0);
+  vec4 gy11 = floor(gx11) * (1.0 / 7.0);
+  vec4 gz11 = floor(gy11) * (1.0 / 6.0);
+  gx11 = fract(gx11) - 0.5;
+  gy11 = fract(gy11) - 0.5;
+  gz11 = fract(gz11) - 0.5;
+  vec4 gw11 = vec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
+  vec4 sw11 = step(gw11, vec4(0.0));
+  gx11 -= sw11 * (step(0.0, gx11) - 0.5);
+  gy11 -= sw11 * (step(0.0, gy11) - 0.5);
+
+  vec4 g0000 = vec4(gx00.x,gy00.x,gz00.x,gw00.x);
+  vec4 g1000 = vec4(gx00.y,gy00.y,gz00.y,gw00.y);
+  vec4 g0100 = vec4(gx00.z,gy00.z,gz00.z,gw00.z);
+  vec4 g1100 = vec4(gx00.w,gy00.w,gz00.w,gw00.w);
+  vec4 g0010 = vec4(gx10.x,gy10.x,gz10.x,gw10.x);
+  vec4 g1010 = vec4(gx10.y,gy10.y,gz10.y,gw10.y);
+  vec4 g0110 = vec4(gx10.z,gy10.z,gz10.z,gw10.z);
+  vec4 g1110 = vec4(gx10.w,gy10.w,gz10.w,gw10.w);
+  vec4 g0001 = vec4(gx01.x,gy01.x,gz01.x,gw01.x);
+  vec4 g1001 = vec4(gx01.y,gy01.y,gz01.y,gw01.y);
+  vec4 g0101 = vec4(gx01.z,gy01.z,gz01.z,gw01.z);
+  vec4 g1101 = vec4(gx01.w,gy01.w,gz01.w,gw01.w);
+  vec4 g0011 = vec4(gx11.x,gy11.x,gz11.x,gw11.x);
+  vec4 g1011 = vec4(gx11.y,gy11.y,gz11.y,gw11.y);
+  vec4 g0111 = vec4(gx11.z,gy11.z,gz11.z,gw11.z);
+  vec4 g1111 = vec4(gx11.w,gy11.w,gz11.w,gw11.w);
+
+  vec4 norm00 = taylorInvSqrt(vec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
+  g0000 *= norm00.x;
+  g0100 *= norm00.y;
+  g1000 *= norm00.z;
+  g1100 *= norm00.w;
+
+  vec4 norm01 = taylorInvSqrt(vec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
+  g0001 *= norm01.x;
+  g0101 *= norm01.y;
+  g1001 *= norm01.z;
+  g1101 *= norm01.w;
+
+  vec4 norm10 = taylorInvSqrt(vec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
+  g0010 *= norm10.x;
+  g0110 *= norm10.y;
+  g1010 *= norm10.z;
+  g1110 *= norm10.w;
+
+  vec4 norm11 = taylorInvSqrt(vec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
+  g0011 *= norm11.x;
+  g0111 *= norm11.y;
+  g1011 *= norm11.z;
+  g1111 *= norm11.w;
+
+  float n0000 = dot(g0000, Pf0);
+  float n1000 = dot(g1000, vec4(Pf1.x, Pf0.yzw));
+  float n0100 = dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.zw));
+  float n1100 = dot(g1100, vec4(Pf1.xy, Pf0.zw));
+  float n0010 = dot(g0010, vec4(Pf0.xy, Pf1.z, Pf0.w));
+  float n1010 = dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
+  float n0110 = dot(g0110, vec4(Pf0.x, Pf1.yz, Pf0.w));
+  float n1110 = dot(g1110, vec4(Pf1.xyz, Pf0.w));
+  float n0001 = dot(g0001, vec4(Pf0.xyz, Pf1.w));
+  float n1001 = dot(g1001, vec4(Pf1.x, Pf0.yz, Pf1.w));
+  float n0101 = dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
+  float n1101 = dot(g1101, vec4(Pf1.xy, Pf0.z, Pf1.w));
+  float n0011 = dot(g0011, vec4(Pf0.xy, Pf1.zw));
+  float n1011 = dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.zw));
+  float n0111 = dot(g0111, vec4(Pf0.x, Pf1.yzw));
+  float n1111 = dot(g1111, Pf1);
+
+  vec4 fade_xyzw = fade(Pf0);
+  vec4 n_0w = mix(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w);
+  vec4 n_1w = mix(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w);
+  vec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z);
+  vec2 n_yzw = mix(n_zw.xy, n_zw.zw, fade_xyzw.y);
+  float n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
+  return 2.2 * n_xyzw;
+}
+
+#pragma glslify: export(pnoise)
diff --git a/glsl-noise/simplex/2d.glsl b/glsl-noise/simplex/2d.glsl
new file mode 100644 (file)
index 0000000..7c89a87
--- /dev/null
@@ -0,0 +1,72 @@
+//
+// Description : Array and textureless GLSL 2D simplex noise function.
+//      Author : Ian McEwan, Ashima Arts.
+//  Maintainer : ijm
+//     Lastmod : 20110822 (ijm)
+//     License : Copyright (C) 2011 Ashima Arts. All rights reserved.
+//               Distributed under the MIT License. See LICENSE file.
+//               https://github.com/ashima/webgl-noise
+//
+
+vec3 mod289(vec3 x) {
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec2 mod289(vec2 x) {
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec3 permute(vec3 x) {
+  return mod289(((x*34.0)+1.0)*x);
+}
+
+float snoise(vec2 v)
+  {
+  const vec4 C = vec4(0.211324865405187,  // (3.0-sqrt(3.0))/6.0
+                      0.366025403784439,  // 0.5*(sqrt(3.0)-1.0)
+                     -0.577350269189626,  // -1.0 + 2.0 * C.x
+                      0.024390243902439); // 1.0 / 41.0
+// First corner
+  vec2 i  = floor(v + dot(v, C.yy) );
+  vec2 x0 = v -   i + dot(i, C.xx);
+
+// Other corners
+  vec2 i1;
+  //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
+  //i1.y = 1.0 - i1.x;
+  i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
+  // x0 = x0 - 0.0 + 0.0 * C.xx ;
+  // x1 = x0 - i1 + 1.0 * C.xx ;
+  // x2 = x0 - 1.0 + 2.0 * C.xx ;
+  vec4 x12 = x0.xyxy + C.xxzz;
+  x12.xy -= i1;
+
+// Permutations
+  i = mod289(i); // Avoid truncation effects in permutation
+  vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
+    + i.x + vec3(0.0, i1.x, 1.0 ));
+
+  vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
+  m = m*m ;
+  m = m*m ;
+
+// Gradients: 41 points uniformly over a line, mapped onto a diamond.
+// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
+
+  vec3 x = 2.0 * fract(p * C.www) - 1.0;
+  vec3 h = abs(x) - 0.5;
+  vec3 ox = floor(x + 0.5);
+  vec3 a0 = x - ox;
+
+// Normalise gradients implicitly by scaling m
+// Approximation of: m *= inversesqrt( a0*a0 + h*h );
+  m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
+
+// Compute final noise value at P
+  vec3 g;
+  g.x  = a0.x  * x0.x  + h.x  * x0.y;
+  g.yz = a0.yz * x12.xz + h.yz * x12.yw;
+  return 130.0 * dot(m, g);
+}
+
+#pragma glslify: export(snoise)
diff --git a/glsl-noise/simplex/3d.glsl b/glsl-noise/simplex/3d.glsl
new file mode 100644 (file)
index 0000000..711e5bf
--- /dev/null
@@ -0,0 +1,104 @@
+//
+// Description : Array and textureless GLSL 2D/3D/4D simplex
+//               noise functions.
+//      Author : Ian McEwan, Ashima Arts.
+//  Maintainer : ijm
+//     Lastmod : 20110822 (ijm)
+//     License : Copyright (C) 2011 Ashima Arts. All rights reserved.
+//               Distributed under the MIT License. See LICENSE file.
+//               https://github.com/ashima/webgl-noise
+//
+
+vec3 mod289(vec3 x) {
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec4 mod289(vec4 x) {
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec4 permute(vec4 x) {
+     return mod289(((x*34.0)+1.0)*x);
+}
+
+vec4 taylorInvSqrt(vec4 r)
+{
+  return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+float snoise(vec3 v)
+  {
+  const vec2  C = vec2(1.0/6.0, 1.0/3.0) ;
+  const vec4  D = vec4(0.0, 0.5, 1.0, 2.0);
+
+// First corner
+  vec3 i  = floor(v + dot(v, C.yyy) );
+  vec3 x0 =   v - i + dot(i, C.xxx) ;
+
+// Other corners
+  vec3 g = step(x0.yzx, x0.xyz);
+  vec3 l = 1.0 - g;
+  vec3 i1 = min( g.xyz, l.zxy );
+  vec3 i2 = max( g.xyz, l.zxy );
+
+  //   x0 = x0 - 0.0 + 0.0 * C.xxx;
+  //   x1 = x0 - i1  + 1.0 * C.xxx;
+  //   x2 = x0 - i2  + 2.0 * C.xxx;
+  //   x3 = x0 - 1.0 + 3.0 * C.xxx;
+  vec3 x1 = x0 - i1 + C.xxx;
+  vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
+  vec3 x3 = x0 - D.yyy;      // -1.0+3.0*C.x = -0.5 = -D.y
+
+// Permutations
+  i = mod289(i);
+  vec4 p = permute( permute( permute(
+             i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
+           + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
+           + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
+
+// Gradients: 7x7 points over a square, mapped onto an octahedron.
+// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
+  float n_ = 0.142857142857; // 1.0/7.0
+  vec3  ns = n_ * D.wyz - D.xzx;
+
+  vec4 j = p - 49.0 * floor(p * ns.z * ns.z);  //  mod(p,7*7)
+
+  vec4 x_ = floor(j * ns.z);
+  vec4 y_ = floor(j - 7.0 * x_ );    // mod(j,N)
+
+  vec4 x = x_ *ns.x + ns.yyyy;
+  vec4 y = y_ *ns.x + ns.yyyy;
+  vec4 h = 1.0 - abs(x) - abs(y);
+
+  vec4 b0 = vec4( x.xy, y.xy );
+  vec4 b1 = vec4( x.zw, y.zw );
+
+  //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
+  //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
+  vec4 s0 = floor(b0)*2.0 + 1.0;
+  vec4 s1 = floor(b1)*2.0 + 1.0;
+  vec4 sh = -step(h, vec4(0.0));
+
+  vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
+  vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
+
+  vec3 p0 = vec3(a0.xy,h.x);
+  vec3 p1 = vec3(a0.zw,h.y);
+  vec3 p2 = vec3(a1.xy,h.z);
+  vec3 p3 = vec3(a1.zw,h.w);
+
+//Normalise gradients
+  vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
+  p0 *= norm.x;
+  p1 *= norm.y;
+  p2 *= norm.z;
+  p3 *= norm.w;
+
+// Mix final noise value
+  vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
+  m = m * m;
+  return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
+                                dot(p2,x2), dot(p3,x3) ) );
+  }
+
+#pragma glslify: export(snoise)
diff --git a/glsl-noise/simplex/4d.glsl b/glsl-noise/simplex/4d.glsl
new file mode 100644 (file)
index 0000000..76ee01c
--- /dev/null
@@ -0,0 +1,130 @@
+//
+// Description : Array and textureless GLSL 2D/3D/4D simplex
+//               noise functions.
+//      Author : Ian McEwan, Ashima Arts.
+//  Maintainer : ijm
+//     Lastmod : 20110822 (ijm)
+//     License : Copyright (C) 2011 Ashima Arts. All rights reserved.
+//               Distributed under the MIT License. See LICENSE file.
+//               https://github.com/ashima/webgl-noise
+//
+
+vec4 mod289(vec4 x) {
+  return x - floor(x * (1.0 / 289.0)) * 289.0; }
+
+float mod289(float x) {
+  return x - floor(x * (1.0 / 289.0)) * 289.0; }
+
+vec4 permute(vec4 x) {
+     return mod289(((x*34.0)+1.0)*x);
+}
+
+float permute(float x) {
+     return mod289(((x*34.0)+1.0)*x);
+}
+
+vec4 taylorInvSqrt(vec4 r)
+{
+  return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+float taylorInvSqrt(float r)
+{
+  return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+vec4 grad4(float j, vec4 ip)
+  {
+  const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);
+  vec4 p,s;
+
+  p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;
+  p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
+  s = vec4(lessThan(p, vec4(0.0)));
+  p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www;
+
+  return p;
+  }
+
+// (sqrt(5) - 1)/4 = F4, used once below
+#define F4 0.309016994374947451
+
+float snoise(vec4 v)
+  {
+  const vec4  C = vec4( 0.138196601125011,  // (5 - sqrt(5))/20  G4
+                        0.276393202250021,  // 2 * G4
+                        0.414589803375032,  // 3 * G4
+                       -0.447213595499958); // -1 + 4 * G4
+
+// First corner
+  vec4 i  = floor(v + dot(v, vec4(F4)) );
+  vec4 x0 = v -   i + dot(i, C.xxxx);
+
+// Other corners
+
+// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
+  vec4 i0;
+  vec3 isX = step( x0.yzw, x0.xxx );
+  vec3 isYZ = step( x0.zww, x0.yyz );
+//  i0.x = dot( isX, vec3( 1.0 ) );
+  i0.x = isX.x + isX.y + isX.z;
+  i0.yzw = 1.0 - isX;
+//  i0.y += dot( isYZ.xy, vec2( 1.0 ) );
+  i0.y += isYZ.x + isYZ.y;
+  i0.zw += 1.0 - isYZ.xy;
+  i0.z += isYZ.z;
+  i0.w += 1.0 - isYZ.z;
+
+  // i0 now contains the unique values 0,1,2,3 in each channel
+  vec4 i3 = clamp( i0, 0.0, 1.0 );
+  vec4 i2 = clamp( i0-1.0, 0.0, 1.0 );
+  vec4 i1 = clamp( i0-2.0, 0.0, 1.0 );
+
+  //  x0 = x0 - 0.0 + 0.0 * C.xxxx
+  //  x1 = x0 - i1  + 1.0 * C.xxxx
+  //  x2 = x0 - i2  + 2.0 * C.xxxx
+  //  x3 = x0 - i3  + 3.0 * C.xxxx
+  //  x4 = x0 - 1.0 + 4.0 * C.xxxx
+  vec4 x1 = x0 - i1 + C.xxxx;
+  vec4 x2 = x0 - i2 + C.yyyy;
+  vec4 x3 = x0 - i3 + C.zzzz;
+  vec4 x4 = x0 + C.wwww;
+
+// Permutations
+  i = mod289(i);
+  float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x);
+  vec4 j1 = permute( permute( permute( permute (
+             i.w + vec4(i1.w, i2.w, i3.w, 1.0 ))
+           + i.z + vec4(i1.z, i2.z, i3.z, 1.0 ))
+           + i.y + vec4(i1.y, i2.y, i3.y, 1.0 ))
+           + i.x + vec4(i1.x, i2.x, i3.x, 1.0 ));
+
+// Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
+// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
+  vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ;
+
+  vec4 p0 = grad4(j0,   ip);
+  vec4 p1 = grad4(j1.x, ip);
+  vec4 p2 = grad4(j1.y, ip);
+  vec4 p3 = grad4(j1.z, ip);
+  vec4 p4 = grad4(j1.w, ip);
+
+// Normalise gradients
+  vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
+  p0 *= norm.x;
+  p1 *= norm.y;
+  p2 *= norm.z;
+  p3 *= norm.w;
+  p4 *= taylorInvSqrt(dot(p4,p4));
+
+// Mix contributions from the five corners
+  vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0);
+  vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4)            ), 0.0);
+  m0 = m0 * m0;
+  m1 = m1 * m1;
+  return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 )))
+               + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ;
+
+  }
+
+#pragma glslify: export(snoise)
diff --git a/sdr/beam.f.glsl b/sdr/beam.f.glsl
new file mode 100644 (file)
index 0000000..5d7b89e
--- /dev/null
@@ -0,0 +1,4 @@
+void main()
+{
+       gl_FragColor = gl_Color;
+}
diff --git a/sdr/beam.v.glsl b/sdr/beam.v.glsl
new file mode 100644 (file)
index 0000000..a823e8b
--- /dev/null
@@ -0,0 +1,9 @@
+void main()
+{
+       float s = gl_Vertex.z + 1.0;
+
+       vec4 pos = gl_Vertex * vec4(s, s, 1.0, 1.0);
+
+       gl_Position = gl_ModelViewProjectionMatrix * pos;
+       gl_FrontColor = gl_Color;
+}
diff --git a/sdr/curve_top.f.glsl b/sdr/curve_top.f.glsl
new file mode 100644 (file)
index 0000000..5d7b89e
--- /dev/null
@@ -0,0 +1,4 @@
+void main()
+{
+       gl_FragColor = gl_Color;
+}
diff --git a/sdr/curve_top.v.glsl b/sdr/curve_top.v.glsl
new file mode 100644 (file)
index 0000000..afb7419
--- /dev/null
@@ -0,0 +1,9 @@
+#define PI 3.141592653589793
+void main()
+{
+       float s = 0.55 * cos(gl_Vertex.z * PI / 2.0 + PI / 2.0) + 1.02;
+       vec4 pos = gl_Vertex * vec4(s, s, 1.0, 1.0);
+
+       gl_Position = gl_ModelViewProjectionMatrix * pos;
+       gl_FrontColor = gl_Color;
+}
diff --git a/sdr/sky.f.glsl b/sdr/sky.f.glsl
new file mode 100644 (file)
index 0000000..1767b42
--- /dev/null
@@ -0,0 +1,92 @@
+float pnoise(vec2 P, vec2 rep);
+float pnoise_octaves();
+
+void main()
+{
+       float alt = min((gl_TexCoord[0].y + 0.29)* 2.0, 1.0);
+       float cloud_dens = 0.5; 
+
+       //const vec3 col_hor = vec3(0.96, 0.55, 0.98);
+       const vec3 col_hor = vec3(0.95, 0.38, 0.54);
+       const vec3 col_zen = vec3(0.05, 0.15, 0.32);
+
+       gl_FragColor.rgb = mix(col_hor, col_zen, alt);
+       gl_FragColor.a = 1.0;
+}
+
+
+//
+// GLSL textureless classic 2D noise "cnoise",
+// with an RSL-style periodic variant "pnoise".
+// Author:  Stefan Gustavson (stefan.gustavson@liu.se)
+// Version: 2011-08-22
+//
+// Many thanks to Ian McEwan of Ashima Arts for the
+// ideas for permutation and gradient selection.
+//
+// Copyright (c) 2011 Stefan Gustavson. All rights reserved.
+// Distributed under the MIT license. See LICENSE file.
+// https://github.com/ashima/webgl-noise
+//
+
+vec4 mod289(vec4 x)
+{
+  return x - floor(x * (1.0 / 289.0)) * 289.0;
+}
+
+vec4 permute(vec4 x)
+{
+  return mod289(((x*34.0)+1.0)*x);
+}
+
+vec4 taylorInvSqrt(vec4 r)
+{
+  return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+vec2 fade(vec2 t) {
+  return t*t*t*(t*(t*6.0-15.0)+10.0);
+}
+
+// Classic Perlin noise, periodic variant
+float pnoise(vec2 P, vec2 rep)
+{
+  vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);
+  vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);
+  Pi = mod(Pi, rep.xyxy); // To create noise with explicit period
+  Pi = mod289(Pi);        // To avoid truncation effects in permutation
+  vec4 ix = Pi.xzxz;
+  vec4 iy = Pi.yyww;
+  vec4 fx = Pf.xzxz;
+  vec4 fy = Pf.yyww;
+
+  vec4 i = permute(permute(ix) + iy);
+
+  vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ;
+  vec4 gy = abs(gx) - 0.5 ;
+  vec4 tx = floor(gx + 0.5);
+  gx = gx - tx;
+
+  vec2 g00 = vec2(gx.x,gy.x);
+  vec2 g10 = vec2(gx.y,gy.y);
+  vec2 g01 = vec2(gx.z,gy.z);
+  vec2 g11 = vec2(gx.w,gy.w);
+
+  vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
+  g00 *= norm.x;
+  g01 *= norm.y;
+  g10 *= norm.z;
+  g11 *= norm.w;
+
+  float n00 = dot(g00, vec2(fx.x, fy.x));
+  float n10 = dot(g10, vec2(fx.y, fy.y));
+  float n01 = dot(g01, vec2(fx.z, fy.z));
+  float n11 = dot(g11, vec2(fx.w, fy.w));
+
+  vec2 fade_xy = fade(Pf.xy);
+  vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
+  float n_xy = mix(n_x.x, n_x.y, fade_xy.y);
+  return 2.3 * n_xy;
+}
+
+#pragma glslify: export(pnoise)
diff --git a/sdr/sky.v.glsl b/sdr/sky.v.glsl
new file mode 100644 (file)
index 0000000..776bbce
--- /dev/null
@@ -0,0 +1,9 @@
+void main()
+{
+       gl_Position = ftransform();
+
+       vec3 p = normalize(gl_Vertex.xyz);
+       vec2 uv = vec2(atan(p.z, p.x), asin(p.y));
+
+       gl_TexCoord[0] = vec4(uv, 0.0, 0.0);
+}
diff --git a/src/main.cc b/src/main.cc
new file mode 100644 (file)
index 0000000..669ede3
--- /dev/null
@@ -0,0 +1,324 @@
+#include <GL/glew.h>
+#include <GL/freeglut.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "sdr.h"
+
+#define CURVE_VS "sdr/curve_top.v.glsl"
+#define CURVE_FS "sdr/curve_top.f.glsl"
+#define BEAM_VS "sdr/beam.v.glsl"
+#define BEAM_FS "sdr/beam.f.glsl"
+
+#define BEAM_SHELLS 40
+#define BEAM_RMIN 0.01
+#define BEAM_RMAX 0.125
+#define BEAM_ENERGY 0.02
+
+static bool init();
+static void cleanup();
+
+static void faros();
+static void light();
+static void ground();
+static void backdrop();
+
+static void display();
+static void idle();
+static void reshape(int x, int y);
+static void keyboard(unsigned char c, int x, int y);
+static void mbutton(int bn, int state, int x, int y);
+static void mmotion(int x, int y);
+
+static float cam_theta = 45, cam_phi, cam_dist = 10;
+static unsigned int sdr_curve_top, sdr_beam, sdr_sky;
+static unsigned int start_time;
+static float beam_rot_speed = 0.1;
+
+int main(int argc, char **argv)
+{
+       glutInit(&argc, argv);
+       glutInitWindowSize(800, 600);
+       glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
+
+       glutCreateWindow("Faros");
+
+       glutDisplayFunc(display);
+       glutIdleFunc(idle);
+       glutReshapeFunc(reshape);
+       glutKeyboardFunc(keyboard);
+       glutMouseFunc(mbutton);
+       glutMotionFunc(mmotion);
+
+       if(!init()) {
+               return 1;
+       }
+
+       atexit(cleanup);
+       glutMainLoop();
+
+       return 0;
+}
+
+static bool init()
+{
+       glewInit();
+
+       glEnable(GL_CULL_FACE);
+       glEnable(GL_DEPTH_TEST);
+       glEnable(GL_MULTISAMPLE);
+
+//     glEnable(GL_LIGHTING);
+       glEnable(GL_LIGHT0);
+
+       glEnable(GL_NORMALIZE);
+
+       if(!(sdr_curve_top = create_program_load(CURVE_VS, CURVE_FS)))
+               return false;
+
+       if(!(sdr_beam = create_program_load(BEAM_VS, BEAM_FS)))
+               return false;
+
+       if(!(sdr_sky = create_program_load("sdr/sky.v.glsl", "sdr/sky.f.glsl"))) {
+               return false;
+       }
+
+       start_time = glutGet(GLUT_ELAPSED_TIME);
+       return true;
+}
+
+static void cleanup()
+{
+}
+
+static void faros()
+{
+       glColor3f(0, 0, 0);
+
+       // kormos
+       glPushMatrix();
+       glScalef(1.1, 3, 1.1);
+       glTranslatef(0, 0.5, 0);
+       glutSolidCube(1.0);
+       glPopMatrix();
+
+       glShadeModel(GL_FLAT);
+
+       // base
+       glPushMatrix();
+       glRotatef(90, 1, 0, 0);
+       glTranslatef(0, -0.15, 0);
+       glutSolidCylinder(2, 0.3, 16, 1);
+       glPopMatrix();
+
+       // middle cylinder
+       glPushMatrix();
+       glTranslatef(0, 3, 0);
+       glRotatef(22.5, 0, 1, 0);
+       glRotatef(-90, 1, 0, 0);
+       glutSolidCylinder(0.5, 1.0, 8, 1);
+       glPopMatrix();
+
+       // trim middle cylinder (mporntoura)
+       glPushMatrix();
+       glTranslatef(0, 3.9, 0);
+       glRotatef(22.5, 0, 1, 0);
+       glRotatef(-90, 1, 0, 0);
+       glutSolidCylinder(0.55, 0.02, 8, 1);
+       glPopMatrix();
+
+       // top smaller cylinder
+       glPushMatrix();
+       glTranslatef(0, 4, 0);
+       glRotatef(22.5, 0, 1, 0);
+       glRotatef(-90, 1, 0, 0);
+       glutSolidCylinder(0.28, 0.5, 8, 1);
+       glPopMatrix();
+
+       // top wire even smaller cylinder
+       glPushMatrix();
+       glTranslatef(0, 4.5, 0);
+       glRotatef(22.5, 0, 1, 0);
+       glRotatef(-90, 1, 0, 0);
+       glutWireCylinder(0.18, 0.3, 9, 3);
+       glPopMatrix();
+
+       glShadeModel(GL_SMOOTH);
+
+       // top troulos
+       glPushMatrix();
+       glTranslatef(0, 4.8, 0);
+       glRotatef(22.5, 0, 1, 0);
+       glRotatef(-90, 1, 0, 0);
+       glutSolidCone(0.18, 0.2, 9, 1);
+       glPopMatrix();
+
+       // tsamploukano
+       glPushMatrix();
+       glTranslatef(-0.28, 4, 0);
+       glScalef(1, 13, 1);
+       glutSolidSphere(0.1, 16, 16);
+       glPopMatrix();
+
+       //pyramid on top of kormos
+       bind_program(sdr_curve_top);
+
+       glPushMatrix();
+       glTranslatef(0, 3, 0);
+       glRotatef(45, 0, 1, 0);
+       glRotatef(-90, 1, 0, 0);
+       glScalef(1, 1, 0.45);
+       glutSolidCylinder(1, 1, 4, 16);
+       glPopMatrix();
+       
+       bind_program(0);
+}
+
+static void light()
+{
+       glPushAttrib(GL_ENABLE_BIT);
+       glDisable(GL_CULL_FACE);
+
+       glPushMatrix();
+
+       glTranslatef(0, 4.65, 0.2);
+       bind_program(sdr_beam);
+
+       glEnable(GL_BLEND);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+
+       for(int i=0; i<BEAM_SHELLS; i++) {
+               float t = (float)i / (float)(BEAM_SHELLS - 1);
+               float rad = BEAM_RMIN + (BEAM_RMAX - BEAM_RMIN) * t;
+               float alpha = BEAM_ENERGY / t;
+
+               glColor4f(0.8, 0.8, 0.2, alpha);
+
+               glutSolidCylinder(rad, 6, 10, 1);
+       }
+
+       bind_program(0);
+
+       glPopMatrix();
+
+       glPopAttrib();
+}
+
+static void ground()
+{
+       glPushMatrix();
+
+       glTranslatef(0, -1.25, 0);
+       glScalef(1, 0.1, 1);
+
+       glColor3f(0, 0, 0);
+       glutSolidSphere(10, 32, 32);
+
+       glPopMatrix();
+}
+
+static void backdrop()
+{
+       glFrontFace(GL_CW);
+       bind_program(sdr_sky);
+       glutSolidSphere(200, 16, 32);
+       bind_program(0);
+       glFrontFace(GL_CCW);
+}
+
+static void display()
+{
+       unsigned int tmsec = glutGet(GLUT_ELAPSED_TIME) - start_time;
+       float tsec = (float)tmsec / 1000.0;
+
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+       backdrop();
+
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
+
+       glTranslatef(0, -2, -cam_dist);
+       glRotatef(cam_phi, 1, 0, 0);
+       glRotatef(cam_theta, 0, 1, 0);
+
+       ground();
+       faros();
+
+       glPushMatrix();
+
+       float beam_angle = tsec * beam_rot_speed * 360;
+
+       glRotatef(beam_angle, 0, 1, 0);
+       light();
+
+       glPopMatrix();
+
+       glutSwapBuffers();
+}
+
+static void idle()
+{
+       glutPostRedisplay();
+}
+
+static void reshape(int x, int y)
+{
+       glViewport(0, 0, x, y);
+
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+
+       gluPerspective(50, (float)x / (float)y, 0.5, 500);
+}
+
+static void keyboard(unsigned char c, int x, int y)
+{
+       switch(c) {
+       case 27:
+               exit(0);
+       default:
+               break;
+       }
+}
+
+static int prev_x, prev_y;
+static bool bst[8];
+static void mbutton(int bn, int state, int x, int y)
+{
+       int button = bn - GLUT_LEFT_BUTTON;
+       bst[button] = state == GLUT_DOWN;
+
+       prev_x = x;
+       prev_y = y;
+}
+
+static void mmotion(int x, int y)
+{
+       int dx = x - prev_x;
+       int dy = y - prev_y;
+
+       prev_x = x;
+       prev_y = y;
+
+       if (dx == 0 && dy == 0)
+               return;
+
+       if (bst[0]) {
+               cam_theta += dx * 0.5;
+               cam_phi += dy * 0.5;
+
+               if (cam_phi < -90)
+                       cam_phi = -90;
+
+               if (cam_phi > 90)
+                       cam_phi = 90;
+       }
+
+       if (bst[2]) {
+               cam_dist += dy * 0.1;
+
+               if (cam_dist < 0)
+                       cam_dist = 0;
+       }
+}
diff --git a/src/sdr.c b/src/sdr.c
new file mode 100644 (file)
index 0000000..5c7084c
--- /dev/null
+++ b/src/sdr.c
@@ -0,0 +1,563 @@
+#include <GL/glew.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#if defined(unix) || defined(__unix__)
+#include <unistd.h>
+#include <sys/stat.h>
+#endif /* unix */
+
+#include "sdr.h"
+
+static const char *sdrtypestr(unsigned int sdrtype);
+static int sdrtypeidx(unsigned int sdrtype);
+
+
+unsigned int create_vertex_shader(const char *src)
+{
+       return create_shader(src, GL_VERTEX_SHADER);
+}
+
+unsigned int create_pixel_shader(const char *src)
+{
+       return create_shader(src, GL_FRAGMENT_SHADER);
+}
+
+unsigned int create_tessctl_shader(const char *src)
+{
+#ifdef GL_TESS_CONTROL_SHADER
+       return create_shader(src, GL_TESS_CONTROL_SHADER);
+#else
+       return 0;
+#endif
+}
+
+unsigned int create_tesseval_shader(const char *src)
+{
+#ifdef GL_TESS_EVALUATION_SHADER
+       return create_shader(src, GL_TESS_EVALUATION_SHADER);
+#else
+       return 0;
+#endif
+}
+
+unsigned int create_geometry_shader(const char *src)
+{
+#ifdef GL_GEOMETRY_SHADER
+       return create_shader(src, GL_GEOMETRY_SHADER);
+#else
+       return 0;
+#endif
+}
+
+unsigned int create_shader(const char *src, unsigned int sdr_type)
+{
+       unsigned int sdr;
+       int success, info_len;
+       char *info_str = 0;
+       const char *src_str[3], *header, *footer;
+       int src_str_count = 0;
+       GLenum err;
+
+       if((header = get_shader_header(sdr_type))) {
+               src_str[src_str_count++] = header;
+       }
+       src_str[src_str_count++] = src;
+       if((footer = get_shader_footer(sdr_type))) {
+               src_str[src_str_count++] = footer;
+       }
+
+       sdr = glCreateShader(sdr_type);
+       assert(glGetError() == GL_NO_ERROR);
+       glShaderSource(sdr, src_str_count, src_str, 0);
+       err = glGetError();
+       assert(err == GL_NO_ERROR);
+       glCompileShader(sdr);
+       assert(glGetError() == GL_NO_ERROR);
+
+       glGetShaderiv(sdr, GL_COMPILE_STATUS, &success);
+       assert(glGetError() == GL_NO_ERROR);
+       glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len);
+       assert(glGetError() == GL_NO_ERROR);
+
+       if(info_len) {
+               if((info_str = malloc(info_len + 1))) {
+                       glGetShaderInfoLog(sdr, info_len, 0, info_str);
+                       assert(glGetError() == GL_NO_ERROR);
+                       info_str[info_len] = 0;
+               }
+       }
+
+       if(success) {
+               fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str);
+       } else {
+               fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str);
+               glDeleteShader(sdr);
+               sdr = 0;
+       }
+
+       free(info_str);
+       return sdr;
+}
+
+void free_shader(unsigned int sdr)
+{
+       glDeleteShader(sdr);
+}
+
+unsigned int load_vertex_shader(const char *fname)
+{
+       return load_shader(fname, GL_VERTEX_SHADER);
+}
+
+unsigned int load_pixel_shader(const char *fname)
+{
+       return load_shader(fname, GL_FRAGMENT_SHADER);
+}
+
+unsigned int load_tessctl_shader(const char *fname)
+{
+#ifdef GL_TESS_CONTROL_SHADER
+       return load_shader(fname, GL_TESS_CONTROL_SHADER);
+#else
+       return 0;
+#endif
+}
+
+unsigned int load_tesseval_shader(const char *fname)
+{
+#ifdef GL_TESS_EVALUATION_SHADER
+       return load_shader(fname, GL_TESS_EVALUATION_SHADER);
+#else
+       return 0;
+#endif
+}
+
+unsigned int load_geometry_shader(const char *fname)
+{
+#ifdef GL_GEOMETRY_SHADER
+       return load_shader(fname, GL_GEOMETRY_SHADER);
+#else
+       return 0;
+#endif
+}
+
+unsigned int load_shader(const char *fname, unsigned int sdr_type)
+{
+       unsigned int sdr;
+       size_t filesize;
+       FILE *fp;
+       char *src;
+
+       if(!(fp = fopen(fname, "rb"))) {
+               fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno));
+               return 0;
+       }
+
+       fseek(fp, 0, SEEK_END);
+       filesize = ftell(fp);
+       fseek(fp, 0, SEEK_SET);
+
+       if(!(src = malloc(filesize + 1))) {
+               fclose(fp);
+               return 0;
+       }
+       fread(src, 1, filesize, fp);
+       src[filesize] = 0;
+       fclose(fp);
+
+       fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname);
+       sdr = create_shader(src, sdr_type);
+
+       free(src);
+       return sdr;
+}
+
+
+/* ---- gpu programs ---- */
+
+unsigned int create_program(void)
+{
+       unsigned int prog = glCreateProgram();
+       assert(glGetError() == GL_NO_ERROR);
+       return prog;
+}
+
+unsigned int create_program_link(unsigned int sdr0, ...)
+{
+       unsigned int prog, sdr;
+       va_list ap;
+
+       if(!(prog = create_program())) {
+               return 0;
+       }
+
+       attach_shader(prog, sdr0);
+       if(glGetError()) {
+               return 0;
+       }
+
+       va_start(ap, sdr0);
+       while((sdr = va_arg(ap, unsigned int))) {
+               attach_shader(prog, sdr);
+               if(glGetError()) {
+                       return 0;
+               }
+       }
+       va_end(ap);
+
+       if(link_program(prog) == -1) {
+               free_program(prog);
+               return 0;
+       }
+       return prog;
+}
+
+unsigned int create_program_load(const char *vfile, const char *pfile)
+{
+       unsigned int vs = 0, ps = 0;
+
+       if(vfile && *vfile && !(vs = load_vertex_shader(vfile))) {
+               return 0;
+       }
+       if(pfile && *pfile && !(ps = load_pixel_shader(pfile))) {
+               return 0;
+       }
+       return create_program_link(vs, ps, 0);
+}
+
+void free_program(unsigned int sdr)
+{
+       glDeleteProgram(sdr);
+}
+
+void attach_shader(unsigned int prog, unsigned int sdr)
+{
+       int err;
+
+       if(prog && sdr) {
+               assert(glGetError() == GL_NO_ERROR);
+               glAttachShader(prog, sdr);
+               if((err = glGetError()) != GL_NO_ERROR) {
+                       fprintf(stderr, "failed to attach shader %u to program %u (err: 0x%x)\n", sdr, prog, err);
+                       abort();
+               }
+       }
+}
+
+int link_program(unsigned int prog)
+{
+       int linked, info_len, retval = 0;
+       char *info_str = 0;
+
+       glLinkProgram(prog);
+       assert(glGetError() == GL_NO_ERROR);
+       glGetProgramiv(prog, GL_LINK_STATUS, &linked);
+       assert(glGetError() == GL_NO_ERROR);
+       glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len);
+       assert(glGetError() == GL_NO_ERROR);
+
+       if(info_len) {
+               if((info_str = malloc(info_len + 1))) {
+                       glGetProgramInfoLog(prog, info_len, 0, info_str);
+                       assert(glGetError() == GL_NO_ERROR);
+                       info_str[info_len] = 0;
+               }
+       }
+
+       if(linked) {
+               fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str);
+       } else {
+               fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str);
+               retval = -1;
+       }
+
+       free(info_str);
+       return retval;
+}
+
+int bind_program(unsigned int prog)
+{
+       GLenum err;
+
+       glUseProgram(prog);
+       if(prog && (err = glGetError()) != GL_NO_ERROR) {
+               /* maybe the program is not linked, try linking first */
+               if(err == GL_INVALID_OPERATION) {
+                       if(link_program(prog) == -1) {
+                               return -1;
+                       }
+                       glUseProgram(prog);
+                       return glGetError() == GL_NO_ERROR ? 0 : -1;
+               }
+               return -1;
+       }
+       return 0;
+}
+
+/* ugly but I'm not going to write the same bloody code over and over */
+#define BEGIN_UNIFORM_CODE \
+       int loc, curr_prog; \
+       glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \
+       if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \
+               return -1; \
+       } \
+       if((loc = glGetUniformLocation(prog, name)) != -1)
+
+#define END_UNIFORM_CODE \
+       if((unsigned int)curr_prog != prog) { \
+               bind_program(curr_prog); \
+       } \
+       return loc == -1 ? -1 : 0
+
+int get_uniform_loc(unsigned int prog, const char *name)
+{
+       int loc, curr_prog;
+       glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog);
+       if((unsigned int)curr_prog != prog && bind_program(prog) == -1) {
+               return -1;
+       }
+       loc = glGetUniformLocation(prog, name);
+       if((unsigned int)curr_prog != prog) {
+               bind_program(curr_prog);
+       }
+       return loc;
+}
+
+int set_uniform_int(unsigned int prog, const char *name, int val)
+{
+       BEGIN_UNIFORM_CODE {
+               glUniform1i(loc, val);
+       }
+       END_UNIFORM_CODE;
+}
+
+int set_uniform_float(unsigned int prog, const char *name, float val)
+{
+       BEGIN_UNIFORM_CODE {
+               glUniform1f(loc, val);
+       }
+       END_UNIFORM_CODE;
+}
+
+int set_uniform_float2(unsigned int prog, const char *name, float x, float y)
+{
+       BEGIN_UNIFORM_CODE {
+               glUniform2f(loc, x, y);
+       }
+       END_UNIFORM_CODE;
+}
+
+int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z)
+{
+       BEGIN_UNIFORM_CODE {
+               glUniform3f(loc, x, y, z);
+       }
+       END_UNIFORM_CODE;
+}
+
+int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w)
+{
+       BEGIN_UNIFORM_CODE {
+               glUniform4f(loc, x, y, z, w);
+       }
+       END_UNIFORM_CODE;
+}
+
+int set_uniform_matrix4(unsigned int prog, const char *name, const float *mat)
+{
+       BEGIN_UNIFORM_CODE {
+               glUniformMatrix4fv(loc, 1, GL_FALSE, mat);
+       }
+       END_UNIFORM_CODE;
+}
+
+int set_uniform_matrix4_transposed(unsigned int prog, const char *name, const float *mat)
+{
+       BEGIN_UNIFORM_CODE {
+               glUniformMatrix4fv(loc, 1, GL_TRUE, mat);
+       }
+       END_UNIFORM_CODE;
+}
+
+int get_attrib_loc(unsigned int prog, const char *name)
+{
+       int loc, curr_prog;
+
+       glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog);
+       if((unsigned int)curr_prog != prog && bind_program(prog) == -1) {
+               return -1;
+       }
+
+       loc = glGetAttribLocation(prog, (char*)name);
+
+       if((unsigned int)curr_prog != prog) {
+               bind_program(curr_prog);
+       }
+       return loc;
+}
+
+void set_attrib_float3(int attr_loc, float x, float y, float z)
+{
+       glVertexAttrib3f(attr_loc, x, y, z);
+}
+
+/* ---- shader composition ---- */
+struct string {
+       char *text;
+       int len;
+};
+
+#define NUM_SHADER_TYPES       5
+static struct string header[NUM_SHADER_TYPES];
+static struct string footer[NUM_SHADER_TYPES];
+
+static void clear_string(struct string *str)
+{
+       free(str->text);
+       str->text = 0;
+       str->len = 0;
+}
+
+static void append_string(struct string *str, const char *s)
+{
+       int len, newlen;
+       char *newstr;
+
+       if(!s || !*s) return;
+
+       len = strlen(s);
+       newlen = str->len + len;
+       if(!(newstr = malloc(newlen + 2))) {    /* leave space for a possible newline */
+               fprintf(stderr, "shader composition: failed to append string of size %d\n", len);
+               abort();
+       }
+
+       if(str->text) {
+               memcpy(newstr, str->text, str->len);
+       }
+       memcpy(newstr + str->len, s, len + 1);
+
+       if(s[len - 1] != '\n') {
+               newstr[newlen] = '\n';
+               newstr[newlen + 1] = 0;
+       }
+
+       free(str->text);
+       str->text = newstr;
+       str->len = newlen;
+}
+
+void clear_shader_header(unsigned int type)
+{
+       if(type) {
+               int idx = sdrtypeidx(type);
+               clear_string(&header[idx]);
+       } else {
+               int i;
+               for(i=0; i<NUM_SHADER_TYPES; i++) {
+                       clear_string(&header[i]);
+               }
+       }
+}
+
+void clear_shader_footer(unsigned int type)
+{
+       if(type) {
+               int idx = sdrtypeidx(type);
+               clear_string(&footer[idx]);
+       } else {
+               int i;
+               for(i=0; i<NUM_SHADER_TYPES; i++) {
+                       clear_string(&footer[i]);
+               }
+       }
+}
+
+void add_shader_header(unsigned int type, const char *s)
+{
+       if(type) {
+               int idx = sdrtypeidx(type);
+               append_string(&header[idx], s);
+       } else {
+               int i;
+               for(i=0; i<NUM_SHADER_TYPES; i++) {
+                       append_string(&header[i], s);
+               }
+       }
+}
+
+void add_shader_footer(unsigned int type, const char *s)
+{
+       if(type) {
+               int idx = sdrtypeidx(type);
+               append_string(&footer[idx], s);
+       } else {
+               int i;
+               for(i=0; i<NUM_SHADER_TYPES; i++) {
+                       append_string(&footer[i], s);
+               }
+       }
+}
+
+const char *get_shader_header(unsigned int type)
+{
+       int idx = sdrtypeidx(type);
+       return header[idx].text;
+}
+
+const char *get_shader_footer(unsigned int type)
+{
+       int idx = sdrtypeidx(type);
+       return footer[idx].text;
+}
+
+static const char *sdrtypestr(unsigned int sdrtype)
+{
+       switch(sdrtype) {
+       case GL_VERTEX_SHADER:
+               return "vertex";
+       case GL_FRAGMENT_SHADER:
+               return "pixel";
+#ifdef GL_TESS_CONTROL_SHADER
+       case GL_TESS_CONTROL_SHADER:
+               return "tessellation control";
+#endif
+#ifdef GL_TESS_EVALUATION_SHADER
+       case GL_TESS_EVALUATION_SHADER:
+               return "tessellation evaluation";
+#endif
+#ifdef GL_GEOMETRY_SHADER
+       case GL_GEOMETRY_SHADER:
+               return "geometry";
+#endif
+
+       default:
+               break;
+       }
+       return "<unknown>";
+}
+
+static int sdrtypeidx(unsigned int sdrtype)
+{
+       switch(sdrtype) {
+       case GL_VERTEX_SHADER:
+               return 0;
+       case GL_FRAGMENT_SHADER:
+               return 1;
+       case GL_TESS_CONTROL_SHADER:
+               return 2;
+       case GL_TESS_EVALUATION_SHADER:
+               return 3;
+       case GL_GEOMETRY_SHADER:
+               return 4;
+       default:
+               break;
+       }
+       return 0;
+}
diff --git a/src/sdr.h b/src/sdr.h
new file mode 100644 (file)
index 0000000..7bf2389
--- /dev/null
+++ b/src/sdr.h
@@ -0,0 +1,68 @@
+#ifndef SDR_H_
+#define SDR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* ---- shaders ---- */
+unsigned int create_vertex_shader(const char *src);
+unsigned int create_pixel_shader(const char *src);
+unsigned int create_tessctl_shader(const char *src);
+unsigned int create_tesseval_shader(const char *src);
+unsigned int create_geometry_shader(const char *src);
+unsigned int create_shader(const char *src, unsigned int sdr_type);
+void free_shader(unsigned int sdr);
+
+unsigned int load_vertex_shader(const char *fname);
+unsigned int load_pixel_shader(const char *fname);
+unsigned int load_tessctl_shader(const char *fname);
+unsigned int load_tesseval_shader(const char *fname);
+unsigned int load_geometry_shader(const char *fname);
+unsigned int load_shader(const char *src, unsigned int sdr_type);
+
+int add_shader(const char *fname, unsigned int sdr);
+int remove_shader(const char *fname);
+
+/* ---- gpu programs ---- */
+unsigned int create_program(void);
+unsigned int create_program_link(unsigned int sdr0, ...);
+unsigned int create_program_load(const char *vfile, const char *pfile);
+void free_program(unsigned int sdr);
+
+void attach_shader(unsigned int prog, unsigned int sdr);
+int link_program(unsigned int prog);
+int bind_program(unsigned int prog);
+
+int get_uniform_loc(unsigned int prog, const char *name);
+
+int set_uniform_int(unsigned int prog, const char *name, int val);
+int set_uniform_float(unsigned int prog, const char *name, float val);
+int set_uniform_float2(unsigned int prog, const char *name, float x, float y);
+int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z);
+int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w);
+int set_uniform_matrix4(unsigned int prog, const char *name, const float *mat);
+int set_uniform_matrix4_transposed(unsigned int prog, const char *name, const float *mat);
+
+int get_attrib_loc(unsigned int prog, const char *name);
+void set_attrib_float3(int attr_loc, float x, float y, float z);
+
+/* ---- shader composition ---- */
+
+/* clear shader header/footer text.
+ * pass the shader type to clear, or 0 to clear all types */
+void clear_shader_header(unsigned int type);
+void clear_shader_footer(unsigned int type);
+/* append text to the header/footer of a specific shader type
+ * or use type 0 to add it to all shade types */
+void add_shader_header(unsigned int type, const char *s);
+void add_shader_footer(unsigned int type, const char *s);
+/* get the current header/footer text for a specific shader type */
+const char *get_shader_header(unsigned int type);
+const char *get_shader_footer(unsigned int type);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SDR_H_ */