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.
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>
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;
26 gl_Position = vPosition;
27 vec4 direction = vec4(vPosition.x *
0.5, vPosition.y *
0.5,
1,
1);
28 texCoord = normalize((rotation * direction).xyz);
32 <script id=
"fshader" type=
"x-shader/x-fragment">
33 precision mediump float;
34 uniform samplerCube tex;
35 varying vec3 texCoord;
38 gl_FragColor = textureCube(tex, normalize(texCoord));
44 description("Checks issues with size of cube map textures");
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(
54 ['vshader', 'fshader'],
55 ['vPosition', 'texCoord0'], [0, 1]);
56 var rotLoc
= gl
.getUniformLocation(program
, "rotation");
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]}
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
];
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
},
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}]},
100 function testSize(size
) {
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
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
);
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");
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
);
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
) {
168 colors
[(h
.colors
[ii
] + count
) % colors
.length
]);
174 gl
.deleteTexture(tex
);
178 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no errors.");
180 function checkRect(x
, y
, width
, height
, 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
) {
197 halfPixelRow
[off
+ 0] = color
[0];
198 halfPixelRow
[off
+ 1] = color
[1];
199 halfPixelRow
[off
+ 2] = color
[2];
200 halfPixelRow
[off
+ 3] = color
[3];
203 target
, level
, gl
.RGBA
, size
, size
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
,
205 for (var jj
= 0; jj
< size
; ++jj
) {
207 target
, level
, 0, jj
, size
/ 2, 1, gl
.RGBA
, gl
.UNSIGNED_BYTE
, halfPixelRow
);
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);
225 var n
= Math
.sqrt(x
* x
+ y
* y
+ 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
;
240 dst
[ 4] = x
* y
* oneMinusCosine
- z
* s
;
241 dst
[ 5] = yy
+ (1 - yy
) * c
;
242 dst
[ 6] = y
* z
* oneMinusCosine
+ x
* s
;
244 dst
[ 8] = x
* z
* oneMinusCosine
+ y
* s
;
245 dst
[ 9] = y
* z
* oneMinusCosine
- x
* s
;
246 dst
[10] = zz
+ (1 - zz
) * c
;
256 function mulMatrix(a
, b
) {
257 var dst
= new Float32Array(16);
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
;
309 var successfullyParsed
= true;
311 <script src=
"../../../js/js-test-post.js"></script>