<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--

/*
** Copyright (c) 2012 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are 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 Materials.
**
** THE MATERIALS ARE 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
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/

-->
<link rel="stylesheet" type="text/css" href="../unit.css" />
<script type="application/javascript" src="../unit.js"></script>
<script type="application/javascript" src="../util.js"></script>
<script type="application/javascript">

Tests.startUnit = function () {
  var canvas = document.getElementById('gl');
  var gl = getGLContext(canvas);
  return [gl];
}

Tests.autorun = false;
Tests.message = "Caution: might hang your GPU"

var arr = ['whiletrue', 'loop100M', 'loopComp', 'variable'];
arr.forEach(function(e){
    Tests['test'+e+'vert'] = function(gl) {
        var sh = new Filter(gl, e+'vert', 'frag');
        assertOk(function(){
            sh.apply();
        });
        sh.destroy();
    }
    Tests['test'+e+'frag'] = function(gl) {
        var sh = new Filter(gl, 'vert', e+'frag');
        assertOk(function(){
            sh.apply();
        });
        sh.destroy();
    }
});

Tests.testMandelbrot = function(gl) {
    gl.disable(gl.DEPTH_TEST);
    var sh = new Filter(gl, 'identity-vert', 'mandelbrot-frag');
    sh.apply(function(s){
        s.uniform1f('z', 0.15);
        s.uniform1f('x', -1.25);
    });
    for (var i=0; i<256; i++) {
        sh.apply();
    }
    sh.destroy();
}

</script>
<script id="identity-vert" type="x-shader/x-vertex">

  attribute vec3 Vertex;
  attribute vec2 Tex;

  varying vec2 texCoord0;
  void main()
  {
    texCoord0 = vec2(Tex.s, Tex.t);
    gl_Position = vec4(Vertex, 1.0);
  }
</script>
<script id="mandelbrot-frag" type="x-shader/x-fragment">
    precision mediump float;

    uniform float x,y,z;
    varying vec2 texCoord0;
    vec4 iter_z(float cr, float ci) {
        int i;
        float nzr, nzi, zr = 0.0, zi = 0.0;
        vec4 color = vec4(0.0);
        for (i=0; i<2500; i++) {
            nzr = zr * zr - zi * zi + cr;
            nzi = 2.0 * zr * zi + ci;
            zr = nzr;
            zi = nzi;
        }
        color = vec4(zi);
        color.a = 1.0;
        return color;
    }

    void main()
    {
        gl_FragColor = iter_z(x+z*(2.0*texCoord0.s-1.5), y+z*(2.0*texCoord0.t-1.0));
    }
</script>
<script id="whiletruevert" type="x-shader/x-vertex">


    attribute vec3 Vertex; attribute vec2 Tex;
    varying vec2 TexCoord;
    void main()
    {
        float z = 1.0;
        while(true) { z += 0.1; z *= 0.995; }
        TexCoord = Tex.st;
        gl_Position = vec4(Vertex, z);
    }
</script>
<script id="loop100Mvert" type="x-shader/x-vertex">


    attribute vec3 Vertex; attribute vec2 Tex;
    varying vec2 TexCoord;
    void main()
    {
        int i;
        float z = 1.0;
        for (i = 0; i<1000000000; i++) {
            z += 0.1; z *= 0.995;
        }
        TexCoord = Tex.st;
        gl_Position = vec4(Vertex, z);
    }
</script>
<script id="loopCompvert" type="x-shader/x-vertex">


    attribute vec3 Vertex; attribute vec2 Tex;
    varying vec2 TexCoord;
    void main()
    {
        float z = 1.0;
        while(z > 0.0) { z += 0.1; z *= 0.995; }
        TexCoord = Tex.st;
        gl_Position = vec4(Vertex, z);
    }
</script>
<script id="variablevert" type="x-shader/x-vertex">


    attribute vec3 Vertex; attribute vec2 Tex;
    varying vec2 TexCoord;

    void main()
    {
        float z = 1.0;
        while(z > Vertex.z) { z += 0.1; z *= 0.995; }
        TexCoord = Tex.st;
        gl_Position = vec4(Vertex, z);
    }
</script>
<script id="vert" type="x-shader/x-vertex">


    attribute vec3 Vertex; attribute vec2 Tex;
    varying vec2 TexCoord;
    void main()
    {
        TexCoord = Tex.st;
        gl_Position = vec4(Vertex, 0.0);
    }
</script>

<script id="whiletruefrag" type="x-shader/x-fragment">


    precision mediump float;

    varying vec2 TexCoord;
    void main()
    {
        float z = 1.0;
        while(true) { z += 0.1; z *= 0.995; }
        gl_FragColor = vec4(1.0, TexCoord.s, TexCoord.t, z);
    }
</script>
<script id="loop100Mfrag" type="x-shader/x-fragment">


    precision mediump float;

    varying vec2 TexCoord;
    void main()
    {
        int i;
        float z = 1.0;
        for (i = 0; i<1000000000; i++) {
            z += 0.1; z *= 0.995;
        }
        gl_FragColor = vec4(1.0, TexCoord.s, TexCoord.t, z);
    }
</script>
<script id="loopCompfrag" type="x-shader/x-fragment">


    precision mediump float;

    varying vec2 TexCoord;
    void main()
    {
        float z = TexCoord.s;
        while(z > 0.0) { z += 0.1; z *= 0.995; }
        gl_FragColor = vec4(1.0, TexCoord.s, TexCoord.t, z);
    }
</script>
<script id="variablefrag" type="x-shader/x-fragment">


    precision mediump float;

    varying vec2 TexCoord;
    void main()
    {
        float z = 1.0;
        while(z > TexCoord.s) { z += 0.1; z *= 0.995; }
        gl_FragColor = vec4(1.0, TexCoord.s, TexCoord.t, z);
    }
</script>
<script id="frag" type="x-shader/x-fragment">


  precision mediump float;

  varying vec2 TexCoord;
  void main()
  {
    gl_FragColor = vec4(1.0, TexCoord.s, TexCoord.t, 1.0);
  }
</script>


<style>canvas{ position:absolute; }</style>
</head><body>
  <canvas id="gl" width="512" height="512"></canvas>
</body></html>
