From e288b11ca263beae92f508ca53e1500f0ce68377 Mon Sep 17 00:00:00 2001 From: Eleni Maria Stea Date: Mon, 1 Oct 2018 16:42:01 +0300 Subject: [PATCH] faros initial commit --- Makefile | 28 +++ glsl-noise/LICENSE | 20 ++ glsl-noise/README.md | 30 +++ glsl-noise/classic/2d.glsl | 74 ++++++ glsl-noise/classic/3d.glsl | 109 +++++++++ glsl-noise/classic/4d.glsl | 169 +++++++++++++ glsl-noise/package.json | 27 +++ glsl-noise/periodic/2d.glsl | 75 ++++++ glsl-noise/periodic/3d.glsl | 109 +++++++++ glsl-noise/periodic/4d.glsl | 169 +++++++++++++ glsl-noise/simplex/2d.glsl | 72 ++++++ glsl-noise/simplex/3d.glsl | 104 ++++++++ glsl-noise/simplex/4d.glsl | 130 ++++++++++ sdr/beam.f.glsl | 4 + sdr/beam.v.glsl | 9 + sdr/curve_top.f.glsl | 4 + sdr/curve_top.v.glsl | 9 + sdr/sky.f.glsl | 92 +++++++ sdr/sky.v.glsl | 9 + src/main.cc | 324 +++++++++++++++++++++++++ src/sdr.c | 563 +++++++++++++++++++++++++++++++++++++++++++ src/sdr.h | 68 ++++++ 22 files changed, 2198 insertions(+) create mode 100644 Makefile create mode 100644 glsl-noise/LICENSE create mode 100644 glsl-noise/README.md create mode 100644 glsl-noise/classic/2d.glsl create mode 100644 glsl-noise/classic/3d.glsl create mode 100644 glsl-noise/classic/4d.glsl create mode 100644 glsl-noise/package.json create mode 100644 glsl-noise/periodic/2d.glsl create mode 100644 glsl-noise/periodic/3d.glsl create mode 100644 glsl-noise/periodic/4d.glsl create mode 100644 glsl-noise/simplex/2d.glsl create mode 100644 glsl-noise/simplex/3d.glsl create mode 100644 glsl-noise/simplex/4d.glsl create mode 100644 sdr/beam.f.glsl create mode 100644 sdr/beam.v.glsl create mode 100644 sdr/curve_top.f.glsl create mode 100644 sdr/curve_top.v.glsl create mode 100644 sdr/sky.f.glsl create mode 100644 sdr/sky.v.glsl create mode 100644 src/main.cc create mode 100644 src/sdr.c create mode 100644 src/sdr.h diff --git a/Makefile b/Makefile new file mode 100644 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 index 0000000..001a9e5 --- /dev/null +++ b/glsl-noise/LICENSE @@ -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 index 0000000..e802225 --- /dev/null +++ b/glsl-noise/README.md @@ -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 index 0000000..20b6e3e --- /dev/null +++ b/glsl-noise/classic/2d.glsl @@ -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 index 0000000..6fe889a --- /dev/null +++ b/glsl-noise/classic/3d.glsl @@ -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 index 0000000..3c90879 --- /dev/null +++ b/glsl-noise/classic/4d.glsl @@ -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 index 0000000..97c14e3 --- /dev/null +++ b/glsl-noise/package.json @@ -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 index 0000000..c267970 --- /dev/null +++ b/glsl-noise/periodic/2d.glsl @@ -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 index 0000000..b88ffa6 --- /dev/null +++ b/glsl-noise/periodic/3d.glsl @@ -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 index 0000000..a754ba4 --- /dev/null +++ b/glsl-noise/periodic/4d.glsl @@ -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 index 0000000..7c89a87 --- /dev/null +++ b/glsl-noise/simplex/2d.glsl @@ -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 index 0000000..711e5bf --- /dev/null +++ b/glsl-noise/simplex/3d.glsl @@ -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 index 0000000..76ee01c --- /dev/null +++ b/glsl-noise/simplex/4d.glsl @@ -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 index 0000000..5d7b89e --- /dev/null +++ b/sdr/beam.f.glsl @@ -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 index 0000000..a823e8b --- /dev/null +++ b/sdr/beam.v.glsl @@ -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 index 0000000..5d7b89e --- /dev/null +++ b/sdr/curve_top.f.glsl @@ -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 index 0000000..afb7419 --- /dev/null +++ b/sdr/curve_top.v.glsl @@ -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 index 0000000..1767b42 --- /dev/null +++ b/sdr/sky.f.glsl @@ -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 index 0000000..776bbce --- /dev/null +++ b/sdr/sky.v.glsl @@ -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 index 0000000..669ede3 --- /dev/null +++ b/src/main.cc @@ -0,0 +1,324 @@ +#include +#include + +#include +#include + +#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 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 index 0000000..5c7084c --- /dev/null +++ b/src/sdr.c @@ -0,0 +1,563 @@ +#include + +#include +#include +#include +#include +#include +#include + +#if defined(unix) || defined(__unix__) +#include +#include +#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"; +} + +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 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_ */ -- 1.7.10.4