<!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/x-javascript" src="../unit.js"></script>
<script type="application/x-javascript" src="../util.js"></script>
<script type="application/x-javascript">

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

Tests.setup = function(gl) {
  var tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  var texCubeMap = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap);
  return [gl]
}

Tests.teardown = function(gl,tex,texCubeMap) {
  gl.bindTexture(gl.TEXTURE_2D, null);
  gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
  gl.deleteTexture(tex);
  gl.deleteTexture(texCubeMap);
}


Tests.testTexImage2D = function(gl) {
  gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0,16,16,0);
  gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0,1,1);
  gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0,2,1);
  gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0,1,2);
  gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0,16,16);
  gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 15,15,1,1);
  gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 1,1, 0,0,15,15);
  gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 15,15, 0,0,1,1);
  var valid_targets = [
    gl.TEXTURE_2D,
    gl.TEXTURE_CUBE_MAP_POSITIVE_X,
    gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
    gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
    gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
    gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
    gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
  ];
  valid_targets.forEach(function(t) {
    assertOk(function(){
        gl.copyTexImage2D(t, 0, gl.RGBA, 0,0,1,1,0);
        gl.copyTexSubImage2D(t, 0, 0,0,0,0,1,1);
    });
  });
}
Tests.testRoundtrip = function(gl) {
    var sh = new Filter(gl, 'identity-flip-vert', 'identity-frag');
    gl.clearColor(1.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    var buf = new Uint8Array(4);
    gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, buf);
    assertEquals([255,0,0,255], [buf[0], buf[1], buf[2], buf[3]]);
    // red texture
    gl.clearColor(0.0, 0.0, 0.0, 0.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, document.getElementById('gl'));
    gl.clearColor(1.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0,0,0,16,16);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.clearColor(0.0, 0.0, 1.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    // blue framebuffer
    gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, buf);
    assertEquals([0,0,255,255], [buf[0], buf[1], buf[2], buf[3]]);
    sh.apply(); // paint with texture
    gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, buf);
    assertEquals([255,0,0,255], [buf[0], buf[1], buf[2], buf[3]]);
    sh.destroy();
}

Tests.endUnit = function(gl) {
}

</script>
<script id="identity-flip-vert" type="x-shader/x-vertex">
attribute vec3 Vertex;
attribute vec2 Tex;

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

uniform sampler2D Texture;

varying vec4 texCoord0;
void main()
{
    vec4 c = texture2D(Texture, texCoord0.st);
    gl_FragColor = c;
}
</script>
<style>canvas{ position:absolute; }</style>
</head><body>
<canvas id="gl" width="16" height="16"></canvas>
</body></html>
