Bug 1945965 – remove new tab April Fools logo. r=home-newtab-reviewers,reemhamz
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance / textures / misc / texture-sub-image-cube-maps.html
blobca5740766ab745ad1881b2a56c018c71c78c754c
1 <!--
2 Copyright (c) 2019 The Khronos Group Inc.
3 Use of this source code is governed by an MIT-style license that can be
4 found in the LICENSE.txt file.
5 -->
7 <!DOCTYPE html>
8 <html>
9 <head>
10 <meta charset="utf-8">
11 <title>WebGL texture texSubImage2Ds cube map conformance test.</title>
12 <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
13 <script src="../../../js/js-test-pre.js"></script>
14 <script src="../../../js/webgl-test-utils.js"></script>
15 </head>
16 <body>
17 <canvas id="example" width="256" height="256" style="width: 40px; height: 40px;"></canvas>
18 <div id="description"></div>
19 <div id="console"></div>
20 <script id="vshader" type="x-shader/x-vertex">
21 attribute vec4 vPosition;
22 uniform mat4 rotation;
23 varying vec3 texCoord;
24 void main()
26 gl_Position = vPosition;
27 vec4 direction = vec4(vPosition.x * 0.5, vPosition.y * 0.5, 1, 1);
28 texCoord = normalize((rotation * direction).xyz);
30 </script>
32 <script id="fshader" type="x-shader/x-fragment">
33 precision mediump float;
34 uniform samplerCube tex;
35 varying vec3 texCoord;
36 void main()
38 gl_FragColor = textureCube(tex, normalize(texCoord));
40 </script>
41 <script>
42 "use strict";
43 var canvas;
44 description("Checks issues with size of cube map textures");
45 debug("");
47 var wtu = WebGLTestUtils;
48 var canvas = document.getElementById("example");
50 var gl = wtu.create3DContext(canvas);
51 wtu.setupUnitQuad(gl, 0, 1);
52 var program = wtu.setupProgram(
53 gl,
54 ['vshader', 'fshader'],
55 ['vPosition', 'texCoord0'], [0, 1]);
56 var rotLoc = gl.getUniformLocation(program, "rotation");
58 var size = 16;
60 var colors = [
61 {name: 'red', color: [255, 0, 0, 255]},
62 {name: 'green', color: [ 0, 255, 0, 255]},
63 {name: 'blue', color: [ 0, 0, 255, 255]},
64 {name: 'yellow', color: [255, 255, 0, 255]},
65 {name: 'cyan', color: [ 0, 255, 255, 255]},
66 {name: 'magenta', color: [255, 0, 255, 255]}
69 var targets = [
70 gl.TEXTURE_CUBE_MAP_POSITIVE_X,
71 gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
72 gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
73 gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
74 gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
75 gl.TEXTURE_CUBE_MAP_NEGATIVE_Z];
77 var rotations = [
78 {axis: [0, 1, 0], angle: Math.PI / 2},
79 {axis: [0, 1, 0], angle: -Math.PI / 2},
80 {axis: [1, 0, 0], angle: -Math.PI / 2},
81 {axis: [1, 0, 0], angle: Math.PI / 2},
82 {axis: [0, 1, 0], angle: 0},
83 {axis: [0, 1, 0], angle: Math.PI},
86 var halfRotations = [
87 {colors: [3, 4], rotations: [{axis: [1, 0, 0], angle: Math.PI / 4}]},
88 {colors: [4, 2], rotations: [{axis: [1, 0, 0], angle: -Math.PI / 4}]},
89 {colors: [5, 3], rotations: [{axis: [1, 0, 0], angle: Math.PI / 4 * 3}]},
90 {colors: [2, 5], rotations: [{axis: [1, 0, 0], angle: -Math.PI / 4 * 3}]},
91 {colors: [3, 0], rotations: [{axis: [0, 1, 0], angle: Math.PI / 2},
92 {axis: [1, 0, 0], angle: Math.PI / 4}]},
93 {colors: [0, 2], rotations: [{axis: [0, 1, 0], angle: Math.PI / 2},
94 {axis: [1, 0, 0], angle: -Math.PI / 4}]},
97 var count = 0;
98 testSize(size);
100 function testSize(size) {
101 debug("");
102 debug("testing size: " + size);
103 var canvasSize = Math.max(size / 4, 2);
104 canvas.width = canvasSize;
105 canvas.height = canvasSize;
106 gl.viewport(0, 0, canvasSize, canvasSize);
107 var tex = gl.createTexture();
108 gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
110 // Seems like I should be using LINEAR here with some other math
111 // to make sure I get more mip coverage but that's easier said
112 // than done.
114 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
115 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
117 for (var jj = 0; jj < 2; ++jj) {
118 for (var tt = 0; tt < targets.length; ++tt) {
119 var color = colors[(tt + count) % colors.length];
120 fillLevel(targets[tt], 0, size, color.color);
122 if (jj == 1) {
123 debug("use mipmap");
124 gl.texParameteri(
125 gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER,
126 gl.NEAREST_MIPMAP_NEAREST);
127 gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
130 var err = gl.getError();
131 if (err == gl.OUT_OF_MEMORY) {
132 debug("out of memory");
133 return false;
135 if (err != gl.NO_ERROR) {
136 testFailed("unexpected gl error: " + wtu.glEnumToString(gl, err));
140 for (var rr = 0; rr < rotations.length; ++rr) {
141 var rot = rotations[rr];
142 var color = colors[(rr + count) % colors.length];
143 var rotMat = axisRotation(rot.axis, rot.angle);
144 gl.uniformMatrix4fv(rotLoc, false, rotMat);
145 wtu.clearAndDrawUnitQuad(gl);
146 wtu.checkCanvas(
147 gl, color.color,
148 wtu.glEnumToString(gl, targets[rr]) + " should be " + color.name);
151 for (var rr = 0; rr < halfRotations.length; ++rr) {
152 var h = halfRotations[rr];
153 var rots = h.rotations;
154 var rotMat = axisRotation(rots[0].axis, rots[0].angle);
155 for (var ii = 1; ii < rots.length; ++ii) {
156 var tmpMat = axisRotation(rots[ii].axis, rots[ii].angle);
157 var rotMat = mulMatrix(tmpMat, rotMat);
159 gl.uniformMatrix4fv(rotLoc, false, rotMat);
160 wtu.clearAndDrawUnitQuad(gl);
162 for (var ii = 0; ii < 2; ++ii) {
163 checkRect(
165 canvasSize / 2 * ii,
166 canvasSize,
167 canvasSize / 2,
168 colors[(h.colors[ii] + count) % colors.length]);
171 ++count;
174 gl.deleteTexture(tex);
175 return true;
178 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
180 function checkRect(x, y, width, height, color) {
181 wtu.checkCanvasRect(
185 width,
186 height,
187 color.color,
188 "" + x + ", " + y + ", " + width + ", " + height +
189 " should be " + color.name);
192 function fillLevel(target, level, size, color) {
193 var numPixels = size * size;
194 var halfPixelRow = new Uint8Array(size * 2);
195 for (var jj = 0; jj < size; ++jj) {
196 var off = jj * 4;
197 halfPixelRow[off + 0] = color[0];
198 halfPixelRow[off + 1] = color[1];
199 halfPixelRow[off + 2] = color[2];
200 halfPixelRow[off + 3] = color[3];
202 gl.texImage2D(
203 target, level, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE,
204 null);
205 for (var jj = 0; jj < size; ++jj) {
206 gl.texSubImage2D(
207 target, level, 0, jj, size / 2, 1, gl.RGBA, gl.UNSIGNED_BYTE, halfPixelRow);
208 gl.texSubImage2D(
209 target, level, size / 2, jj, size / 2, 1, gl.RGBA, gl.UNSIGNED_BYTE, halfPixelRow);
213 function printMat(mat) {
214 debug("" + mat[0] + ", " + mat[1] + ", " + mat[2] + ", " + mat[3] + ", ");
215 debug("" + mat[4] + ", " + mat[5] + ", " + mat[6] + ", " + mat[7] + ", ");
216 debug("" + mat[8] + ", " + mat[9] + ", " + mat[10] + ", " + mat[11] + ", ");
217 debug("" + mat[12] + ", " + mat[13] + ", " + mat[14] + ", " + mat[15] + ", ");
220 function axisRotation(axis, angle) {
221 var dst = new Float32Array(16);
222 var x = axis[0];
223 var y = axis[1];
224 var z = axis[2];
225 var n = Math.sqrt(x * x + y * y + z * z);
226 x /= n;
227 y /= n;
228 z /= n;
229 var xx = x * x;
230 var yy = y * y;
231 var zz = z * z;
232 var c = Math.cos(angle);
233 var s = Math.sin(angle);
234 var oneMinusCosine = 1 - c;
236 dst[ 0] = xx + (1 - xx) * c;
237 dst[ 1] = x * y * oneMinusCosine + z * s;
238 dst[ 2] = x * z * oneMinusCosine - y * s;
239 dst[ 3] = 0;
240 dst[ 4] = x * y * oneMinusCosine - z * s;
241 dst[ 5] = yy + (1 - yy) * c;
242 dst[ 6] = y * z * oneMinusCosine + x * s;
243 dst[ 7] = 0;
244 dst[ 8] = x * z * oneMinusCosine + y * s;
245 dst[ 9] = y * z * oneMinusCosine - x * s;
246 dst[10] = zz + (1 - zz) * c;
247 dst[11] = 0;
248 dst[12] = 0;
249 dst[13] = 0;
250 dst[14] = 0;
251 dst[15] = 1;
253 return dst;
256 function mulMatrix(a, b) {
257 var dst = new Float32Array(16);
258 var a00 = a[0];
259 var a01 = a[1];
260 var a02 = a[2];
261 var a03 = a[3];
262 var a10 = a[ 4 + 0];
263 var a11 = a[ 4 + 1];
264 var a12 = a[ 4 + 2];
265 var a13 = a[ 4 + 3];
266 var a20 = a[ 8 + 0];
267 var a21 = a[ 8 + 1];
268 var a22 = a[ 8 + 2];
269 var a23 = a[ 8 + 3];
270 var a30 = a[12 + 0];
271 var a31 = a[12 + 1];
272 var a32 = a[12 + 2];
273 var a33 = a[12 + 3];
274 var b00 = b[0];
275 var b01 = b[1];
276 var b02 = b[2];
277 var b03 = b[3];
278 var b10 = b[ 4 + 0];
279 var b11 = b[ 4 + 1];
280 var b12 = b[ 4 + 2];
281 var b13 = b[ 4 + 3];
282 var b20 = b[ 8 + 0];
283 var b21 = b[ 8 + 1];
284 var b22 = b[ 8 + 2];
285 var b23 = b[ 8 + 3];
286 var b30 = b[12 + 0];
287 var b31 = b[12 + 1];
288 var b32 = b[12 + 2];
289 var b33 = b[12 + 3];
290 dst[ 0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30;
291 dst[ 1] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31;
292 dst[ 2] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32;
293 dst[ 3] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33;
294 dst[ 4] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30;
295 dst[ 5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31;
296 dst[ 6] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32;
297 dst[ 7] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33;
298 dst[ 8] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30;
299 dst[ 9] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31;
300 dst[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32;
301 dst[11] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33;
302 dst[12] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30;
303 dst[13] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31;
304 dst[14] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32;
305 dst[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33;
306 return dst;
309 var successfullyParsed = true;
310 </script>
311 <script src="../../../js/js-test-post.js"></script>
313 </body>
314 </html>