4 ** Copyright (c) 2012 The Khronos Group Inc.
6 ** Permission is hereby granted, free of charge, to any person obtaining a
7 ** copy of this software and/or associated documentation files (the
8 ** "Materials"), to deal in the Materials without restriction, including
9 ** without limitation the rights to use, copy, modify, merge, publish,
10 ** distribute, sublicense, and/or sell copies of the Materials, and to
11 ** permit persons to whom the Materials are furnished to do so, subject to
12 ** the following conditions:
14 ** The above copyright notice and this permission notice shall be included
15 ** in all copies or substantial portions of the Materials.
17 ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
31 <meta charset=
"utf-8">
32 <title>WebGL texture texSubImage2Ds cube map conformance test.
</title>
33 <script src=
"../../../resources/js-test.js"></script>
34 <script src=
"resources/webgl-test.js"> </script>
35 <script src=
"resources/webgl-test-utils.js"></script>
38 <canvas id=
"example" width=
"256" height=
"256" style=
"width: 40px; height: 40px;"></canvas>
39 <div id=
"description"></div>
40 <div id=
"console"></div>
41 <script id=
"vshader" type=
"x-shader/x-vertex">
42 attribute vec4 vPosition;
43 uniform mat4 rotation;
44 varying vec3 texCoord;
47 gl_Position = vPosition;
48 vec4 direction = vec4(vPosition.x *
0.5, vPosition.y *
0.5,
1,
1);
49 texCoord = normalize((rotation * direction).xyz);
53 <script id=
"fshader" type=
"x-shader/x-fragment">
54 precision mediump float;
55 uniform samplerCube tex;
56 varying vec3 texCoord;
59 gl_FragColor = textureCube(tex, normalize(texCoord));
64 description("Checks texSubImage2D with cube map textures");
67 var wtu
= WebGLTestUtils
;
68 canvas
= document
.getElementById("example");
70 gl
= wtu
.create3DContext(canvas
);
71 wtu
.setupUnitQuad(gl
, 0, 1);
72 var program
= wtu
.setupProgram(
74 ['vshader', 'fshader'],
75 ['vPosition', 'texCoord0'], [0, 1]);
76 var rotLoc
= gl
.getUniformLocation(program
, "rotation");
81 {name
: 'red', color
: [255, 0, 0, 255]},
82 {name
: 'green', color
: [ 0, 255, 0, 255]},
83 {name
: 'blue', color
: [ 0, 0, 255, 255]},
84 {name
: 'yellow', color
: [255, 255, 0, 255]},
85 {name
: 'cyan', color
: [ 0, 255, 255, 255]},
86 {name
: 'magenta', color
: [255, 0, 255, 255]}
90 gl
.TEXTURE_CUBE_MAP_POSITIVE_X
,
91 gl
.TEXTURE_CUBE_MAP_NEGATIVE_X
,
92 gl
.TEXTURE_CUBE_MAP_POSITIVE_Y
,
93 gl
.TEXTURE_CUBE_MAP_NEGATIVE_Y
,
94 gl
.TEXTURE_CUBE_MAP_POSITIVE_Z
,
95 gl
.TEXTURE_CUBE_MAP_NEGATIVE_Z
];
98 {axis
: [0, 1, 0], angle
: Math
.PI
/ 2},
99 {axis
: [0, 1, 0], angle
: -Math
.PI
/ 2},
100 {axis
: [1, 0, 0], angle
: -Math
.PI
/ 2},
101 {axis
: [1, 0, 0], angle
: Math
.PI
/ 2},
102 {axis
: [0, 1, 0], angle
: 0},
103 {axis
: [0, 1, 0], angle
: Math
.PI
},
106 var halfRotations
= [
107 {colors
: [3, 4], rotations
: [{axis
: [1, 0, 0], angle
: Math
.PI
/ 4}]},
108 {colors
: [4, 2], rotations
: [{axis
: [1, 0, 0], angle
: -Math
.PI
/ 4}]},
109 {colors
: [5, 3], rotations
: [{axis
: [1, 0, 0], angle
: Math
.PI
/ 4 * 3}]},
110 {colors
: [2, 5], rotations
: [{axis
: [1, 0, 0], angle
: -Math
.PI
/ 4 * 3}]},
111 {colors
: [3, 0], rotations
: [{axis
: [0, 1, 0], angle
: Math
.PI
/ 2},
112 {axis
: [1, 0, 0], angle
: Math
.PI
/ 4}]},
113 {colors
: [0, 2], rotations
: [{axis
: [0, 1, 0], angle
: Math
.PI
/ 2},
114 {axis
: [1, 0, 0], angle
: -Math
.PI
/ 4}]},
120 function testSize(size
) {
122 debug("testing size: " + size
);
123 var canvasSize
= Math
.max(size
/ 4, 2);
124 canvas
.width
= canvasSize
;
125 canvas
.height
= canvasSize
;
126 gl
.viewport(0, 0, canvasSize
, canvasSize
);
127 var tex
= gl
.createTexture();
128 gl
.bindTexture(gl
.TEXTURE_CUBE_MAP
, tex
);
130 // Seems like I should be using LINEAR here with some other math
131 // to make sure I get more mip coverage but that's easier said
134 gl
.texParameteri(gl
.TEXTURE_CUBE_MAP
, gl
.TEXTURE_MIN_FILTER
, gl
.NEAREST
);
135 gl
.texParameteri(gl
.TEXTURE_CUBE_MAP
, gl
.TEXTURE_MAG_FILTER
, gl
.NEAREST
);
137 for (var jj
= 0; jj
< 2; ++jj
) {
138 for (var tt
= 0; tt
< targets
.length
; ++tt
) {
139 var color
= colors
[(tt
+ count
) % colors
.length
];
140 fillLevel(targets
[tt
], 0, size
, color
.color
);
145 gl
.TEXTURE_CUBE_MAP
, gl
.TEXTURE_MIN_FILTER
,
146 gl
.NEAREST_MIPMAP_NEAREST
);
147 gl
.generateMipmap(gl
.TEXTURE_CUBE_MAP
);
150 var err
= gl
.getError();
151 if (err
== gl
.OUT_OF_MEMORY
) {
152 debug("out of memory");
155 if (err
!= gl
.NO_ERROR
) {
156 testFailed("unexpected gl error: " + wtu
.glEnumToString(gl
, err
));
160 for (var rr
= 0; rr
< rotations
.length
; ++rr
) {
161 var rot
= rotations
[rr
];
162 var color
= colors
[(rr
+ count
) % colors
.length
];
163 var rotMat
= axisRotation(rot
.axis
, rot
.angle
);
164 gl
.uniformMatrix4fv(rotLoc
, false, rotMat
);
168 wtu
.glEnumToString(gl
, targets
[rr
]) + " should be " + color
.name
);
171 for (var rr
= 0; rr
< halfRotations
.length
; ++rr
) {
172 var h
= halfRotations
[rr
];
173 var rots
= h
.rotations
;
174 var rotMat
= axisRotation(rots
[0].axis
, rots
[0].angle
);
175 for (var ii
= 1; ii
< rots
.length
; ++ii
) {
176 var tmpMat
= axisRotation(rots
[ii
].axis
, rots
[ii
].angle
);
177 var rotMat
= mulMatrix(tmpMat
, rotMat
);
179 gl
.uniformMatrix4fv(rotLoc
, false, rotMat
);
182 for (var ii
= 0; ii
< 2; ++ii
) {
188 colors
[(h
.colors
[ii
] + count
) % colors
.length
]);
194 gl
.deleteTexture(tex
);
198 glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no errors.");
200 function checkRect(x
, y
, width
, height
, color
) {
208 "" + x
+ ", " + y
+ ", " + width
+ ", " + height
+
209 " should be " + color
.name
);
212 function fillLevel(target
, level
, size
, color
) {
213 var numPixels
= size
* size
;
214 var halfPixelRow
= new Uint8Array(size
* 2);
215 for (var jj
= 0; jj
< size
; ++jj
) {
217 halfPixelRow
[off
+ 0] = color
[0];
218 halfPixelRow
[off
+ 1] = color
[1];
219 halfPixelRow
[off
+ 2] = color
[2];
220 halfPixelRow
[off
+ 3] = color
[3];
223 target
, level
, gl
.RGBA
, size
, size
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
,
225 for (var jj
= 0; jj
< size
; ++jj
) {
227 target
, level
, 0, jj
, size
/ 2, 1, gl
.RGBA
, gl
.UNSIGNED_BYTE
, halfPixelRow
);
229 target
, level
, size
/ 2, jj
, size
/ 2, 1, gl
.RGBA
, gl
.UNSIGNED_BYTE
, halfPixelRow
);
233 function printMat(mat
) {
234 debug("" + mat
[0] + ", " + mat
[1] + ", " + mat
[2] + ", " + mat
[3] + ", ");
235 debug("" + mat
[4] + ", " + mat
[5] + ", " + mat
[6] + ", " + mat
[7] + ", ");
236 debug("" + mat
[8] + ", " + mat
[9] + ", " + mat
[10] + ", " + mat
[11] + ", ");
237 debug("" + mat
[12] + ", " + mat
[13] + ", " + mat
[14] + ", " + mat
[15] + ", ");
240 function axisRotation(axis
, angle
) {
241 var dst
= new Float32Array(16);
245 var n
= Math
.sqrt(x
* x
+ y
* y
+ z
* z
);
252 var c
= Math
.cos(angle
);
253 var s
= Math
.sin(angle
);
254 var oneMinusCosine
= 1 - c
;
256 dst
[ 0] = xx
+ (1 - xx
) * c
;
257 dst
[ 1] = x
* y
* oneMinusCosine
+ z
* s
;
258 dst
[ 2] = x
* z
* oneMinusCosine
- y
* s
;
260 dst
[ 4] = x
* y
* oneMinusCosine
- z
* s
;
261 dst
[ 5] = yy
+ (1 - yy
) * c
;
262 dst
[ 6] = y
* z
* oneMinusCosine
+ x
* s
;
264 dst
[ 8] = x
* z
* oneMinusCosine
+ y
* s
;
265 dst
[ 9] = y
* z
* oneMinusCosine
- x
* s
;
266 dst
[10] = zz
+ (1 - zz
) * c
;
276 function mulMatrix(a
, b
) {
277 var dst
= new Float32Array(16);
310 dst
[ 0] = a00
* b00
+ a01
* b10
+ a02
* b20
+ a03
* b30
;
311 dst
[ 1] = a00
* b01
+ a01
* b11
+ a02
* b21
+ a03
* b31
;
312 dst
[ 2] = a00
* b02
+ a01
* b12
+ a02
* b22
+ a03
* b32
;
313 dst
[ 3] = a00
* b03
+ a01
* b13
+ a02
* b23
+ a03
* b33
;
314 dst
[ 4] = a10
* b00
+ a11
* b10
+ a12
* b20
+ a13
* b30
;
315 dst
[ 5] = a10
* b01
+ a11
* b11
+ a12
* b21
+ a13
* b31
;
316 dst
[ 6] = a10
* b02
+ a11
* b12
+ a12
* b22
+ a13
* b32
;
317 dst
[ 7] = a10
* b03
+ a11
* b13
+ a12
* b23
+ a13
* b33
;
318 dst
[ 8] = a20
* b00
+ a21
* b10
+ a22
* b20
+ a23
* b30
;
319 dst
[ 9] = a20
* b01
+ a21
* b11
+ a22
* b21
+ a23
* b31
;
320 dst
[10] = a20
* b02
+ a21
* b12
+ a22
* b22
+ a23
* b32
;
321 dst
[11] = a20
* b03
+ a21
* b13
+ a22
* b23
+ a23
* b33
;
322 dst
[12] = a30
* b00
+ a31
* b10
+ a32
* b20
+ a33
* b30
;
323 dst
[13] = a30
* b01
+ a31
* b11
+ a32
* b21
+ a33
* b31
;
324 dst
[14] = a30
* b02
+ a31
* b12
+ a32
* b22
+ a33
* b32
;
325 dst
[15] = a30
* b03
+ a31
* b13
+ a32
* b23
+ a33
* b33
;
329 successfullyParsed
= true;