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 |