<!--

/*
** 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 GLSL 2 types of textures on same unit conformance test.</title>
    <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
    <script src="../../../js/js-test-pre.js"></script>
    <script src="../../../js/webgl-test-utils.js"> </script>
</head>
<body>
<canvas id="example" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
<canvas id="canvas2d" width="1" height="1" style="width: 40px; height: 40px;"></canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 texCoord0;
varying vec2 texCoord;
void main()
{
  gl_Position = vPosition;
  texCoord = texCoord0;
}
</script>

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

uniform sampler2D tex2d;
uniform samplerCube texCube;
varying vec2 texCoord;
void main()
{
  gl_FragColor =  texture2D(tex2d, texCoord) +
                  textureCube(texCube, vec3(0,1,0));
}
</script>

  <script>
  "use strict";
function init()
{
  description(
    "Tests that using 2 types of textures on the same texture unit" +
    "and referencing them both in the same program fails as per" +
    "OpenGL ES 2.0.24 spec section 2.10.4, Samplers subsection.");

  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([
          0,0, 1,0, 0,1,
          0,1, 1,0, 1,1]),
      gl.STATIC_DRAW);
  gl.enableVertexAttribArray(1);
  gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);

  // Make texture unit 1 active.
  gl.activeTexture(gl.TEXTURE1);

  // Make a 2d texture
  var tex2d = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex2d);
  ctx2d.fillStyle = "rgba(0, 0, 255, 255)";
  ctx2d.fillRect(0, 0, 1, 1);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);

  // make a cube texture
  var texCube = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCube);
  ctx2d.fillStyle = "rgba(0, 255, 0, 64)";
  ctx2d.fillRect(0, 0, 1, 1);
  var targets = [
    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];
  for (var ii = 0; ii < targets.length; ++ii) {
    gl.texImage2D(targets[ii], 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
  }

  var tex2dLoc = gl.getUniformLocation(program, "tex2d");
  var texCubeLoc = gl.getUniformLocation(program, "texCube");
  gl.uniform1i(tex2dLoc, 1);
  gl.uniform1i(texCubeLoc, 1);

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

  for (var ii = 0; ii < 4; ++ii) {
    var x = ii % 2;
    var y = Math.floor(ii / 2);
    gl.drawArrays(gl.TRIANGLES, 0, 6);
    wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
              "drawing with 2 different targets on the same texture unit should generate INVALID_VALUE");
  }
}

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

</body>
</html>
