<!--

/*
** 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 BindAttribLocation Conformance Tests</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>
<div id="description"></div>
<div id="console"></div>
<canvas style="border: 1px solid black;" id="canvas" width="50" height="50"></canvas>
<script id="vshader" type="text/something-not-javascript">
attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 color;
void main()
{
  gl_Position = vPosition;
  color = vColor;
}
</script>
<script id="fshader" type="text/something-not-javascript">
precision mediump float;

varying vec4 color;
void main()
{
  gl_FragColor = color;
}
</script>
<script>
"use strict";
description("This test ensures WebGL implementations don't allow names that start with 'gl_' when calling bindAttribLocation.");

debug("");
debug("Canvas.getContext");

var wtu = WebGLTestUtils;
var gl = wtu.create3DContext("canvas");
shouldBeNonNull("gl");

function fail(x,y, buf, shouldBe)
{
  var i = (y*50+x) * 4;
  var reason = "pixel at ("+x+","+y+") is ("+buf[i]+","+buf[i+1]+","+buf[i+2]+","+buf[i+3]+"), should be "+shouldBe;
  testFailed(reason);
}

function pass()
{
  testPassed("drawing is correct");
}

function loadShader(shaderType, shaderId) {
  // Get the shader source.
  var shaderSource = document.getElementById(shaderId).text;

  // Create the shader object
  var shader = gl.createShader(shaderType);
  if (shader == null) {
    debug("*** Error: unable to create shader '"+shaderId+"'");
    return null;
  }

  // Load the shader source
  gl.shaderSource(shader, shaderSource);

  // Compile the shader
  gl.compileShader(shader);

  // Check the compile status
  var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  if (!compiled) {
    // Something went wrong during compilation; get the error
    var error = gl.getShaderInfoLog(shader);
    debug("*** Error compiling shader '"+shader+"':"+error);
    gl.deleteShader(shader);
    return null;
  }
  return shader;
}

debug("");
debug("Checking gl.bindAttribLocation.");

var program = gl.createProgram();
gl.bindAttribLocation(program, 0, "gl_foo");
glErrorShouldBe(gl, gl.INVALID_OPERATION,
    "bindAttribLocation should return INVALID_OPERATION if name starts with 'gl_'");
gl.bindAttribLocation(program, 0, "gl_TexCoord0");
glErrorShouldBe(gl, gl.INVALID_OPERATION,
    "bindAttribLocation should return INVALID_OPERATION if name starts with 'gl_'");

var vs = loadShader(gl.VERTEX_SHADER, "vshader");
var fs = loadShader(gl.FRAGMENT_SHADER, "fshader");
gl.attachShader(program, vs);
gl.attachShader(program, fs);

var positions = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positions);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW);

var colors = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colors);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    0,1,0,1,
    0,1,0,1,
    0,1,0,1]), gl.STATIC_DRAW);

function setBindLocations(colorLocation, positionLocation) {
  gl.bindAttribLocation(program, positionLocation, "vPosition");
  gl.bindAttribLocation(program, colorLocation, "vColor");
  gl.linkProgram(program);
  gl.useProgram(program);
  var linked = (gl.getProgramParameter(program, gl.LINK_STATUS) != 0);
  assertMsg(linked, "program linked successfully");

  debug("vPosition:" + gl.getAttribLocation(program, "vPosition"))
  debug("vColor   :" + gl.getAttribLocation(program, "vColor"))
  assertMsg(gl.getAttribLocation(program, "vPosition") == positionLocation,
            "location of vPosition should be " + positionLocation);
  assertMsg(gl.getAttribLocation(program, "vColor") == colorLocation,
            "location of vColor should be " + colorLocation);

  var ploc = gl.getAttribLocation(program, "vPosition");
  var cloc = gl.getAttribLocation(program, "vColor");
  gl.bindBuffer(gl.ARRAY_BUFFER, positions);
  gl.enableVertexAttribArray(positionLocation);
  gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
  gl.bindBuffer(gl.ARRAY_BUFFER, colors);
  gl.enableVertexAttribArray(colorLocation);
  gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
}

function checkDraw(colorLocation, positionLocation, r, g, b, a) {
  gl.clearColor(0, 0, 0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  gl.drawArrays(gl.TRIANGLES, 0, 3);

  var width = 50;
  var height = 50;
  var buf = new Uint8Array(width * height * 4);
  gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);

  function checkPixel(x, y, r, g, b, a) {
    var offset = (y * width + x) * 4;
    if (buf[offset + 0] != r ||
        buf[offset + 1] != g ||
        buf[offset + 2] != b ||
        buf[offset + 3] != a) {
        fail(x, y, buf, "(" + r + "," + g + "," + b + "," + a + ")");
        return false;
    }
    return true;
  }

  // Test several locations
  // First line should be all black
  var success = true;
  for (var i = 0; i < 50; ++i)
    success = success && checkPixel(i, 0, 0, 0, 0, 255);

  // Line 15 should be red for at least 10 rgba pixels starting 20 pixels in
  var offset = (15 * 50 + 20) * 4;
  for (var i = 0; i < 10; ++i)
    success = success && checkPixel(20 + i, 15, r, g, b, a);

  // Last line should be all black
  for (var i = 0; i < 50; ++i)
    success = success && checkPixel(i, 49, 0, 0, 0, 255);

  if (success)
    pass();

  gl.disableVertexAttribArray(positionLocation);
  gl.disableVertexAttribArray(colorLocation);
}

setBindLocations(2, 3);
checkDraw(2, 3, 0, 255, 0, 255);

setBindLocations(0, 3);
gl.disableVertexAttribArray(0);
gl.vertexAttrib4f(0, 1, 0, 0, 1);
checkDraw(0, 3, 255, 0, 0, 255);

glErrorShouldBe(gl, gl.NO_ERROR);

debug("");
var successfullyParsed = true;

</script>
<script src="../../resources/js-test-post.js"></script>

</body>
</html>
