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