gl-uniform-arrays.html (26272B)
1 <!-- 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. 5 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>WebGL uniform array Conformance Tests</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> 15 </head> 16 <body> 17 <div id="description"></div> 18 <div id="console"></div> 19 <canvas id="example" width="2" height="2"> </canvas> 20 <script id="vshader" type="x-shader/x-vertex"> 21 attribute vec4 a_position; 22 void main() 23 { 24 gl_Position = a_position; 25 } 26 </script> 27 28 <script id="fshader" type="x-shader/x-fragment"> 29 precision mediump float; 30 uniform $(type) color[3]; 31 void main() 32 { 33 gl_FragColor = vec4(color[0]$(elem), color[1]$(elem), color[2]$(elem), 1); 34 } 35 </script> 36 <script id="vshader300" type="x-shader/x-vertex"> 37 #version 300 es 38 in vec4 a_position; 39 void main() 40 { 41 gl_Position = a_position; 42 } 43 </script> 44 45 <script id="fshader300" type="x-shader/x-fragment"> 46 #version 300 es 47 precision mediump float; 48 uniform $(type) color[3]; 49 out vec4 o_FragColor; 50 void main() 51 { 52 o_FragColor = vec4(color[0]$(elem), color[1]$(elem), color[2]$(elem), 1); 53 } 54 </script> 55 <script> 56 "use strict"; 57 description(); 58 debug(""); 59 // MaxInt32 is 2^32-1. We need +1 of that to test overflow conditions. 60 var MaxInt32PlusOne = 4294967296; 61 var wtu = WebGLTestUtils; 62 var gl = wtu.create3DContext("example"); 63 64 const contextVersion = wtu.getDefault3DContextVersion(); 65 66 let [vElemId, fElemId] = ["vshader", "fshader"]; 67 if (contextVersion >= 2) { 68 [vElemId, fElemId] = ["vshader300", "fshader300"]; 69 } 70 71 var vSrc = wtu.getScript(vElemId).trim(); 72 var fTemplate = wtu.getScript(fElemId).trim(); 73 74 const typeInfos = [ 75 { type: 'float', 76 jsTypeOf: 'number', 77 setter: 'uniform1fv', 78 elem: '', 79 numSrcValues: 3, 80 invalidSet: function(loc) { 81 gl.uniform2fv(loc, [1, 2]); 82 }, 83 srcValueAsString: function(index, srcValues) { 84 return srcValues[index].toString(); 85 }, 86 returnValueAsString: function(value) { 87 return value === null ? 'null' : value.toString(); 88 }, 89 checkType: function(value) { 90 return typeof value === 'number'; 91 }, 92 checkValue: function(typeInfo, index, value) { 93 return typeInfo.srcValues[index] == value; 94 }, 95 srcValues: [16, 15, 14], 96 srcValuesLess: [], 97 srcValuesLessMultiple: [16], 98 srcValuesMoreMultiple: [16, 15, 14, 13], 99 srcValuesNonMultiple: null, 100 }, 101 { type: 'vec2', 102 jsTypeOf: 'Float32Array', 103 setter: 'uniform2fv', 104 elem: '[1]', 105 numSrcValues: 3, 106 invalidSet: function(loc) { 107 gl.uniform1fv(loc, [2]); 108 }, 109 illegalSet: function(loc) { 110 gl.uniform1fv(loc, 2); 111 }, 112 srcValueAsString: function(index, srcValues) { 113 return "[" + srcValues[index * 2 + 0].toString() + ", " + 114 srcValues[index * 2 + 1].toString() + "]"; 115 }, 116 returnValueAsString: function(value) { 117 return value === null ? 'null' : ("[" + value[0] + ", " + value[1] + "]"); 118 }, 119 checkType: function(value) { 120 return value && 121 typeof value.length === 'number' && 122 value.length == 2; 123 }, 124 checkValue: function(typeInfo, index, value) { 125 return value !== null && 126 typeInfo.srcValues[index * 2 + 0] == value[0] && 127 typeInfo.srcValues[index * 2 + 1] == value[1]; 128 }, 129 srcValues: [16, 15, 14, 13, 12, 11], 130 srcValuesLess: [16], 131 srcValuesLessMultiple: [16, 15, 14, 13], 132 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9], 133 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10], 134 }, 135 { type: 'vec3', 136 jsTypeOf: 'Float32Array', 137 setter: 'uniform3fv', 138 elem: '[2]', 139 numSrcValues: 3, 140 invalidSet: function(loc) { 141 gl.uniform1fv(loc, [2]); 142 }, 143 illegalSet: function(loc) { 144 gl.uniform1fv(loc, 2); 145 }, 146 srcValueAsString: function(index, srcValues) { 147 return "[" + srcValues[index * 3 + 0].toString() + ", " + 148 srcValues[index * 3 + 1].toString() + ", " + 149 srcValues[index * 3 + 2].toString() + "]"; 150 }, 151 returnValueAsString: function(value) { 152 return value === null ? 'null' : 153 ("[" + value[0] + ", " + value[1] + ", " + value[2] + "]"); 154 }, 155 checkType: function(value) { 156 return value && 157 typeof value.length === 'number' && 158 value.length == 3; 159 }, 160 checkValue: function(typeInfo, index, value) { 161 return value !== null && 162 typeInfo.srcValues[index * 3 + 0] == value[0] && 163 typeInfo.srcValues[index * 3 + 1] == value[1] && 164 typeInfo.srcValues[index * 3 + 2] == value[2]; 165 }, 166 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8], 167 srcValuesLess: [16, 15], 168 srcValuesLessMultiple: [16, 15, 14, 13, 12, 11], 169 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2], 170 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7], 171 }, 172 { type: 'vec4', 173 jsTypeOf: 'Float32Array', 174 setter: 'uniform4fv', 175 elem: '[3]', 176 numSrcValues: 3, 177 invalidSet: function(loc) { 178 gl.uniform1fv(loc, [2]); 179 }, 180 illegalSet: function(loc) { 181 gl.uniform1fv(loc, 2); 182 }, 183 srcValueAsString: function(index, srcValues) { 184 return "[" + srcValues[index * 4 + 0].toString() + ", " + 185 srcValues[index * 4 + 1].toString() + ", " + 186 srcValues[index * 4 + 2].toString() + ", " + 187 srcValues[index * 4 + 3].toString() + "]"; 188 }, 189 returnValueAsString: function(value) { 190 return value === null ? 'null' : 191 ("[" + value[0] + ", " + value[1] + 192 ", " + value[2] + ", " + value[3] + "]"); 193 }, 194 checkType: function(value) { 195 return value && 196 typeof value.length === 'number' && 197 value.length == 4; 198 }, 199 checkValue: function(typeInfo, index, value) { 200 return value !== null && 201 typeInfo.srcValues[index * 4 + 0] == value[0] && 202 typeInfo.srcValues[index * 4 + 1] == value[1] && 203 typeInfo.srcValues[index * 4 + 2] == value[2] && 204 typeInfo.srcValues[index * 4 + 3] == value[3]; 205 }, 206 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], 207 srcValuesLess: [16, 15, 14], 208 srcValuesLessMultiple: [16, 15, 14, 13, 12, 11, 10, 9], 209 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 210 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4], 211 } 212 ]; 213 214 if (contextVersion >= 2) { 215 const more = [ 216 { type: 'int', 217 jsTypeOf: 'number', 218 setter: 'uniform1iv', 219 elem: '', 220 numSrcValues: 3, 221 invalidSet: function(loc) { 222 gl.uniform2iv(loc, [1, 2]); 223 }, 224 srcValueAsString: function(index, srcValues) { 225 return srcValues[index].toString(); 226 }, 227 returnValueAsString: function(value) { 228 return value === null ? 'null' : value.toString(); 229 }, 230 checkType: function(value) { 231 return typeof value === 'number'; 232 }, 233 checkValue: function(typeInfo, index, value) { 234 return typeInfo.srcValues[index] == value; 235 }, 236 srcValues: [16, 15, 14], 237 srcValuesLess: [], 238 srcValuesLessMultiple: [16], 239 srcValuesMoreMultiple: [16, 15, 14, 13], 240 srcValuesNonMultiple: null, 241 }, 242 { type: 'ivec2', 243 jsTypeOf: 'Int32Array', 244 setter: 'uniform2iv', 245 elem: '[1]', 246 numSrcValues: 3, 247 invalidSet: function(loc) { 248 gl.uniform1iv(loc, [2]); 249 }, 250 illegalSet: function(loc) { 251 gl.uniform1iv(loc, 2); 252 }, 253 srcValueAsString: function(index, srcValues) { 254 return "[" + srcValues[index * 2 + 0].toString() + ", " + 255 srcValues[index * 2 + 1].toString() + "]"; 256 }, 257 returnValueAsString: function(value) { 258 return value === null ? 'null' : ("[" + value[0] + ", " + value[1] + "]"); 259 }, 260 checkType: function(value) { 261 return value && 262 typeof value.length === 'number' && 263 value.length == 2; 264 }, 265 checkValue: function(typeInfo, index, value) { 266 return value !== null && 267 typeInfo.srcValues[index * 2 + 0] == value[0] && 268 typeInfo.srcValues[index * 2 + 1] == value[1]; 269 }, 270 srcValues: [16, 15, 14, 13, 12, 11], 271 srcValuesLess: [16], 272 srcValuesLessMultiple: [16, 15, 14, 13], 273 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9], 274 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10], 275 }, 276 { type: 'ivec3', 277 jsTypeOf: 'Int32Array', 278 setter: 'uniform3iv', 279 elem: '[2]', 280 numSrcValues: 3, 281 invalidSet: function(loc) { 282 gl.uniform1iv(loc, [2]); 283 }, 284 illegalSet: function(loc) { 285 gl.uniform1iv(loc, 2); 286 }, 287 srcValueAsString: function(index, srcValues) { 288 return "[" + srcValues[index * 3 + 0].toString() + ", " + 289 srcValues[index * 3 + 1].toString() + ", " + 290 srcValues[index * 3 + 2].toString() + "]"; 291 }, 292 returnValueAsString: function(value) { 293 return value === null ? 'null' : 294 ("[" + value[0] + ", " + value[1] + ", " + value[2] + "]"); 295 }, 296 checkType: function(value) { 297 return value && 298 typeof value.length === 'number' && 299 value.length == 3; 300 }, 301 checkValue: function(typeInfo, index, value) { 302 return value !== null && 303 typeInfo.srcValues[index * 3 + 0] == value[0] && 304 typeInfo.srcValues[index * 3 + 1] == value[1] && 305 typeInfo.srcValues[index * 3 + 2] == value[2]; 306 }, 307 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8], 308 srcValuesLess: [16, 15], 309 srcValuesLessMultiple: [16, 15, 14, 13, 12, 11], 310 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2], 311 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7], 312 }, 313 { type: 'ivec4', 314 jsTypeOf: 'Int32Array', 315 setter: 'uniform4iv', 316 elem: '[3]', 317 numSrcValues: 3, 318 invalidSet: function(loc) { 319 gl.uniform1iv(loc, [2]); 320 }, 321 illegalSet: function(loc) { 322 gl.uniform1iv(loc, 2); 323 }, 324 srcValueAsString: function(index, srcValues) { 325 return "[" + srcValues[index * 4 + 0].toString() + ", " + 326 srcValues[index * 4 + 1].toString() + ", " + 327 srcValues[index * 4 + 2].toString() + ", " + 328 srcValues[index * 4 + 3].toString() + "]"; 329 }, 330 returnValueAsString: function(value) { 331 return value === null ? 'null' : 332 ("[" + value[0] + ", " + value[1] + 333 ", " + value[2] + ", " + value[3] + "]"); 334 }, 335 checkType: function(value) { 336 return value && 337 typeof value.length === 'number' && 338 value.length == 4; 339 }, 340 checkValue: function(typeInfo, index, value) { 341 return value !== null && 342 typeInfo.srcValues[index * 4 + 0] == value[0] && 343 typeInfo.srcValues[index * 4 + 1] == value[1] && 344 typeInfo.srcValues[index * 4 + 2] == value[2] && 345 typeInfo.srcValues[index * 4 + 3] == value[3]; 346 }, 347 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], 348 srcValuesLess: [16, 15, 14], 349 srcValuesLessMultiple: [16, 15, 14, 13, 12, 11, 10, 9], 350 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 351 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4], 352 }, 353 354 355 { type: 'uint', 356 jsTypeOf: 'number', 357 setter: 'uniform1uiv', 358 elem: '', 359 numSrcValues: 3, 360 invalidSet: function(loc) { 361 gl.uniform2uiv(loc, [1, 2]); 362 }, 363 srcValueAsString: function(index, srcValues) { 364 return srcValues[index].toString(); 365 }, 366 returnValueAsString: function(value) { 367 return value === null ? 'null' : value.toString(); 368 }, 369 checkType: function(value) { 370 return typeof value === 'number'; 371 }, 372 checkValue: function(typeInfo, index, value) { 373 return typeInfo.srcValues[index] == value; 374 }, 375 srcValues: [16, 15, 14], 376 srcValuesLess: [], 377 srcValuesLessMultiple: [16], 378 srcValuesMoreMultiple: [16, 15, 14, 13], 379 srcValuesNonMultiple: null, 380 }, 381 { type: 'uvec2', 382 jsTypeOf: 'Uint32Array', 383 setter: 'uniform2uiv', 384 elem: '[1]', 385 numSrcValues: 3, 386 invalidSet: function(loc) { 387 gl.uniform1uiv(loc, [2]); 388 }, 389 illegalSet: function(loc) { 390 gl.uniform1uiv(loc, 2); 391 }, 392 srcValueAsString: function(index, srcValues) { 393 return "[" + srcValues[index * 2 + 0].toString() + ", " + 394 srcValues[index * 2 + 1].toString() + "]"; 395 }, 396 returnValueAsString: function(value) { 397 return value === null ? 'null' : ("[" + value[0] + ", " + value[1] + "]"); 398 }, 399 checkType: function(value) { 400 return value && 401 typeof value.length === 'number' && 402 value.length == 2; 403 }, 404 checkValue: function(typeInfo, index, value) { 405 return value !== null && 406 typeInfo.srcValues[index * 2 + 0] == value[0] && 407 typeInfo.srcValues[index * 2 + 1] == value[1]; 408 }, 409 srcValues: [16, 15, 14, 13, 12, 11], 410 srcValuesLess: [16], 411 srcValuesLessMultiple: [16, 15, 14, 13], 412 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9], 413 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10], 414 }, 415 { type: 'uvec3', 416 jsTypeOf: 'Uint32Array', 417 setter: 'uniform3uiv', 418 elem: '[2]', 419 numSrcValues: 3, 420 invalidSet: function(loc) { 421 gl.uniform1uiv(loc, [2]); 422 }, 423 illegalSet: function(loc) { 424 gl.uniform1uiv(loc, 2); 425 }, 426 srcValueAsString: function(index, srcValues) { 427 return "[" + srcValues[index * 3 + 0].toString() + ", " + 428 srcValues[index * 3 + 1].toString() + ", " + 429 srcValues[index * 3 + 2].toString() + "]"; 430 }, 431 returnValueAsString: function(value) { 432 return value === null ? 'null' : 433 ("[" + value[0] + ", " + value[1] + ", " + value[2] + "]"); 434 }, 435 checkType: function(value) { 436 return value && 437 typeof value.length === 'number' && 438 value.length == 3; 439 }, 440 checkValue: function(typeInfo, index, value) { 441 return value !== null && 442 typeInfo.srcValues[index * 3 + 0] == value[0] && 443 typeInfo.srcValues[index * 3 + 1] == value[1] && 444 typeInfo.srcValues[index * 3 + 2] == value[2]; 445 }, 446 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8], 447 srcValuesLess: [16, 15], 448 srcValuesLessMultiple: [16, 15, 14, 13, 12, 11], 449 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2], 450 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7], 451 }, 452 { type: 'uvec4', 453 jsTypeOf: 'Uint32Array', 454 setter: 'uniform4uiv', 455 elem: '[3]', 456 numSrcValues: 3, 457 invalidSet: function(loc) { 458 gl.uniform1uiv(loc, [2]); 459 }, 460 illegalSet: function(loc) { 461 gl.uniform1uiv(loc, 2); 462 }, 463 srcValueAsString: function(index, srcValues) { 464 return "[" + srcValues[index * 4 + 0].toString() + ", " + 465 srcValues[index * 4 + 1].toString() + ", " + 466 srcValues[index * 4 + 2].toString() + ", " + 467 srcValues[index * 4 + 3].toString() + "]"; 468 }, 469 returnValueAsString: function(value) { 470 return value === null ? 'null' : 471 ("[" + value[0] + ", " + value[1] + 472 ", " + value[2] + ", " + value[3] + "]"); 473 }, 474 checkType: function(value) { 475 return value && 476 typeof value.length === 'number' && 477 value.length == 4; 478 }, 479 checkValue: function(typeInfo, index, value) { 480 return value !== null && 481 typeInfo.srcValues[index * 4 + 0] == value[0] && 482 typeInfo.srcValues[index * 4 + 1] == value[1] && 483 typeInfo.srcValues[index * 4 + 2] == value[2] && 484 typeInfo.srcValues[index * 4 + 3] == value[3]; 485 }, 486 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], 487 srcValuesLess: [16, 15, 14], 488 srcValuesLessMultiple: [16, 15, 14, 13, 12, 11, 10, 9], 489 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 490 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4], 491 }, 492 493 494 { type: 'bool', 495 jsTypeOf: 'boolean', 496 setter: 'uniform1iv', 497 elem: '', 498 numSrcValues: 3, 499 invalidSet: function(loc) { 500 gl.uniform2iv(loc, [1, 2]); 501 }, 502 srcValueAsString: function(index, srcValues) { 503 return srcValues[index].toString(); 504 }, 505 returnValueAsString: function(value) { 506 return value === null ? 'null' : value.toString(); 507 }, 508 checkType: function(value) { 509 return typeof value === 'boolean'; 510 }, 511 checkValue: function(typeInfo, index, value) { 512 return typeInfo.srcValues[index] == value; 513 }, 514 srcValues: [true, true, true], 515 srcValuesLess: [], 516 srcValuesLessMultiple: [16], 517 srcValuesMoreMultiple: [16, 15, 14, 13], 518 srcValuesNonMultiple: null, 519 }, 520 { type: 'bvec2', 521 jsTypeOf: 'Float32Array', 522 setter: 'uniform2fv', 523 elem: '[1]', 524 numSrcValues: 3, 525 invalidSet: function(loc) { 526 gl.uniform1iv(loc, [2]); 527 }, 528 illegalSet: function(loc) { 529 gl.uniform1iv(loc, 2); 530 }, 531 srcValueAsString: function(index, srcValues) { 532 return "[" + srcValues[index * 2 + 0].toString() + ", " + 533 srcValues[index * 2 + 1].toString() + "]"; 534 }, 535 returnValueAsString: function(value) { 536 return value === null ? 'null' : ("[" + value[0] + ", " + value[1] + "]"); 537 }, 538 checkType: function(value) { 539 return value && 540 typeof value.length === 'number' && 541 value.length == 2; 542 }, 543 checkValue: function(typeInfo, index, value) { 544 return value !== null && 545 typeInfo.srcValues[index * 2 + 0] == value[0] && 546 typeInfo.srcValues[index * 2 + 1] == value[1]; 547 }, 548 srcValues: [true, true, true, true, true, true], 549 srcValuesLess: [16], 550 srcValuesLessMultiple: [16, 15, 14, 13], 551 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9], 552 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10], 553 }, 554 { type: 'bvec3', 555 jsTypeOf: 'Int32Array', 556 setter: 'uniform3iv', 557 elem: '[2]', 558 numSrcValues: 3, 559 invalidSet: function(loc) { 560 gl.uniform1iv(loc, [2]); 561 }, 562 illegalSet: function(loc) { 563 gl.uniform1iv(loc, 2); 564 }, 565 srcValueAsString: function(index, srcValues) { 566 return "[" + srcValues[index * 3 + 0].toString() + ", " + 567 srcValues[index * 3 + 1].toString() + ", " + 568 srcValues[index * 3 + 2].toString() + "]"; 569 }, 570 returnValueAsString: function(value) { 571 return value === null ? 'null' : 572 ("[" + value[0] + ", " + value[1] + ", " + value[2] + "]"); 573 }, 574 checkType: function(value) { 575 return value && 576 typeof value.length === 'number' && 577 value.length == 3; 578 }, 579 checkValue: function(typeInfo, index, value) { 580 return value !== null && 581 typeInfo.srcValues[index * 3 + 0] == value[0] && 582 typeInfo.srcValues[index * 3 + 1] == value[1] && 583 typeInfo.srcValues[index * 3 + 2] == value[2]; 584 }, 585 srcValues: [true, true, true, true, true, true, true, true, true], 586 srcValuesLess: [16, 15], 587 srcValuesLessMultiple: [16, 15, 14, 13, 12, 11], 588 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2], 589 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7], 590 }, 591 { type: 'bvec4', 592 jsTypeOf: 'Uint32Array', 593 setter: 'uniform4uiv', 594 elem: '[3]', 595 numSrcValues: 3, 596 invalidSet: function(loc) { 597 gl.uniform1iv(loc, [2]); 598 }, 599 illegalSet: function(loc) { 600 gl.uniform1iv(loc, 2); 601 }, 602 srcValueAsString: function(index, srcValues) { 603 return "[" + srcValues[index * 4 + 0].toString() + ", " + 604 srcValues[index * 4 + 1].toString() + ", " + 605 srcValues[index * 4 + 2].toString() + ", " + 606 srcValues[index * 4 + 3].toString() + "]"; 607 }, 608 returnValueAsString: function(value) { 609 return value === null ? 'null' : 610 ("[" + value[0] + ", " + value[1] + 611 ", " + value[2] + ", " + value[3] + "]"); 612 }, 613 checkType: function(value) { 614 return value && 615 typeof value.length === 'number' && 616 value.length == 4; 617 }, 618 checkValue: function(typeInfo, index, value) { 619 return value !== null && 620 typeInfo.srcValues[index * 4 + 0] == value[0] && 621 typeInfo.srcValues[index * 4 + 1] == value[1] && 622 typeInfo.srcValues[index * 4 + 2] == value[2] && 623 typeInfo.srcValues[index * 4 + 3] == value[3]; 624 }, 625 srcValues: [true, true, true, true, true, true, true, true, true, true, true, true], 626 srcValuesLess: [16, 15, 14], 627 srcValuesLessMultiple: [16, 15, 14, 13, 12, 11, 10, 9], 628 srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 629 srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4], 630 } 631 ]; 632 typeInfos.push(...more); 633 } 634 635 let loc; 636 for (var tt = 0; tt < typeInfos.length; ++tt) { 637 var typeInfo = typeInfos[tt]; 638 debug(""); 639 debug("check " + typeInfo.type); 640 var fSrc = wtu.replaceParams(fTemplate, typeInfo); 641 //debug("fSrc: " + fSrc); 642 var program = wtu.loadProgram(gl, vSrc, fSrc); 643 644 var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); 645 assertMsg(numUniforms == 1, "1 uniform found"); 646 var info = gl.getActiveUniform(program, 0); 647 assertMsg(info.name == "color[0]", 648 "uniform name is 'color[0]' not 'color' as per OpenGL ES 2.0.24 section 2.10"); 649 shouldBeNull("gl.getUniformLocation(program, 'color[" + MaxInt32PlusOne + "]');"); 650 loc = gl.getUniformLocation(program, "color[0]"); 651 if (!loc) throw 'Missing loc'; 652 var srcValues = typeInfo.srcValues; 653 var srcValuesLess = typeInfo.srcValuesLess; 654 var srcValuesLessMultiple = typeInfo.srcValuesLessMultiple; 655 var srcValuesMoreMultiple = typeInfo.srcValuesMoreMultiple; 656 var srcValuesNonMultiple = typeInfo.srcValuesNonMultiple; 657 658 // Try setting the value before using the program 659 gl[typeInfo.setter](loc, srcValues); 660 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 661 "should fail if there is no current program"); 662 663 gl.useProgram(program); 664 gl[typeInfo.setter](loc, srcValuesLess); 665 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, 666 "should fail with insufficient array size with gl." + typeInfo.setter); 667 if (srcValuesNonMultiple) { 668 gl[typeInfo.setter](loc, srcValuesNonMultiple); 669 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, 670 "should fail with non-multiple array size with gl." + typeInfo.setter); 671 } 672 673 const validDatas = [ 674 `new Float32Array(${srcValues.length})`, 675 `new Float32Array(new ArrayBuffer(4*${srcValues.length}))`, 676 ]; 677 if (window.SharedArrayBuffer) { 678 validDatas.push( 679 `new Float32Array(new SharedArrayBuffer(4*${srcValues.length}))` 680 ); 681 } 682 for (const x of validDatas) { 683 shouldNotThrow(`gl.${typeInfo.setter}(loc, ${x});`); 684 } 685 686 gl[typeInfo.setter](loc, srcValues); 687 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 688 "can set an array of uniforms with gl." + typeInfo.setter); 689 gl[typeInfo.setter](loc, srcValuesLessMultiple); 690 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 691 "can partially set an array of uniforms with gl." + typeInfo.setter + " with a smaller array"); 692 gl[typeInfo.setter](loc, srcValuesMoreMultiple); 693 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 694 "can set an array of uniforms with gl." + typeInfo.setter + " with a larger array"); 695 696 var values = gl.getUniform(program, loc); 697 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 698 "can call gl.getUniform"); 699 assertMsg(typeInfo.checkType(values), 700 "gl.getUniform returns the correct type. " + `(was ${values.constructor.name})`); 701 for (var ii = 0; ii < typeInfo.numSrcValues; ++ii) { 702 shouldBeNull("gl.getUniformLocation(program, 'color[" + (MaxInt32PlusOne + ii) + "]')"); 703 var elemLoc = gl.getUniformLocation(program, "color[" + ii + "]"); 704 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 705 "can get location of element " + ii + 706 " of array from gl.getUniformLocation"); 707 var value = gl.getUniform(program, elemLoc); 708 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 709 "can get value of element " + ii + " of array from gl.getUniform"); 710 assertMsg(typeInfo.checkValue(typeInfo, ii, value), 711 "value put in (" + typeInfo.srcValueAsString(ii, srcValues) + 712 ") matches value pulled out (" + 713 typeInfo.returnValueAsString(value) + ")"); 714 } 715 typeInfo.invalidSet(loc); 716 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 717 "using the wrong size of gl.Uniform fails"); 718 var exceptionCaught = false; 719 if (typeInfo.illegalSet) { 720 try { 721 typeInfo.illegalSet(loc); 722 } catch (e) { 723 exceptionCaught = true; 724 } 725 assertMsg(exceptionCaught, "passing non-array to glUniform*fv should throw TypeError"); 726 } 727 728 gl.useProgram(null); 729 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 730 "can call gl.useProgram(null)"); 731 } 732 733 var successfullyParsed = true; 734 735 </script> 736 <script src="../../js/js-test-post.js"></script> 737 </body> 738 </html>