OLD | NEW |
| (Empty) |
1 <!-- | |
2 Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
3 Use of this source code is governed by a BSD-style license that can be | |
4 found in the LICENSE file. | |
5 --> | |
6 <!DOCTYPE html> | |
7 <html> | |
8 <head> | |
9 <meta charset="utf-8"> | |
10 <title>WebGL texture size cube map conformance test.</title> | |
11 <link rel="stylesheet" href="../../resources/js-test-style.css"/> | |
12 <script src="../../resources/js-test-pre.js"></script> | |
13 <script src="../resources/webgl-test.js"> </script> | |
14 <script src="../resources/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() | |
25 { | |
26 gl_Position = vPosition; | |
27 vec4 direction = vec4(vPosition.x * 0.5, vPosition.y * 0.5, 1, 1); | |
28 texCoord = normalize((rotation * direction).xyz); | |
29 } | |
30 </script> | |
31 | |
32 <script id="fshader" type="x-shader/x-fragment"> | |
33 precision mediump float; | |
34 uniform samplerCube tex; | |
35 varying vec3 texCoord; | |
36 void main() | |
37 { | |
38 gl_FragColor = textureCube(tex, normalize(texCoord)); | |
39 } | |
40 </script> | |
41 <script> | |
42 var canvas; | |
43 description("Checks issues with size of cube map textures"); | |
44 debug(""); | |
45 | |
46 var wtu = WebGLTestUtils; | |
47 canvas = document.getElementById("example"); | |
48 | |
49 gl = wtu.create3DContext(canvas); | |
50 wtu.setupUnitQuad(gl, 0, 1); | |
51 var program = wtu.setupProgram( | |
52 gl, | |
53 [wtu.loadShaderFromScript(gl, 'vshader', gl.VERTEX_SHADER), | |
54 wtu.loadShaderFromScript(gl, 'fshader', gl.FRAGMENT_SHADER)], | |
55 ['vPosition', 'texCoord0'], [0, 1]); | |
56 var rotLoc = gl.getUniformLocation(program, "rotation"); | |
57 | |
58 gl.disable(gl.DEPTH_TEST); | |
59 gl.disable(gl.BLEND); | |
60 | |
61 var maxSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); | |
62 debug("max cube map size: " + maxSize); | |
63 maxSize = Math.min(512, maxSize); | |
64 | |
65 // a cube map of 512x512 takes 6meg. I'm assuming it's not | |
66 // unreasonable to expect to be able to allocate a 6meg texture | |
67 | |
68 var colors = [ | |
69 {name: 'red', color: [255, 0, 0, 255]}, | |
70 {name: 'green', color: [ 0, 255, 0, 255]}, | |
71 {name: 'blue', color: [ 0, 0, 255, 255]}, | |
72 {name: 'yellow', color: [255, 255, 0, 255]}, | |
73 {name: 'cyan', color: [ 0, 255, 255, 255]}, | |
74 {name: 'magenta', color: [255, 0, 255, 255]} | |
75 ]; | |
76 | |
77 var targets = [ | |
78 gl.TEXTURE_CUBE_MAP_POSITIVE_X, | |
79 gl.TEXTURE_CUBE_MAP_NEGATIVE_X, | |
80 gl.TEXTURE_CUBE_MAP_POSITIVE_Y, | |
81 gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, | |
82 gl.TEXTURE_CUBE_MAP_POSITIVE_Z, | |
83 gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]; | |
84 | |
85 var rotations = [ | |
86 {axis: [0, 1, 0], angle: Math.PI / 2}, | |
87 {axis: [0, 1, 0], angle: -Math.PI / 2}, | |
88 {axis: [1, 0, 0], angle: -Math.PI / 2}, | |
89 {axis: [1, 0, 0], angle: Math.PI / 2}, | |
90 {axis: [0, 1, 0], angle: 0}, | |
91 {axis: [0, 1, 0], angle: Math.PI}, | |
92 ]; | |
93 | |
94 var halfRotations = [ | |
95 {colors: [3, 4], rotations: [{axis: [1, 0, 0], angle: Math.PI / 4}]}, | |
96 {colors: [4, 2], rotations: [{axis: [1, 0, 0], angle: -Math.PI / 4}]}, | |
97 {colors: [5, 3], rotations: [{axis: [1, 0, 0], angle: Math.PI / 4 * 3}]}, | |
98 {colors: [2, 5], rotations: [{axis: [1, 0, 0], angle: -Math.PI / 4 * 3}]}, | |
99 {colors: [3, 0], rotations: [{axis: [0, 1, 0], angle: Math.PI / 2}, | |
100 {axis: [1, 0, 0], angle: Math.PI / 4}]}, | |
101 {colors: [0, 2], rotations: [{axis: [0, 1, 0], angle: Math.PI / 2}, | |
102 {axis: [1, 0, 0], angle: -Math.PI / 4}]}, | |
103 ]; | |
104 | |
105 var count = 0; | |
106 var sizeCount = 0; | |
107 | |
108 test(); | |
109 | |
110 function test() { | |
111 var size = Math.pow(2, sizeCount); | |
112 if (size > maxSize || !testSize(size)) { | |
113 finishTest(); | |
114 } else { | |
115 ++sizeCount; | |
116 setTimeout(test, 100); | |
117 } | |
118 } | |
119 | |
120 function testSize(size) { | |
121 debug(""); | |
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); | |
129 | |
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 | |
132 // than done. | |
133 | |
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); | |
136 | |
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); | |
141 } | |
142 if (jj == 1) { | |
143 debug("use mipmap"); | |
144 gl.texParameteri( | |
145 gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, | |
146 gl.NEAREST_MIPMAP_NEAREST); | |
147 gl.generateMipmap(gl.TEXTURE_CUBE_MAP); | |
148 } | |
149 | |
150 var err = gl.getError(); | |
151 if (err == gl.OUT_OF_MEMORY) { | |
152 return false; | |
153 } | |
154 if (err != gl.NO_ERROR) { | |
155 testFailed("unexpected gl error: " + wtu.glEnumToString(gl, err)); | |
156 } | |
157 | |
158 | |
159 for (var rr = 0; rr < rotations.length; ++rr) { | |
160 var rot = rotations[rr]; | |
161 var color = colors[(rr + count) % colors.length]; | |
162 var rotMat = axisRotation(rot.axis, rot.angle); | |
163 gl.uniformMatrix4fv(rotLoc, false, rotMat); | |
164 wtu.drawQuad(gl); | |
165 wtu.checkCanvas( | |
166 gl, color.color, | |
167 wtu.glEnumToString(gl, targets[rr]) + " should be " + color.name); | |
168 } | |
169 | |
170 for (var rr = 0; rr < halfRotations.length; ++rr) { | |
171 var h = halfRotations[rr]; | |
172 var rots = h.rotations; | |
173 var rotMat = axisRotation(rots[0].axis, rots[0].angle); | |
174 for (var ii = 1; ii < rots.length; ++ii) { | |
175 var tmpMat = axisRotation(rots[ii].axis, rots[ii].angle); | |
176 var rotMat = mulMatrix(tmpMat, rotMat); | |
177 } | |
178 gl.uniformMatrix4fv(rotLoc, false, rotMat); | |
179 wtu.drawQuad(gl); | |
180 | |
181 for (var ii = 0; ii < 2; ++ii) { | |
182 checkRect( | |
183 0, | |
184 canvasSize / 2 * ii, | |
185 canvasSize, | |
186 canvasSize / 2, | |
187 colors[(h.colors[ii] + count) % colors.length]); | |
188 } | |
189 } | |
190 ++count; | |
191 } | |
192 | |
193 gl.deleteTexture(tex); | |
194 return true; | |
195 } | |
196 | |
197 glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors."); | |
198 | |
199 function checkRect(x, y, width, height, color) { | |
200 wtu.checkCanvasRect( | |
201 gl, | |
202 x, | |
203 y, | |
204 width, | |
205 height, | |
206 color.color, | |
207 "" + x + ", " + y + ", " + width + ", " + height + | |
208 " should be " + color.name); | |
209 } | |
210 | |
211 function fillLevel(target, level, size, color) { | |
212 var numPixels = size * size; | |
213 var pixels = new Uint8Array(numPixels * 4); | |
214 for (var jj = 0; jj < numPixels; ++jj) { | |
215 var off = jj * 4; | |
216 pixels[off + 0] = color[0]; | |
217 pixels[off + 1] = color[1]; | |
218 pixels[off + 2] = color[2]; | |
219 pixels[off + 3] = color[3]; | |
220 } | |
221 gl.texImage2D( | |
222 target, level, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, | |
223 pixels); | |
224 } | |
225 | |
226 function printMat(mat) { | |
227 debug("" + mat[0] + ", " + mat[1] + ", " + mat[2] + ", " + mat[3] + ", "); | |
228 debug("" + mat[4] + ", " + mat[5] + ", " + mat[6] + ", " + mat[7] + ", "); | |
229 debug("" + mat[8] + ", " + mat[9] + ", " + mat[10] + ", " + mat[11] + ", "); | |
230 debug("" + mat[12] + ", " + mat[13] + ", " + mat[14] + ", " + mat[15] + ", "); | |
231 } | |
232 | |
233 function axisRotation(axis, angle) { | |
234 var dst = new Float32Array(16); | |
235 var x = axis[0]; | |
236 var y = axis[1]; | |
237 var z = axis[2]; | |
238 var n = Math.sqrt(x * x + y * y + z * z); | |
239 x /= n; | |
240 y /= n; | |
241 z /= n; | |
242 var xx = x * x; | |
243 var yy = y * y; | |
244 var zz = z * z; | |
245 var c = Math.cos(angle); | |
246 var s = Math.sin(angle); | |
247 var oneMinusCosine = 1 - c; | |
248 | |
249 dst[ 0] = xx + (1 - xx) * c; | |
250 dst[ 1] = x * y * oneMinusCosine + z * s; | |
251 dst[ 2] = x * z * oneMinusCosine - y * s; | |
252 dst[ 3] = 0; | |
253 dst[ 4] = x * y * oneMinusCosine - z * s; | |
254 dst[ 5] = yy + (1 - yy) * c; | |
255 dst[ 6] = y * z * oneMinusCosine + x * s; | |
256 dst[ 7] = 0; | |
257 dst[ 8] = x * z * oneMinusCosine + y * s; | |
258 dst[ 9] = y * z * oneMinusCosine - x * s; | |
259 dst[10] = zz + (1 - zz) * c; | |
260 dst[11] = 0; | |
261 dst[12] = 0; | |
262 dst[13] = 0; | |
263 dst[14] = 0; | |
264 dst[15] = 1; | |
265 | |
266 return dst; | |
267 }; | |
268 | |
269 function mulMatrix(a, b) { | |
270 var dst = new Float32Array(16); | |
271 var a00 = a[0]; | |
272 var a01 = a[1]; | |
273 var a02 = a[2]; | |
274 var a03 = a[3]; | |
275 var a10 = a[ 4 + 0]; | |
276 var a11 = a[ 4 + 1]; | |
277 var a12 = a[ 4 + 2]; | |
278 var a13 = a[ 4 + 3]; | |
279 var a20 = a[ 8 + 0]; | |
280 var a21 = a[ 8 + 1]; | |
281 var a22 = a[ 8 + 2]; | |
282 var a23 = a[ 8 + 3]; | |
283 var a30 = a[12 + 0]; | |
284 var a31 = a[12 + 1]; | |
285 var a32 = a[12 + 2]; | |
286 var a33 = a[12 + 3]; | |
287 var b00 = b[0]; | |
288 var b01 = b[1]; | |
289 var b02 = b[2]; | |
290 var b03 = b[3]; | |
291 var b10 = b[ 4 + 0]; | |
292 var b11 = b[ 4 + 1]; | |
293 var b12 = b[ 4 + 2]; | |
294 var b13 = b[ 4 + 3]; | |
295 var b20 = b[ 8 + 0]; | |
296 var b21 = b[ 8 + 1]; | |
297 var b22 = b[ 8 + 2]; | |
298 var b23 = b[ 8 + 3]; | |
299 var b30 = b[12 + 0]; | |
300 var b31 = b[12 + 1]; | |
301 var b32 = b[12 + 2]; | |
302 var b33 = b[12 + 3]; | |
303 dst[ 0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30; | |
304 dst[ 1] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31; | |
305 dst[ 2] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32; | |
306 dst[ 3] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33; | |
307 dst[ 4] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30; | |
308 dst[ 5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31; | |
309 dst[ 6] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32; | |
310 dst[ 7] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33; | |
311 dst[ 8] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30; | |
312 dst[ 9] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31; | |
313 dst[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32; | |
314 dst[11] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33; | |
315 dst[12] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30; | |
316 dst[13] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31; | |
317 dst[14] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32; | |
318 dst[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33; | |
319 return dst; | |
320 }; | |
321 | |
322 successfullyParsed = true; | |
323 </script> | |
324 </body> | |
325 </html> | |
326 | |
327 | |
OLD | NEW |