packages feed

hylogen 0.1.0.3 → 0.1.0.4

raw patch · 5 files changed

+145/−81 lines, 5 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ Hylogen.Globals: audio :: Vec4

Files

README.md view
@@ -5,7 +5,7 @@ ## Setup ``` cabal update-cabal install ghcid hylogen+cabal install hylogen ``` ## Usage 
app/index.html view
@@ -107,105 +107,167 @@  function loadProgram (gl, state, vsSource, fsSource) { -  // compileShader :: (gl, source, shaderType) -> Shader-  // throws Error on compilation error+    // compileShader :: (gl, source, shaderType) -> Shader+    // throws Error on compilation error -  function compileShader (gl, source, shaderType) {-    //assert(shaderType === gl.FRAGMENT_SHADER || shaderType === g.VERTEXT_SHADER);+    function compileShader (gl, source, shaderType) {+        //assert(shaderType === gl.FRAGMENT_SHADER || shaderType === g.VERTEXT_SHADER); -    let shader = gl.createShader(shaderType);+        let shader = gl.createShader(shaderType); -    gl.shaderSource(shader, source);-    gl.compileShader(shader);+        gl.shaderSource(shader, source);+        gl.compileShader(shader);  -    let success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);-    if (!success) {-      throw "could not compile shader:" + gl.getShaderInfoLog(shader);-    }+        let success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);+        if (!success) {+            throw "could not compile shader:" + gl.getShaderInfoLog(shader);+        } -    return shader;-  };+        return shader;+    };   -  let vs = compileShader(gl, vsSource, gl.VERTEX_SHADER);-  let fs = compileShader(gl, fsSource, gl.FRAGMENT_SHADER);+    let vs = compileShader(gl, vsSource, gl.VERTEX_SHADER);+    let fs = compileShader(gl, fsSource, gl.FRAGMENT_SHADER);  -  let program = gl.createProgram();+    let program = gl.createProgram(); -  gl.attachShader(program, vs);-  gl.attachShader(program, fs);+    gl.attachShader(program, vs);+    gl.attachShader(program, fs); -  gl.linkProgram(program);+    gl.linkProgram(program); -  let success = gl.getProgramParameter(program, gl.LINK_STATUS);-  if (!success) {-    throw ("program failed to link:" + gl.getProgramInfoLog(program));-  }+    let success = gl.getProgramParameter(program, gl.LINK_STATUS);+    if (!success) {+        throw ("program failed to link:" + gl.getProgramInfoLog(program));+    } -  gl.useProgram(program);+    gl.useProgram(program);  -  // Create a square as a strip of two triangles.-  gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());-  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ -1,1,0, 1,1,0, -1,-1,0, 1,-1,0 ]), gl.STATIC_DRAW);+    // Create a square as a strip of two triangles.+    gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());+    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ -1,1,0, 1,1,0, -1,-1,0, 1,-1,0 ]), gl.STATIC_DRAW); -  // Assign attribute aPosition to each of the square's vertices.-  gl.aPosition = gl.getAttribLocation(program, "aPosition");-  gl.enableVertexAttribArray(gl.aPosition);-  gl.vertexAttribPointer(gl.aPosition, 3, gl.FLOAT, false, 0, 0);+    // Assign attribute aPosition to each of the square's vertices.+    gl.aPosition = gl.getAttribLocation(program, "aPosition");+    gl.enableVertexAttribArray(gl.aPosition);+    gl.vertexAttribPointer(gl.aPosition, 3, gl.FLOAT, false, 0, 0); -  // remember the address within the fragment shader of each of my uniforms variables-  gl.time = gl.getUniformLocation(program, "time");-  gl.mouse = gl.getUniformLocation(program, "mouse");+    // remember the address within the fragment shader of each of my uniforms variables+    gl.time = gl.getUniformLocation(program, "time");+    gl.mouse = gl.getUniformLocation(program, "mouse");+    gl.audio = gl.getUniformLocation(program, "audio"); -  draw(gl, state);+    draw(gl, state); -  if (state.animationFrameRequest === null) {-    state.animationFrameRequest = requestAnimationFrame(() => animate(gl, state));-  }+    if (state.animationFrameRequest === null) {+        state.animationFrameRequest = requestAnimationFrame(() => animate(gl, state));+    } }  function draw (gl, state) { -  gl.uniform1f(gl.time, (new Date().getTime() / 1000 - state.time0));-  gl.uniform3f(gl.mouse, state.mouse.x, state.mouse.y, state.mouse.z);+    gl.uniform1f(gl.time, (new Date().getTime() / 1000 - state.time0));+    gl.uniform3f(gl.mouse, state.mouse.x, state.mouse.y, state.mouse.z);+    gl.uniform4f(gl.audio, state.audio.low, state.audio.mid, state.audio.upper, state.audio.high); -  gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);+    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); };  function animate (gl, state) {-  draw(gl, state);-  state.animationFrameRequest = requestAnimationFrame(() => animate(gl, state));+    draw(gl, state);+    state.animationFrameRequest = requestAnimationFrame(() => animate(gl, state)); };    function setupState (state, canvas){-  function setMouse (event, z) {-    let r = event.target.getBoundingClientRect();-    state.mouse.x = (event.clientX - r.left) / (r.right - r.left) * 2 -1;-    state.mouse.y = (event.clientY - r.bottom) / (r.top - r.bottom) * 2 - 1;+    state.animationFrameRequest = null; -    if (z !== undefined) {-      state.mouse.z = z;-    }-  };+    state.time0 = new Date() / 1000; -  state.animationFrameRequest = null; -  state.time0 = new Date() / 1000;+    function setMouse (event, z) {+        let r = event.target.getBoundingClientRect();+        state.mouse.x = (event.clientX - r.left) / (r.right - r.left) * 2 -1;+        state.mouse.y = (event.clientY - r.bottom) / (r.top - r.bottom) * 2 - 1; +        if (z !== undefined) {+            state.mouse.z = z;+        }+    };+    canvas.onmousedown = (event) => setMouse(event, 1);+    canvas.onmousemove = (event) => setMouse(event);+    canvas.onmouseup = (event) => setMouse(event, 0);+    state.mouse = {x: 0, y: 0, z: 0}; -  canvas.onmousedown = (event) => setMouse(event, 1);-  canvas.onmousemove = (event) => setMouse(event);-  canvas.onmouseup = (event) => setMouse(event, 0); -  state.mouse = {x: 0, y: 0, z: 0};+    state.audio = {low: 0.0, mid: 0.0, upper: 0.0, high: 0.0};+    state.audioAgain = null;+    navigator.mediaDevices.getUserMedia( {audio: true})+      .then((stream) => {+        let audioCtx = new (window.AudioContext || window.webkitAudioContext)();+        let source = audioCtx.createMediaStreamSource(stream);+        let analyser = audioCtx.createAnalyser();+        source.connect(analyser); -  // TODO: implement Audio+        analyser.fftSize = 512;+        let bufferLength = analyser.frequencyBinCount;+        let dataArray = new Uint8Array(bufferLength);+++        function toAudio() {+          state.audioAgain = requestAnimationFrame(toAudio);+          analyser.getByteFrequencyData(dataArray);++            // Taken from The_Force+            let k = 0, f = 0.0;+            let a = 5, b = 11, c = 24, d = bufferLength, i = 0;++            for(; i < a; i++) {+                f += dataArray[i];+            }++            f *= .2; // 1/(a-0)+            f *= .003921569; // 1/255+            state.audio.low = f;++            f = 0.0;+            for(; i < b; i++) {+                f += dataArray[i];+            }++            f *= .166666667; // 1/(b-a)+            f *= .003921569; // 1/255+            state.audio.mid = f;++            f = 0.0;+            for(; i < c; i++) {+                f += dataArray[i];+            }++            f *= .076923077; // 1/(c-b)+            f *= .003921569; // 1/255+            state.audio.upper = f;++            f = 0.0;+            for(; i < d; i++) {+                f += dataArray[i];+            }+            f *= .00204918; // 1/(d-c)+            f *= .003921569; // 1/255+            state.audio.high = f;+        };++        toAudio();++      })+      .catch((err) => {console.log(err);});+ }  @@ -228,34 +290,34 @@   function fadeOut(elem) {-  elem.className = "removing";-  window.setTimeout(function() {-    elem.remove();-  }, 1000);+    elem.className = "removing";+    window.setTimeout(function() {+        elem.remove();+    }, 1000); }  function connectToHylogen() {-  const wsConn = new WebSocket("ws://localhost:8080/");+    const wsConn = new WebSocket("ws://localhost:8080/"); -  wsConn.onopen = function() {-    const landing = document.getElementById("landing");-    if (landing) {-      fadeOut(document.getElementById("bg"));-      window.setTimeout(() => {fadeOut(landing);}, 500);-    }-    console.log('websocket opened');+    wsConn.onopen = function() {+        const landing = document.getElementById("landing");+        if (landing) {+            fadeOut(document.getElementById("bg"));+            window.setTimeout(() => {fadeOut(landing);}, 500);+        }+        console.log('websocket opened'); -  };+    }; -  wsConn.onclose = function() {-    console.log('websocket closed');-    window.setTimeout(connectToHylogen, 100);-  };+    wsConn.onclose = function() {+        console.log('websocket closed');+        window.setTimeout(connectToHylogen, 100);+    }; -  wsConn.onmessage = function (m) {-    console.log(m.data);-    loadProgram(gl, state,  vsSource, m.data);-  };+    wsConn.onmessage = function (m) {+        console.log(m.data);+        loadProgram(gl, state,  vsSource, m.data);+    }; }  connectToHylogen();
hylogen.cabal view
@@ -1,5 +1,5 @@ name:                hylogen-version:             0.1.0.3+version:             0.1.0.4 synopsis:            a tiny EDSL for live-coding fragment shaders description:         a tiny EDSL for live-coding fragment shaders homepage:            https://github.com/sleexyz/hylogen
src/Hylogen.hs view
@@ -33,6 +33,7 @@     boiler = unlines $ [ "precision mediump float;"                        , "uniform float time;"                        , "uniform vec3 mouse;"+                       , "uniform vec4 audio;"                        , "const float PI = 3.141592653589793238462643383; "                        , "varying vec3 uv;"                        ]
src/Hylogen/Globals.hs view
@@ -26,3 +26,4 @@   -- coord_ = V4u "gl_FragCoord"+audio = V4u "audio"