<!--

/*
** 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.
*/

-->

<!DOCTYPE html>
<html>
  <head>
<meta charset="utf-8">
    <title>WebGL TexParameter conformance test.</title>
    <link rel="stylesheet" href="../../resources/js-test-style.css"/>
    <script src="../../resources/js-test-pre.js"></script>
    <script src="../resources/webgl-test.js"> </script>
    <script src="../resources/webgl-test-utils.js"> </script>
</head>
<body>
<canvas id="example" width="24" height="24"></canvas>
<canvas id="canvas2d" width="2" height="2"></canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
uniform mat4 world;
attribute vec3 vPosition;
attribute vec2 texCoord0;
varying vec2 texCoord;
void main()
{
  gl_Position = world * vec4(vPosition, 1);
  texCoord = texCoord0;
}
</script>

<script id="fshader" type="x-shader/x-fragment">
precision mediump float;

uniform sampler2D tex;
varying vec2 texCoord;
void main()
{
  gl_FragColor = texture2D(tex, texCoord);
}
</script>

<script>
"use strict";
function init()
{
  description("Tests TexParameter works as expected");
  debug("");

  var canvas2d = document.getElementById("canvas2d");
  var ctx2d = canvas2d.getContext("2d");

  var wtu = WebGLTestUtils;
  var gl = wtu.create3DContext("example");
  var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition", "texCoord0"]);

  var vertexObject = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
  gl.bufferData(
      gl.ARRAY_BUFFER,
      new Float32Array([-1, 1,0, 1,1,0, -1,-1,0,
                           -1,-1,0, 1,1,0,  1,-1,0]),
      gl.STATIC_DRAW);
  gl.enableVertexAttribArray(0);
  gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);

  var vertexObject = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
  gl.bufferData(
      gl.ARRAY_BUFFER,
      new Float32Array([ -2.5,-2.5, 3.5,-2.5, -2.5,3.5,
                            -2.5,3.5, 3.5,-2.5, 3.5,3.5]),
      gl.STATIC_DRAW);
  gl.enableVertexAttribArray(1);
  gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);

  var colors = [
      [0,255,128,255],
      [128,64,255,255],
      [192,255,64,255],
      [200,0,255,255]];
  var texParam = [
    gl.REPEAT,
    gl.CLAMP_TO_EDGE,
    gl.MIRRORED_REPEAT,
    gl.REPEAT];

  // Make textures setting the texture parameters differently each time..
  // This verifies both that the render correct AND that texture parameters
  // are associated with the textures, not with the texture-units.
  var textures = [];
  for (var ii = 0; ii < colors.length; ++ii) {
    var c = colors[ii];
    ctx2d.fillStyle =
        "rgba(" + c[0] + "," + c[1] + "," + c[2] + "," + c[3] + ")";
    ctx2d.fillRect(0, 0, 1, 1);
    var tex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, tex);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texParam[ii]);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texParam[ii]);
    textures[ii] = tex;
  }

  var textureLoc = gl.getUniformLocation(program, "tex");
  var worldLoc = gl.getUniformLocation(program, "world");

  gl.clearColor(1,1,1,1);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  for (var ii = 0; ii < colors.length; ++ii) {
    var x = ii % 2;
    var y = Math.floor(ii / 2);
    gl.bindTexture(gl.TEXTURE_2D, textures[ii]);
    gl.uniformMatrix4fv(
        worldLoc, false,
        [0.5, 0, 0, 0,
         0, 0.5, 0, 0,
         0, 0, 1, 0,
         -0.5 + x, -0.5 + y, 0, 1]);
    gl.drawArrays(gl.TRIANGLES, 0, 6);
  }

  var buf = new Uint8Array(24 * 24 * 4);
  gl.readPixels(0, 0, 24, 24, gl.RGBA, gl.UNSIGNED_BYTE, buf);
  var passed = true;
  for (var ii = 0; ii < colors.length; ++ii) {
    var x = ii % 2;
    var y = Math.floor(ii / 2);
    var c = colors[ii];
    for (var yy = 0; yy < 12; ++yy) {
      for (var xx = 0; xx < 12; ++xx) {
        var ec = [0,0,0,0];
        switch (texParam[ii]) {
          case gl.REPEAT:
            if (xx % 2 == 1 && yy % 2 == 0) {
              ec = c;
            }
            break;
          case gl.CLAMP_TO_EDGE:
            if (xx < 6 && yy >= 6) {
              ec = c;
            }
            break;
          case gl.MIRRORED_REPEAT:
            if (xx % 4 < 2 && yy % 4 >= 2) {
              ec = c;
            }
            break;
        }
        var off = ((y * 12 + yy) * 24 + x * 12 + xx) * 4;
        if (buf[off + 0] != ec[0] ||
            buf[off + 1] != ec[1] ||
            buf[off + 2] != ec[2] ||
            buf[off + 3] != ec[3]) {
          var msg = 'at (' + (x * 12 + xx) + ', ' + (y * 12 + yy) +
              ') expected: ' +
              ec[0] + ', ' + ec[1] + ', ' + ec[2] + ', ' + ec[3] + ' found: ' +
              buf[off + 0] + ', ' +
              buf[off + 1] + ', ' +
              buf[off + 2] + ', ' +
              buf[off + 3];
          testFailed(msg);
          passed = false;
        }
      }
    }
  }
  if (passed) {
    testPassed("rendered as expected");
   }
}

init();
var successfullyParsed = true;
</script>
<script src="../../resources/js-test-post.js"></script>

</body>
</html>

