333 lines
10 KiB
HTML
333 lines
10 KiB
HTML
<!--
|
|
|
|
/*
|
|
** 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 texture texSubImage2Ds cube map conformance test.</title>
|
|
<script src="../../../resources/js-test.js"></script>
|
|
<script src="resources/webgl-test.js"> </script>
|
|
<script src="resources/webgl-test-utils.js"></script>
|
|
</head>
|
|
<body>
|
|
<canvas id="example" width="256" height="256" 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;
|
|
uniform mat4 rotation;
|
|
varying vec3 texCoord;
|
|
void main()
|
|
{
|
|
gl_Position = vPosition;
|
|
vec4 direction = vec4(vPosition.x * 0.5, vPosition.y * 0.5, 1, 1);
|
|
texCoord = normalize((rotation * direction).xyz);
|
|
}
|
|
</script>
|
|
|
|
<script id="fshader" type="x-shader/x-fragment">
|
|
precision mediump float;
|
|
uniform samplerCube tex;
|
|
varying vec3 texCoord;
|
|
void main()
|
|
{
|
|
gl_FragColor = textureCube(tex, normalize(texCoord));
|
|
}
|
|
</script>
|
|
<script>
|
|
var canvas;
|
|
description("Checks texSubImage2D with cube map textures");
|
|
debug("");
|
|
|
|
var wtu = WebGLTestUtils;
|
|
canvas = document.getElementById("example");
|
|
|
|
gl = wtu.create3DContext(canvas);
|
|
wtu.setupUnitQuad(gl, 0, 1);
|
|
var program = wtu.setupProgram(
|
|
gl,
|
|
['vshader', 'fshader'],
|
|
['vPosition', 'texCoord0'], [0, 1]);
|
|
var rotLoc = gl.getUniformLocation(program, "rotation");
|
|
|
|
size = 16;
|
|
|
|
var colors = [
|
|
{name: 'red', color: [255, 0, 0, 255]},
|
|
{name: 'green', color: [ 0, 255, 0, 255]},
|
|
{name: 'blue', color: [ 0, 0, 255, 255]},
|
|
{name: 'yellow', color: [255, 255, 0, 255]},
|
|
{name: 'cyan', color: [ 0, 255, 255, 255]},
|
|
{name: 'magenta', color: [255, 0, 255, 255]}
|
|
];
|
|
|
|
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 rotations = [
|
|
{axis: [0, 1, 0], angle: Math.PI / 2},
|
|
{axis: [0, 1, 0], angle: -Math.PI / 2},
|
|
{axis: [1, 0, 0], angle: -Math.PI / 2},
|
|
{axis: [1, 0, 0], angle: Math.PI / 2},
|
|
{axis: [0, 1, 0], angle: 0},
|
|
{axis: [0, 1, 0], angle: Math.PI},
|
|
];
|
|
|
|
var halfRotations = [
|
|
{colors: [3, 4], rotations: [{axis: [1, 0, 0], angle: Math.PI / 4}]},
|
|
{colors: [4, 2], rotations: [{axis: [1, 0, 0], angle: -Math.PI / 4}]},
|
|
{colors: [5, 3], rotations: [{axis: [1, 0, 0], angle: Math.PI / 4 * 3}]},
|
|
{colors: [2, 5], rotations: [{axis: [1, 0, 0], angle: -Math.PI / 4 * 3}]},
|
|
{colors: [3, 0], rotations: [{axis: [0, 1, 0], angle: Math.PI / 2},
|
|
{axis: [1, 0, 0], angle: Math.PI / 4}]},
|
|
{colors: [0, 2], rotations: [{axis: [0, 1, 0], angle: Math.PI / 2},
|
|
{axis: [1, 0, 0], angle: -Math.PI / 4}]},
|
|
];
|
|
|
|
var count = 0;
|
|
testSize(size);
|
|
|
|
function testSize(size) {
|
|
debug("");
|
|
debug("testing size: " + size);
|
|
var canvasSize = Math.max(size / 4, 2);
|
|
canvas.width = canvasSize;
|
|
canvas.height = canvasSize;
|
|
gl.viewport(0, 0, canvasSize, canvasSize);
|
|
var tex = gl.createTexture();
|
|
gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
|
|
|
|
// Seems like I should be using LINEAR here with some other math
|
|
// to make sure I get more mip coverage but that's easier said
|
|
// than done.
|
|
|
|
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
|
|
for (var jj = 0; jj < 2; ++jj) {
|
|
for (var tt = 0; tt < targets.length; ++tt) {
|
|
var color = colors[(tt + count) % colors.length];
|
|
fillLevel(targets[tt], 0, size, color.color);
|
|
}
|
|
if (jj == 1) {
|
|
debug("use mipmap");
|
|
gl.texParameteri(
|
|
gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER,
|
|
gl.NEAREST_MIPMAP_NEAREST);
|
|
gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
|
|
}
|
|
|
|
var err = gl.getError();
|
|
if (err == gl.OUT_OF_MEMORY) {
|
|
debug("out of memory");
|
|
return false;
|
|
}
|
|
if (err != gl.NO_ERROR) {
|
|
testFailed("unexpected gl error: " + wtu.glEnumToString(gl, err));
|
|
}
|
|
|
|
|
|
for (var rr = 0; rr < rotations.length; ++rr) {
|
|
var rot = rotations[rr];
|
|
var color = colors[(rr + count) % colors.length];
|
|
var rotMat = axisRotation(rot.axis, rot.angle);
|
|
gl.uniformMatrix4fv(rotLoc, false, rotMat);
|
|
wtu.drawQuad(gl);
|
|
wtu.checkCanvas(
|
|
gl, color.color,
|
|
wtu.glEnumToString(gl, targets[rr]) + " should be " + color.name);
|
|
}
|
|
|
|
for (var rr = 0; rr < halfRotations.length; ++rr) {
|
|
var h = halfRotations[rr];
|
|
var rots = h.rotations;
|
|
var rotMat = axisRotation(rots[0].axis, rots[0].angle);
|
|
for (var ii = 1; ii < rots.length; ++ii) {
|
|
var tmpMat = axisRotation(rots[ii].axis, rots[ii].angle);
|
|
var rotMat = mulMatrix(tmpMat, rotMat);
|
|
}
|
|
gl.uniformMatrix4fv(rotLoc, false, rotMat);
|
|
wtu.drawQuad(gl);
|
|
|
|
for (var ii = 0; ii < 2; ++ii) {
|
|
checkRect(
|
|
0,
|
|
canvasSize / 2 * ii,
|
|
canvasSize,
|
|
canvasSize / 2,
|
|
colors[(h.colors[ii] + count) % colors.length]);
|
|
}
|
|
}
|
|
++count;
|
|
}
|
|
|
|
gl.deleteTexture(tex);
|
|
return true;
|
|
}
|
|
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
|
|
|
|
function checkRect(x, y, width, height, color) {
|
|
wtu.checkCanvasRect(
|
|
gl,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
color.color,
|
|
"" + x + ", " + y + ", " + width + ", " + height +
|
|
" should be " + color.name);
|
|
}
|
|
|
|
function fillLevel(target, level, size, color) {
|
|
var numPixels = size * size;
|
|
var halfPixelRow = new Uint8Array(size * 2);
|
|
for (var jj = 0; jj < size; ++jj) {
|
|
var off = jj * 4;
|
|
halfPixelRow[off + 0] = color[0];
|
|
halfPixelRow[off + 1] = color[1];
|
|
halfPixelRow[off + 2] = color[2];
|
|
halfPixelRow[off + 3] = color[3];
|
|
}
|
|
gl.texImage2D(
|
|
target, level, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE,
|
|
null);
|
|
for (var jj = 0; jj < size; ++jj) {
|
|
gl.texSubImage2D(
|
|
target, level, 0, jj, size / 2, 1, gl.RGBA, gl.UNSIGNED_BYTE, halfPixelRow);
|
|
gl.texSubImage2D(
|
|
target, level, size / 2, jj, size / 2, 1, gl.RGBA, gl.UNSIGNED_BYTE, halfPixelRow);
|
|
}
|
|
}
|
|
|
|
function printMat(mat) {
|
|
debug("" + mat[0] + ", " + mat[1] + ", " + mat[2] + ", " + mat[3] + ", ");
|
|
debug("" + mat[4] + ", " + mat[5] + ", " + mat[6] + ", " + mat[7] + ", ");
|
|
debug("" + mat[8] + ", " + mat[9] + ", " + mat[10] + ", " + mat[11] + ", ");
|
|
debug("" + mat[12] + ", " + mat[13] + ", " + mat[14] + ", " + mat[15] + ", ");
|
|
}
|
|
|
|
function axisRotation(axis, angle) {
|
|
var dst = new Float32Array(16);
|
|
var x = axis[0];
|
|
var y = axis[1];
|
|
var z = axis[2];
|
|
var n = Math.sqrt(x * x + y * y + z * z);
|
|
x /= n;
|
|
y /= n;
|
|
z /= n;
|
|
var xx = x * x;
|
|
var yy = y * y;
|
|
var zz = z * z;
|
|
var c = Math.cos(angle);
|
|
var s = Math.sin(angle);
|
|
var oneMinusCosine = 1 - c;
|
|
|
|
dst[ 0] = xx + (1 - xx) * c;
|
|
dst[ 1] = x * y * oneMinusCosine + z * s;
|
|
dst[ 2] = x * z * oneMinusCosine - y * s;
|
|
dst[ 3] = 0;
|
|
dst[ 4] = x * y * oneMinusCosine - z * s;
|
|
dst[ 5] = yy + (1 - yy) * c;
|
|
dst[ 6] = y * z * oneMinusCosine + x * s;
|
|
dst[ 7] = 0;
|
|
dst[ 8] = x * z * oneMinusCosine + y * s;
|
|
dst[ 9] = y * z * oneMinusCosine - x * s;
|
|
dst[10] = zz + (1 - zz) * c;
|
|
dst[11] = 0;
|
|
dst[12] = 0;
|
|
dst[13] = 0;
|
|
dst[14] = 0;
|
|
dst[15] = 1;
|
|
|
|
return dst;
|
|
};
|
|
|
|
function mulMatrix(a, b) {
|
|
var dst = new Float32Array(16);
|
|
var a00 = a[0];
|
|
var a01 = a[1];
|
|
var a02 = a[2];
|
|
var a03 = a[3];
|
|
var a10 = a[ 4 + 0];
|
|
var a11 = a[ 4 + 1];
|
|
var a12 = a[ 4 + 2];
|
|
var a13 = a[ 4 + 3];
|
|
var a20 = a[ 8 + 0];
|
|
var a21 = a[ 8 + 1];
|
|
var a22 = a[ 8 + 2];
|
|
var a23 = a[ 8 + 3];
|
|
var a30 = a[12 + 0];
|
|
var a31 = a[12 + 1];
|
|
var a32 = a[12 + 2];
|
|
var a33 = a[12 + 3];
|
|
var b00 = b[0];
|
|
var b01 = b[1];
|
|
var b02 = b[2];
|
|
var b03 = b[3];
|
|
var b10 = b[ 4 + 0];
|
|
var b11 = b[ 4 + 1];
|
|
var b12 = b[ 4 + 2];
|
|
var b13 = b[ 4 + 3];
|
|
var b20 = b[ 8 + 0];
|
|
var b21 = b[ 8 + 1];
|
|
var b22 = b[ 8 + 2];
|
|
var b23 = b[ 8 + 3];
|
|
var b30 = b[12 + 0];
|
|
var b31 = b[12 + 1];
|
|
var b32 = b[12 + 2];
|
|
var b33 = b[12 + 3];
|
|
dst[ 0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30;
|
|
dst[ 1] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31;
|
|
dst[ 2] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32;
|
|
dst[ 3] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33;
|
|
dst[ 4] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30;
|
|
dst[ 5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31;
|
|
dst[ 6] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32;
|
|
dst[ 7] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33;
|
|
dst[ 8] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30;
|
|
dst[ 9] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31;
|
|
dst[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32;
|
|
dst[11] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33;
|
|
dst[12] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30;
|
|
dst[13] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31;
|
|
dst[14] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32;
|
|
dst[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33;
|
|
return dst;
|
|
};
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|
|
|