<!--

/*
** Copyright (c) 2016 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 Integer Cubemap Texture Sampling Tests</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>
<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
</head>
<body>
<canvas id="example" width="128" height="128"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";

var wtu = WebGLTestUtils;
var tiu = TexImageUtils;

description("Verify sampling works fine with integer cubemap textures");
debug("https://github.com/KhronosGroup/WebGL/issues/1819");

var gl = wtu.create3DContext("example", undefined, 2);

var testCases = [
    { internalFormat: "R8UI", format: "RED_INTEGER", type: "UNSIGNED_BYTE" },
    { internalFormat: "RG8UI", format: "RG_INTEGER", type: "UNSIGNED_BYTE" },
    { internalFormat: "RGB8UI", format: "RGB_INTEGER", type: "UNSIGNED_BYTE" },
    { internalFormat: "RGBA8UI", format: "RGBA_INTEGER", type: "UNSIGNED_BYTE" },
];

function setupData(internalFormat, size) {
    var numComponents = 0;
    switch (gl[internalFormat]) {
      case gl.R8UI:
        numComponents = 1;
        break;
      case gl.RG8UI:
        numComponents = 2;
        break;
      case gl.RGB8UI:
        numComponents = 3;
        break;
      case gl.RGBA8UI:
        numComponents = 4;
        break;
    }
    if (numComponents == 0) {
        testFailed("This should never be reached");
        return null;
    }
    var data = new Uint8Array(numComponents * size * size);
    for (var ii = 0; ii < size * size; ++ii) {
        // Set all pixels to RED.
        data[ii * numComponents] = 255;
        if (numComponents > 1)
            data[ii * numComponents + 1] = 0;
        if (numComponents > 2)
            data[ii * numComponents + 2] = 0;
        if (numComponents > 3)
            data[ii * numComponents + 3] = 255;
    }
    return data;
}

function checkIntegerTextureValues(internalFormat, size) {
    var buffer = new Uint32Array(4 * size * size);
    gl.readPixels(0, 0, size, size, gl.RGBA_INTEGER, gl.UNSIGNED_INT, buffer);
    for (var y = 0; y < size; ++y) {
        for (var x = 0; x < size; ++x) {
            var index = (y * size + x) * 4;
            if (buffer[index] != 255 || buffer[index + 1] != 0 || buffer[index + 2] != 0) {
                testFailed("At (" + x + ", " + y + "), expected 255,0,0,255, was " +
                           [buffer[index], buffer[index + 1], buffer[index + 2], buffer[index + 3]]);
                return;
            }
        }
    }
    testPassed("All pixels are as expected");
}

function runOneTest(internalFormat, format, type, size) {
    debug("");
    debug("Testing internalformat = " + internalFormat + ", format = " + format + ", type = " + type + ", size = " + size);

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

    var tex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

    gl.pixelStorei(gl.UNPACK_ALIGNMENT, 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];
    var data = setupData(internalFormat, size);
    for (var tt = 0; tt < targets.length; ++tt) {
        gl.texImage2D(targets[tt], 0, gl[internalFormat], size, size, 0, gl[format], gl[type], data);
    }

    debug("1) Reading back texture data");
    var fbo = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    for (var tt = 0; tt < targets.length; ++tt) {
        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, targets[tt], tex, 0);
        if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
            checkIntegerTextureValues(internalFormat, size);
        }
    }
    gl.deleteFramebuffer(fbo);

    debug("2) Rendering with texture");
    var program = tiu.setupTexturedQuadWithCubeMap(gl, internalFormat);
    var loc = gl.getUniformLocation(program, "face");
    for (var tt = 0; tt < targets.length; ++tt) {
        gl.uniform1i(loc, targets[tt]);
        // Draw the triangles
        wtu.clearAndDrawUnitQuad(gl, [0, 255, 0, 255]);
        wtu.checkCanvasRect(gl, 0, 0, gl.canvas.width, gl.canvas.height, [255, 0, 0, 255], "Should be red");
    }
    gl.deleteProgram(program);
    gl.deleteTexture(tex);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL errors");

    var m = wtu.makeImageFromCanvas(gl.canvas);
    document.getElementById("console").appendChild(m);
    document.getElementById("console").appendChild(document.createElement("hr"));
}

function runTests() {
    for (var ii = 0; ii < testCases.length; ++ii) {
        runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 2);
        runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 4);
        runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 8);
        runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 16);
        runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 32);
        runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 64);
        runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 65);
        runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 127);
        runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 128);
        runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 129);
    }
}

runTests();

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

</body>
</html>
