tex-image-and-sub-image-utils.js (31237B)
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 var TexImageUtils = (function() { 7 8 "use strict"; 9 10 var wtu = WebGLTestUtils; 11 12 /** 13 * A vertex shader for a single texture. 14 * @type {string} 15 */ 16 var simpleTextureVertexShaderES3 = [ 17 '#version 300 es', 18 'in vec4 vPosition;', 19 'in vec2 texCoord0;', 20 'out vec2 texCoord;', 21 'void main() {', 22 ' gl_Position = vPosition;', 23 ' texCoord = texCoord0;', 24 '}'].join('\n'); 25 26 /** 27 * A fragment shader for a single unsigned integer texture. 28 * @type {string} 29 */ 30 // Note we always output 1.0 for alpha because if the texture does not contain 31 // alpha channel, sampling returns 1; for RGBA textures, sampling returns [0,255]. 32 var simpleUintTextureFragmentShaderES3 = [ 33 '#version 300 es', 34 'precision mediump float;', 35 'uniform mediump usampler2D tex;', 36 'in vec2 texCoord;', 37 'out vec4 fragData;', 38 'void main() {', 39 ' uvec4 data = texture(tex, texCoord);', 40 ' fragData = vec4(float(data[0])/255.0,', 41 ' float(data[1])/255.0,', 42 ' float(data[2])/255.0,', 43 ' 1.0);', 44 '}'].join('\n'); 45 46 /** 47 * A fragment shader for a single signed integer texture. 48 * @type {string} 49 */ 50 // Note we always output 1.0 for alpha because if the texture does not contain 51 // alpha channel, sampling returns 1; for RGBA textures, sampling returns [0,255]. 52 var simpleIntTextureFragmentShaderES3 = [ 53 '#version 300 es', 54 'precision mediump float;', 55 'uniform mediump isampler2D tex;', 56 'in vec2 texCoord;', 57 'out vec4 fragData;', 58 'void main() {', 59 ' ivec4 data = texture(tex, texCoord);', 60 ' fragData = vec4(float(data[0])/255.0,', 61 ' float(data[1])/255.0,', 62 ' float(data[2])/255.0,', 63 ' 1.0);', 64 '}'].join('\n'); 65 66 /** 67 * A fragment shader for a single cube map unsigned integer texture. 68 * @type {string} 69 */ 70 // Note we always output 1.0 for alpha because if the texture does not contain 71 // alpha channel, sampling returns 1; for RGBA textures, sampling returns [0,255]. 72 var simpleCubeMapUintTextureFragmentShaderES3 = [ 73 '#version 300 es', 74 'precision mediump float;', 75 'uniform mediump usamplerCube tex;', 76 'uniform highp int face;', 77 'in vec2 texCoord;', 78 'out vec4 fragData;', 79 'void main() {', 80 // Transform [0, 1] -> [-1, 1] 81 ' vec2 texC2 = (texCoord * 2.) - 1.;', 82 // Transform 2d tex coord. to each face of TEXTURE_CUBE_MAP coord. 83 ' vec3 texCube = vec3(0., 0., 0.);', 84 ' if (face == 34069) {', // TEXTURE_CUBE_MAP_POSITIVE_X 85 ' texCube = vec3(1., -texC2.y, -texC2.x);', 86 ' } else if (face == 34070) {', // TEXTURE_CUBE_MAP_NEGATIVE_X 87 ' texCube = vec3(-1., -texC2.y, texC2.x);', 88 ' } else if (face == 34071) {', // TEXTURE_CUBE_MAP_POSITIVE_Y 89 ' texCube = vec3(texC2.x, 1., texC2.y);', 90 ' } else if (face == 34072) {', // TEXTURE_CUBE_MAP_NEGATIVE_Y 91 ' texCube = vec3(texC2.x, -1., -texC2.y);', 92 ' } else if (face == 34073) {', // TEXTURE_CUBE_MAP_POSITIVE_Z 93 ' texCube = vec3(texC2.x, -texC2.y, 1.);', 94 ' } else if (face == 34074) {', // TEXTURE_CUBE_MAP_NEGATIVE_Z 95 ' texCube = vec3(-texC2.x, -texC2.y, -1.);', 96 ' }', 97 ' uvec4 data = texture(tex, texCube);', 98 ' fragData = vec4(float(data[0])/255.0,', 99 ' float(data[1])/255.0,', 100 ' float(data[2])/255.0,', 101 ' 1.0);', 102 '}'].join('\n'); 103 104 /** 105 * A fragment shader for a single cube map signed integer texture. 106 * @type {string} 107 */ 108 // Note we always output 1.0 for alpha because if the texture does not contain 109 // alpha channel, sampling returns 1; for RGBA textures, sampling returns [0,255]. 110 var simpleCubeMapIntTextureFragmentShaderES3 = [ 111 '#version 300 es', 112 'precision mediump float;', 113 'uniform mediump isamplerCube tex;', 114 'uniform highp int face;', 115 'in vec2 texCoord;', 116 'out vec4 fragData;', 117 'void main() {', 118 // Transform [0, 1] -> [-1, 1] 119 ' vec2 texC2 = (texCoord * 2.) - 1.;', 120 // Transform 2d tex coord. to each face of TEXTURE_CUBE_MAP coord. 121 ' vec3 texCube = vec3(0., 0., 0.);', 122 ' if (face == 34069) {', // TEXTURE_CUBE_MAP_POSITIVE_X 123 ' texCube = vec3(1., -texC2.y, -texC2.x);', 124 ' } else if (face == 34070) {', // TEXTURE_CUBE_MAP_NEGATIVE_X 125 ' texCube = vec3(-1., -texC2.y, texC2.x);', 126 ' } else if (face == 34071) {', // TEXTURE_CUBE_MAP_POSITIVE_Y 127 ' texCube = vec3(texC2.x, 1., texC2.y);', 128 ' } else if (face == 34072) {', // TEXTURE_CUBE_MAP_NEGATIVE_Y 129 ' texCube = vec3(texC2.x, -1., -texC2.y);', 130 ' } else if (face == 34073) {', // TEXTURE_CUBE_MAP_POSITIVE_Z 131 ' texCube = vec3(texC2.x, -texC2.y, 1.);', 132 ' } else if (face == 34074) {', // TEXTURE_CUBE_MAP_NEGATIVE_Z 133 ' texCube = vec3(-texC2.x, -texC2.y, -1.);', 134 ' }', 135 ' ivec4 data = texture(tex, texCube);', 136 ' fragData = vec4(float(data[0])/255.0,', 137 ' float(data[1])/255.0,', 138 ' float(data[2])/255.0,', 139 ' 1.0);', 140 '}'].join('\n'); 141 142 /** 143 * A fragment shader for a single 3D texture. 144 * @type {string} 145 */ 146 // Note that the tex coordinate r (the uniform uRCoord) is set to 0.0 by default. 147 var simple3DTextureFragmentShaderES3 = [ 148 '#version 300 es', 149 'precision mediump float;', 150 'uniform mediump sampler3D tex;', 151 'in vec2 texCoord;', 152 'uniform float uRCoord;', 153 'out vec4 fragData;', 154 'void main() {', 155 ' fragData = vec4(texture(tex, vec3(texCoord, uRCoord)).rgb, 1.0);', 156 '}'].join('\n'); 157 158 /** 159 * A fragment shader for a single 3D unsigned integer texture. 160 * @type {string} 161 */ 162 // Note that the tex coordinate r (the uniform uRCoord) is set to 0.0 by default. 163 // Note we always output 1.0 for alpha because if the texture does not contain 164 // alpha channel, sampling returns 1; for RGBA textures, sampling returns [0,255]. 165 var simple3DUintTextureFragmentShaderES3 = [ 166 '#version 300 es', 167 'precision mediump float;', 168 'uniform mediump usampler3D tex;', 169 'in vec2 texCoord;', 170 'uniform float uRCoord;', 171 'out vec4 fragData;', 172 'void main() {', 173 ' uvec4 data = texture(tex, vec3(texCoord, uRCoord));', 174 ' fragData = vec4(float(data[0])/255.0,', 175 ' float(data[1])/255.0,', 176 ' float(data[2])/255.0,', 177 ' 1.0);', 178 '}'].join('\n'); 179 180 /** 181 * A fragment shader for a single 3D signed integer texture. 182 * @type {string} 183 */ 184 // Note that the tex coordinate r (the uniform uRCoord) is set to 0.0 by default. 185 // Note we always output 1.0 for alpha because if the texture does not contain 186 // alpha channel, sampling returns 1; for RGBA textures, sampling returns [0,255]. 187 var simple3DIntTextureFragmentShaderES3 = [ 188 '#version 300 es', 189 'precision mediump float;', 190 'uniform mediump isampler3D tex;', 191 'in vec2 texCoord;', 192 'uniform float uRCoord;', 193 'out vec4 fragData;', 194 'void main() {', 195 ' ivec4 data = texture(tex, vec3(texCoord, uRCoord));', 196 ' fragData = vec4(float(data[0])/255.0,', 197 ' float(data[1])/255.0,', 198 ' float(data[2])/255.0,', 199 ' 1.0);', 200 '}'].join('\n'); 201 202 /** 203 * A fragment shader for a single 2D_ARRAY texture. 204 * @type {string} 205 */ 206 // Note that the first image in the array (selected by the uniform 207 // uRCoord) is used by default. 208 var simple2DArrayTextureFragmentShaderES3 = [ 209 '#version 300 es', 210 'precision mediump float;', 211 'uniform mediump sampler2DArray tex;', 212 'in vec2 texCoord;', 213 'uniform float uRCoord;', 214 'out vec4 fragData;', 215 'void main() {', 216 ' fragData = vec4(texture(tex, vec3(texCoord, uRCoord)).rgb, 1.0);', 217 '}'].join('\n'); 218 219 /** 220 * A fragment shader for a single 2D_ARRAY unsigned integer texture. 221 * @type {string} 222 */ 223 // Note that the first image in the array (selected by the uniform 224 // uRCoord) is used by default. 225 // Note we always output 1.0 for alpha because if the texture does not contain 226 // alpha channel, sampling returns 1; for RGBA textures, sampling returns [0,255]. 227 var simple2DArrayUintTextureFragmentShaderES3 = [ 228 '#version 300 es', 229 'precision mediump float;', 230 'uniform mediump usampler2DArray tex;', 231 'in vec2 texCoord;', 232 'uniform float uRCoord;', 233 'out vec4 fragData;', 234 'void main() {', 235 ' uvec4 data = texture(tex, vec3(texCoord, uRCoord));', 236 ' fragData = vec4(float(data[0])/255.0,', 237 ' float(data[1])/255.0,', 238 ' float(data[2])/255.0,', 239 ' 1.0);', 240 '}'].join('\n'); 241 242 /** 243 * A fragment shader for a single 2D_ARRAY signed integer texture. 244 * @type {string} 245 */ 246 // Note that the first image in the array (selected by the uniform 247 // uRCoord) is used by default. 248 // Note we always output 1.0 for alpha because if the texture does not contain 249 // alpha channel, sampling returns 1; for RGBA textures, sampling returns [0,255]. 250 var simple2DArrayIntTextureFragmentShaderES3 = [ 251 '#version 300 es', 252 'precision mediump float;', 253 'uniform mediump isampler2DArray tex;', 254 'in vec2 texCoord;', 255 'uniform float uRCoord;', 256 'out vec4 fragData;', 257 'void main() {', 258 ' ivec4 data = texture(tex, vec3(texCoord, uRCoord));', 259 ' fragData = vec4(float(data[0])/255.0,', 260 ' float(data[1])/255.0,', 261 ' float(data[2])/255.0,', 262 ' 1.0);', 263 '}'].join('\n'); 264 265 266 /** 267 * Creates a simple texture vertex shader. 268 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 269 * @return {!WebGLShader} 270 */ 271 var setupSimpleTextureVertexShader = function(gl) { 272 return WebGLTestUtils.loadShader(gl, simpleTextureVertexShaderES3, gl.VERTEX_SHADER); 273 }; 274 275 /** 276 * Creates a simple unsigned integer texture fragment shader. 277 * Output is scaled by 1/255 to bring the result into normalized float range. 278 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 279 * @return {!WebGLShader} 280 */ 281 var setupSimpleUintTextureFragmentShader = function(gl) { 282 return WebGLTestUtils.loadShader(gl, simpleUintTextureFragmentShaderES3, gl.FRAGMENT_SHADER); 283 }; 284 285 /** 286 * Creates a simple signed integer texture fragment shader. 287 * Output is scaled by 1/255 to bring the result into normalized float range. 288 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 289 * @return {!WebGLShader} 290 */ 291 var setupSimpleIntTextureFragmentShader = function(gl) { 292 return WebGLTestUtils.loadShader(gl, simpleIntTextureFragmentShaderES3, gl.FRAGMENT_SHADER); 293 }; 294 295 /** 296 * Creates a simple cube map unsigned integer texture fragment shader. 297 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 298 * @return {!WebGLShader} 299 */ 300 var setupSimpleCubeMapUintTextureFragmentShader = function(gl) { 301 return WebGLTestUtils.loadShader(gl, simpleCubeMapUintTextureFragmentShaderES3, gl.FRAGMENT_SHADER); 302 }; 303 304 /** 305 * Creates a simple cube map signed integer texture fragment shader. 306 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 307 * @return {!WebGLShader} 308 */ 309 var setupSimpleCubeMapIntTextureFragmentShader = function(gl) { 310 return WebGLTestUtils.loadShader(gl, simpleCubeMapIntTextureFragmentShaderES3, gl.FRAGMENT_SHADER); 311 }; 312 313 /** 314 * Creates a simple 3D texture fragment shader. 315 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 316 * @return {!WebGLShader} 317 */ 318 var setupSimple3DTextureFragmentShader = function(gl) { 319 return WebGLTestUtils.loadShader(gl, simple3DTextureFragmentShaderES3, gl.FRAGMENT_SHADER); 320 }; 321 322 /** 323 * Creates a simple 3D unsigned integer texture fragment shader. 324 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 325 * @return {!WebGLShader} 326 */ 327 var setupSimple3DUintTextureFragmentShader = function(gl) { 328 return WebGLTestUtils.loadShader(gl, simple3DUintTextureFragmentShaderES3, gl.FRAGMENT_SHADER); 329 }; 330 331 /** 332 * Creates a simple 3D signed integer texture fragment shader. 333 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 334 * @return {!WebGLShader} 335 */ 336 var setupSimple3DIntTextureFragmentShader = function(gl) { 337 return WebGLTestUtils.loadShader(gl, simple3DIntTextureFragmentShaderES3, gl.FRAGMENT_SHADER); 338 }; 339 340 /** 341 * Creates a simple 2D_ARRAY texture fragment shader. 342 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 343 * @return {!WebGLShader} 344 */ 345 var setupSimple2DArrayTextureFragmentShader = function(gl) { 346 return WebGLTestUtils.loadShader(gl, simple2DArrayTextureFragmentShaderES3, gl.FRAGMENT_SHADER); 347 }; 348 349 /** 350 * Creates a simple 2D_ARRAY integer texture fragment shader. 351 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 352 * @return {!WebGLShader} 353 */ 354 var setupSimple2DArrayUintTextureFragmentShader = function(gl) { 355 return WebGLTestUtils.loadShader(gl, simple2DArrayUintTextureFragmentShaderES3, gl.FRAGMENT_SHADER); 356 }; 357 358 /** 359 * Creates a simple unsigned integer texture program. 360 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 361 * @param {number} opt_positionLocation The attrib location for position. 362 * @param {number} opt_texcoordLocation The attrib location for texture coords. 363 * @return {WebGLProgram} 364 */ 365 var setupSimpleUintTextureProgram = function(gl, opt_positionLocation, opt_texcoordLocation) 366 { 367 opt_positionLocation = opt_positionLocation || 0; 368 opt_texcoordLocation = opt_texcoordLocation || 1; 369 var vs = setupSimpleTextureVertexShader(gl), 370 fs = setupSimpleUintTextureFragmentShader(gl); 371 if (!vs || !fs) { 372 return null; 373 } 374 var program = WebGLTestUtils.setupProgram( 375 gl, 376 [vs, fs], 377 ['vPosition', 'texCoord0'], 378 [opt_positionLocation, opt_texcoordLocation]); 379 if (!program) { 380 gl.deleteShader(fs); 381 gl.deleteShader(vs); 382 } 383 gl.useProgram(program); 384 return program; 385 }; 386 387 /** 388 * Creates a simple signed integer texture program. 389 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 390 * @param {number} opt_positionLocation The attrib location for position. 391 * @param {number} opt_texcoordLocation The attrib location for texture coords. 392 * @return {WebGLProgram} 393 */ 394 var setupSimpleIntTextureProgram = function(gl, opt_positionLocation, opt_texcoordLocation) 395 { 396 opt_positionLocation = opt_positionLocation || 0; 397 opt_texcoordLocation = opt_texcoordLocation || 1; 398 var vs = setupSimpleTextureVertexShader(gl), 399 fs = setupSimpleIntTextureFragmentShader(gl); 400 if (!vs || !fs) { 401 return null; 402 } 403 var program = WebGLTestUtils.setupProgram( 404 gl, 405 [vs, fs], 406 ['vPosition', 'texCoord0'], 407 [opt_positionLocation, opt_texcoordLocation]); 408 if (!program) { 409 gl.deleteShader(fs); 410 gl.deleteShader(vs); 411 } 412 gl.useProgram(program); 413 return program; 414 }; 415 416 /** 417 * Creates a simple cube map unsigned integer texture program. 418 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 419 * @param {number} opt_positionLocation The attrib location for position. 420 * @param {number} opt_texcoordLocation The attrib location for texture coords. 421 * @return {WebGLProgram} 422 */ 423 var setupSimpleCubeMapUintTextureProgram = function(gl, opt_positionLocation, opt_texcoordLocation) { 424 opt_positionLocation = opt_positionLocation || 0; 425 opt_texcoordLocation = opt_texcoordLocation || 1; 426 var vs = setupSimpleTextureVertexShader(gl); 427 var fs = setupSimpleCubeMapUintTextureFragmentShader(gl); 428 if (!vs || !fs) { 429 return null; 430 } 431 var program = WebGLTestUtils.setupProgram( 432 gl, 433 [vs, fs], 434 ['vPosition', 'texCoord0'], 435 [opt_positionLocation, opt_texcoordLocation]); 436 if (!program) { 437 gl.deleteShader(fs); 438 gl.deleteShader(vs); 439 } 440 gl.useProgram(program); 441 return program; 442 }; 443 444 /** 445 * Creates a simple cube map signed integer texture program. 446 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 447 * @param {number} opt_positionLocation The attrib location for position. 448 * @param {number} opt_texcoordLocation The attrib location for texture coords. 449 * @return {WebGLProgram} 450 */ 451 var setupSimpleCubeMapIntTextureProgram = function(gl, opt_positionLocation, opt_texcoordLocation) { 452 opt_positionLocation = opt_positionLocation || 0; 453 opt_texcoordLocation = opt_texcoordLocation || 1; 454 var vs = setupSimpleTextureVertexShader(gl); 455 var fs = setupSimpleCubeMapIntTextureFragmentShader(gl); 456 if (!vs || !fs) { 457 return null; 458 } 459 var program = WebGLTestUtils.setupProgram( 460 gl, 461 [vs, fs], 462 ['vPosition', 'texCoord0'], 463 [opt_positionLocation, opt_texcoordLocation]); 464 if (!program) { 465 gl.deleteShader(fs); 466 gl.deleteShader(vs); 467 } 468 gl.useProgram(program); 469 return program; 470 }; 471 472 /** 473 * Creates a simple 3D texture program. 474 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 475 * @param {number} opt_positionLocation The attrib location for position. 476 * @param {number} opt_texcoordLocation The attrib location for texture coords. 477 * @return {WebGLProgram} 478 */ 479 var setupSimple3DTextureProgram = function(gl, opt_positionLocation, opt_texcoordLocation) 480 { 481 opt_positionLocation = opt_positionLocation || 0; 482 opt_texcoordLocation = opt_texcoordLocation || 1; 483 var vs = setupSimpleTextureVertexShader(gl), 484 fs = setupSimple3DTextureFragmentShader(gl); 485 if (!vs || !fs) { 486 return null; 487 } 488 var program = WebGLTestUtils.setupProgram( 489 gl, 490 [vs, fs], 491 ['vPosition', 'texCoord0'], 492 [opt_positionLocation, opt_texcoordLocation]); 493 if (!program) { 494 gl.deleteShader(fs); 495 gl.deleteShader(vs); 496 } 497 gl.useProgram(program); 498 return program; 499 }; 500 501 /** 502 * Creates a simple 3D unsigned integer texture program. 503 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 504 * @param {number} opt_positionLocation The attrib location for position. 505 * @param {number} opt_texcoordLocation The attrib location for texture coords. 506 * @return {WebGLProgram} 507 */ 508 var setupSimple3DUintTextureProgram = function(gl, opt_positionLocation, opt_texcoordLocation) 509 { 510 opt_positionLocation = opt_positionLocation || 0; 511 opt_texcoordLocation = opt_texcoordLocation || 1; 512 var vs = setupSimpleTextureVertexShader(gl), 513 fs = setupSimple3DUintTextureFragmentShader(gl); 514 if (!vs || !fs) { 515 return null; 516 } 517 var program = WebGLTestUtils.setupProgram( 518 gl, 519 [vs, fs], 520 ['vPosition', 'texCoord0'], 521 [opt_positionLocation, opt_texcoordLocation]); 522 if (!program) { 523 gl.deleteShader(fs); 524 gl.deleteShader(vs); 525 } 526 gl.useProgram(program); 527 return program; 528 }; 529 530 /** 531 * Creates a simple 3D signed integer texture program. 532 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 533 * @param {number} opt_positionLocation The attrib location for position. 534 * @param {number} opt_texcoordLocation The attrib location for texture coords. 535 * @return {WebGLProgram} 536 */ 537 var setupSimple3DIntTextureProgram = function(gl, opt_positionLocation, opt_texcoordLocation) 538 { 539 opt_positionLocation = opt_positionLocation || 0; 540 opt_texcoordLocation = opt_texcoordLocation || 1; 541 var vs = setupSimpleTextureVertexShader(gl), 542 fs = setupSimple3DIntTextureFragmentShader(gl); 543 if (!vs || !fs) { 544 return null; 545 } 546 var program = WebGLTestUtils.setupProgram( 547 gl, 548 [vs, fs], 549 ['vPosition', 'texCoord0'], 550 [opt_positionLocation, opt_texcoordLocation]); 551 if (!program) { 552 gl.deleteShader(fs); 553 gl.deleteShader(vs); 554 } 555 gl.useProgram(program); 556 return program; 557 }; 558 559 /** 560 * Creates a simple 2D_ARRAY texture program. 561 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 562 * @param {number} opt_positionLocation The attrib location for position. 563 * @param {number} opt_texcoordLocation The attrib location for texture coords. 564 * @return {WebGLProgram} 565 */ 566 var setupSimple2DArrayTextureProgram = function(gl, opt_positionLocation, opt_texcoordLocation) 567 { 568 opt_positionLocation = opt_positionLocation || 0; 569 opt_texcoordLocation = opt_texcoordLocation || 1; 570 var vs = setupSimpleTextureVertexShader(gl), 571 fs = setupSimple2DArrayTextureFragmentShader(gl); 572 if (!vs || !fs) { 573 return null; 574 } 575 var program = WebGLTestUtils.setupProgram( 576 gl, 577 [vs, fs], 578 ['vPosition', 'texCoord0'], 579 [opt_positionLocation, opt_texcoordLocation]); 580 if (!program) { 581 gl.deleteShader(fs); 582 gl.deleteShader(vs); 583 } 584 gl.useProgram(program); 585 return program; 586 }; 587 588 /** 589 * Creates a simple 2D_ARRAY unsigned integer texture program. 590 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 591 * @param {number} opt_positionLocation The attrib location for position. 592 * @param {number} opt_texcoordLocation The attrib location for texture coords. 593 * @return {WebGLProgram} 594 */ 595 var setupSimple2DArrayUintTextureProgram = function(gl, opt_positionLocation, opt_texcoordLocation) 596 { 597 opt_positionLocation = opt_positionLocation || 0; 598 opt_texcoordLocation = opt_texcoordLocation || 1; 599 var vs = setupSimpleTextureVertexShader(gl), 600 fs = setupSimple2DArrayUintTextureFragmentShader(gl); 601 if (!vs || !fs) { 602 return null; 603 } 604 var program = WebGLTestUtils.setupProgram( 605 gl, 606 [vs, fs], 607 ['vPosition', 'texCoord0'], 608 [opt_positionLocation, opt_texcoordLocation]); 609 if (!program) { 610 gl.deleteShader(fs); 611 gl.deleteShader(vs); 612 } 613 gl.useProgram(program); 614 return program; 615 }; 616 617 /** 618 * Creates a simple 2D_ARRAY signed integer texture program. 619 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 620 * @param {number} opt_positionLocation The attrib location for position. 621 * @param {number} opt_texcoordLocation The attrib location for texture coords. 622 * @return {WebGLProgram} 623 */ 624 var setupSimple2DArrayIntTextureProgram = function(gl, opt_positionLocation, opt_texcoordLocation) 625 { 626 opt_positionLocation = opt_positionLocation || 0; 627 opt_texcoordLocation = opt_texcoordLocation || 1; 628 var vs = setupSimpleTextureVertexShader(gl), 629 fs = setupSimple2DArrayIntTextureFragmentShader(gl); 630 if (!vs || !fs) { 631 return null; 632 } 633 var program = WebGLTestUtils.setupProgram( 634 gl, 635 [vs, fs], 636 ['vPosition', 'texCoord0'], 637 [opt_positionLocation, opt_texcoordLocation]); 638 if (!program) { 639 gl.deleteShader(fs); 640 gl.deleteShader(vs); 641 } 642 gl.useProgram(program); 643 return program; 644 }; 645 646 /** 647 * Creates a program and buffers for rendering a unsigned integer textured quad. 648 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 649 * @return {!WebGLProgram} 650 */ 651 var setupUintTexturedQuad = function(gl) { 652 var program = setupSimpleUintTextureProgram(gl); 653 wtu.setupUnitQuad(gl); 654 return program; 655 }; 656 657 /** 658 * Creates a program and buffers for rendering a signed integer textured quad. 659 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 660 * @return {!WebGLProgram} 661 */ 662 var setupIntTexturedQuad = function(gl) { 663 var program = setupSimpleIntTextureProgram(gl); 664 wtu.setupUnitQuad(gl); 665 return program; 666 }; 667 668 /** 669 * Creates a program and buffers for rendering a textured quad with 670 * a cube map unsigned integer texture. 671 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 672 * @return {!WebGLProgram} 673 */ 674 var setupUintTexturedQuadWithCubeMap = function(gl) 675 { 676 var program = setupSimpleCubeMapUintTextureProgram(gl); 677 wtu.setupUnitQuad(gl); 678 return program; 679 }; 680 681 /** 682 * Creates a program and buffers for rendering a textured quad with 683 * a cube map signed integer texture. 684 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 685 * @return {!WebGLProgram} 686 */ 687 var setupIntTexturedQuadWithCubeMap = function(gl) 688 { 689 var program = setupSimpleCubeMapIntTextureProgram(gl); 690 wtu.setupUnitQuad(gl); 691 return program; 692 }; 693 694 /** 695 * Does the GL internal format represent an unsigned integer format 696 * texture? 697 * @return {boolean} 698 */ 699 var isUintFormat = function(internalFormat) 700 { 701 return (internalFormat == "R8UI" || internalFormat == "RG8UI" || internalFormat == "RGB8UI" || internalFormat == "RGBA8UI" || 702 internalFormat == "R16UI" || internalFormat == "RG16UI" || internalFormat == "RGB16UI" || internalFormat == "RGBA16UI" || 703 internalFormat == "R32UI" || internalFormat == "RG32UI" || internalFormat == "RGB32UI" || internalFormat == "RGBA32UI"); 704 }; 705 706 /** 707 * Does the GL internal format represent an signed integer format 708 * texture? 709 * @return {boolean} 710 */ 711 var isIntFormat = function(internalFormat) 712 { 713 return (internalFormat == "R8I" || internalFormat == "RG8I" || internalFormat == "RGB8I" || internalFormat == "RGBA8I" || 714 internalFormat == "R16I" || internalFormat == "RG16I" || internalFormat == "RGB16I" || internalFormat == "RGBA16I" || 715 internalFormat == "R32I" || internalFormat == "RG32I" || internalFormat == "RGB32I" || internalFormat == "RGBA32I"); 716 }; 717 718 /** 719 * Createa a program and buffers for rendering a textured quad for 720 * tex-image-and-sub-image tests. Handle selection of correct 721 * program to handle texture format. 722 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 723 * @param {string} internalFormat The internal format for texture to be tested. 724 */ 725 var setupTexturedQuad = function(gl, internalFormat) 726 { 727 if (isUintFormat(internalFormat)) 728 return setupUintTexturedQuad(gl); 729 if (isIntFormat(internalFormat)) 730 return setupIntTexturedQuad(gl); 731 return wtu.setupTexturedQuad(gl); 732 }; 733 734 /** 735 * Createa a program and buffers for rendering a textured quad with 736 * a cube map for tex-image-and-sub-image tests. Handle selection of 737 * correct program to handle texture format. 738 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 739 * @param {string} internalFormat The internal format for texture to be tested. 740 */ 741 function setupTexturedQuadWithCubeMap(gl, internalFormat) 742 { 743 if (isUintFormat(internalFormat)) 744 return setupUintTexturedQuadWithCubeMap(gl); 745 if (isIntFormat(internalFormat)) 746 return setupIntTexturedQuadWithCubeMap(gl); 747 return wtu.setupTexturedQuadWithCubeMap(gl); 748 } 749 750 /** 751 * Createa a program and buffers for rendering a textured quad with a 3D texture 752 * for tex-image-and-sub-image tests. Handle selection of correct 753 * program to handle texture format. 754 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 755 * @param {string} internalFormat The internal format for texture to be tested. 756 */ 757 var setupTexturedQuadWith3D = function(gl, internalFormat) 758 { 759 var program; 760 if (isUintFormat(internalFormat)) 761 program = setupSimple3DUintTextureProgram(gl); 762 else if (isIntFormat(internalFormat)) 763 program = setupSimple3DIntTextureProgram(gl); 764 else 765 program = setupSimple3DTextureProgram(gl); 766 var uRCoordLoc = gl.getUniformLocation(program, 'uRCoord'); 767 gl.uniform1f(uRCoordLoc, 0.0); 768 wtu.setupUnitQuad(gl); 769 return program; 770 }; 771 772 /** 773 * Createa a program and buffers for rendering a textured quad with a 2D_ARRAY 774 * texture for tex-image-and-sub-image tests. Handle selection of correct 775 * program to handle texture format. 776 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. 777 * @param {string} internalFormat The internal format for texture to be tested. 778 */ 779 var setupTexturedQuadWith2DArray = function(gl, internalFormat) 780 { 781 var program; 782 if (isUintFormat(internalFormat)) 783 program = setupSimple2DArrayUintTextureProgram(gl); 784 else if (isIntFormat(internalFormat)) 785 program = setupSimple2DArrayIntTextureProgram(gl); 786 else 787 program = setupSimple2DArrayTextureProgram(gl); 788 var uRCoordLoc = gl.getUniformLocation(program, 'uRCoord'); 789 gl.uniform1f(uRCoordLoc, 0.0); 790 wtu.setupUnitQuad(gl); 791 return program; 792 }; 793 794 /** 795 * Return a list of unpack color spaces to test, supported by the specified 796 * WebGLRenderingContext. 797 */ 798 var unpackColorSpacesToTest = function(gl) 799 { 800 if ('unpackColorSpace' in gl) 801 return ['srgb', 'display-p3']; 802 else 803 return [undefined]; 804 } 805 806 /** 807 * For each entry in unpackColorSpaces, duplicate all of cases, adding an 808 * unpackColorSpace key with its value set to that entry to each case. 809 */ 810 var crossProductTestCasesWithUnpackColorSpaces = function(testCaseList, unpackColorSpaces) 811 { 812 var testCaseWithUnpackColorSpace = function(testCase, colorSpace) 813 { 814 return {...testCase, ...{unpackColorSpace:colorSpace}}; 815 } 816 var listOfTestCaseLists = unpackColorSpaces.map(colorSpace => 817 testCaseList.map(testCase => testCaseWithUnpackColorSpace(testCase, colorSpace))); 818 return listOfTestCaseLists.flat(); 819 } 820 821 /** 822 * Given given an internalformat, format, and type, return the tolerance 823 * that should be used when comparing an input 8-bit value to one that has 824 * been truncated through the specified formats. 825 */ 826 var tolerance = function(internalformat, format, type) { 827 function typeTolerance(type) { 828 switch(type) { 829 case 'UNSIGNED_SHORT_5_6_5': 830 case 'UNSIGNED_SHORT_5_5_5_1': 831 return 255 / 31; 832 case 'UNSIGNED_SHORT_4_4_4_4': 833 return 255 / 15; 834 break; 835 default: 836 return 1; 837 } 838 }; 839 function formatTolerance(format) { 840 switch(format) { 841 case 'RGB565': 842 case 'RGB5_A1': 843 return 255/31; 844 case 'RGBA4': 845 return 255/15; 846 default: 847 return 1; 848 } 849 }; 850 return Math.max(formatTolerance(internalformat), 851 formatTolerance(format), 852 typeTolerance(type)); 853 } 854 855 return { 856 setupTexturedQuad: setupTexturedQuad, 857 setupTexturedQuadWithCubeMap: setupTexturedQuadWithCubeMap, 858 setupTexturedQuadWith3D: setupTexturedQuadWith3D, 859 setupTexturedQuadWith2DArray: setupTexturedQuadWith2DArray, 860 unpackColorSpacesToTest: unpackColorSpacesToTest, 861 crossProductTestCasesWithUnpackColorSpaces: crossProductTestCasesWithUnpackColorSpaces, 862 tolerance: tolerance 863 }; 864 865 }());