WebGLTextures.js 35.9 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4
/**
 * @author mrdoob / http://mrdoob.com/
 */

W
WestLangley 已提交
5
import { LinearFilter, NearestFilter, RGBFormat, RGBAFormat, DepthFormat, DepthStencilFormat, UnsignedShortType, UnsignedIntType, UnsignedInt248Type, FloatType, HalfFloatType, ClampToEdgeWrapping, NearestMipmapLinearFilter, NearestMipmapNearestFilter } from '../../constants.js';
B
bentok 已提交
6
import { _Math } from '../../math/Math.js';
R
Rich Harris 已提交
7

M
Mugen87 已提交
8
function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) {
9

J
Joel 已提交
10
	var _videoTextures = new WeakMap();
11
	var _canvas;
12

M
Mr.doob 已提交
13
	//
14

15 16 17 18 19 20 21 22 23 24 25 26
	var useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined';

	function createCanvas( width, height ) {

		// Use OffscreenCanvas when available. Specially needed in web workers

		return useOffscreenCanvas ?
			new OffscreenCanvas( width, height ) :
			document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );

	}

M
Mugen87 已提交
27
	function resizeImage( image, needsPowerOfTwo, needsNewCanvas, maxSize ) {
28

M
Mugen87 已提交
29
		var scale = 1;
30

M
Mugen87 已提交
31
		// handle case if texture exceeds max size
32

M
Mugen87 已提交
33
		if ( image.width > maxSize || image.height > maxSize ) {
34

M
Mugen87 已提交
35
			scale = maxSize / Math.max( image.width, image.height );
36

M
Mugen87 已提交
37
		}
38

M
Mugen87 已提交
39
		// only perform resize if necessary
40

M
Mugen87 已提交
41
		if ( scale < 1 || needsPowerOfTwo === true ) {
42

M
Mugen87 已提交
43
			// only perform resize for certain image types
44

45 46 47
			if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
				( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
				( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
48

M
Mugen87 已提交
49
				var floor = needsPowerOfTwo ? _Math.floorPowerOfTwo : Math.floor;
50

51 52 53 54 55 56 57 58 59 60 61
				var width = floor( scale * image.width );
				var height = floor( scale * image.height );

				if ( _canvas === undefined ) _canvas = createCanvas( width, height );

				// cube textures can't reuse the same canvas

				var canvas = needsNewCanvas ? createCanvas( width, height ) : _canvas;

				canvas.width = width;
				canvas.height = height;
62

M
Mugen87 已提交
63
				var context = canvas.getContext( '2d' );
64
				context.drawImage( image, 0, 0, width, height );
65

66
				console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' );
67

68
				return canvas;
69

M
Mugen87 已提交
70
			} else {
71

M
Mugen87 已提交
72
				if ( 'data' in image ) {
73

M
Mugen87 已提交
74
					console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').' );
75

M
Mugen87 已提交
76
				}
77

M
Mugen87 已提交
78
				return image;
79

M
Mugen87 已提交
80
			}
81 82 83 84 85 86 87

		}

		return image;

	}

M
Mugen87 已提交
88 89 90 91 92 93
	function isPowerOfTwo( image ) {

		return _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );

	}

94 95
	function textureNeedsPowerOfTwo( texture ) {

T
Takahiro 已提交
96
		if ( capabilities.isWebGL2 ) return false;
T
Takahiro 已提交
97

M
Mr.doob 已提交
98 99 100
		return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||
			( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );

101 102
	}

103
	function textureNeedsGenerateMipmaps( texture, supportsMips ) {
104

105
		return texture.generateMipmaps && supportsMips &&
106
			texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
107 108 109

	}

110
	function generateMipmap( target, texture, width, height ) {
111 112 113

		_gl.generateMipmap( target );

114
		var textureProperties = properties.get( texture );
A
aardgoose 已提交
115 116

		// Note: Math.log( x ) * Math.LOG2E used instead of Math.log2( x ) which is not supported by IE11
117
		textureProperties.__maxMipLevel = Math.log( Math.max( width, height ) ) * Math.LOG2E;
118 119 120

	}

121 122
	function getInternalFormat( glFormat, glType ) {

T
Takahiro 已提交
123
		if ( ! capabilities.isWebGL2 ) return glFormat;
T
Takahiro 已提交
124

125 126
		var internalFormat = glFormat;

A
artur.trzesiok 已提交
127
		if ( glFormat === _gl.RED ) {
A
artur.trzesiok 已提交
128

129 130 131
			if ( glType === _gl.FLOAT ) internalFormat = _gl.R32F;
			if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.R16F;
			if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = _gl.R8;
A
artur.trzesiok 已提交
132

A
artur.trzesiok 已提交
133
		}
A
artur.trzesiok 已提交
134

135 136
		if ( glFormat === _gl.RGB ) {

137 138 139
			if ( glType === _gl.FLOAT ) internalFormat = _gl.RGB32F;
			if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.RGB16F;
			if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = _gl.RGB8;
140 141 142 143

		}

		if ( glFormat === _gl.RGBA ) {
T
Takahiro 已提交
144

145 146 147 148 149 150
			if ( glType === _gl.FLOAT ) internalFormat = _gl.RGBA32F;
			if ( glType === _gl.HALF_FLOAT ) internalFormat = _gl.RGBA16F;
			if ( glType === _gl.UNSIGNED_BYTE ) internalFormat = _gl.RGBA8;

		}

V
vasco 已提交
151
		if ( internalFormat === _gl.R16F || internalFormat === _gl.R32F ||
152 153 154 155 156 157 158
			internalFormat === _gl.RGBA16F || internalFormat === _gl.RGBA32F ) {

			extensions.get( 'EXT_color_buffer_float' );

		} else if ( internalFormat === _gl.RGB16F || internalFormat === _gl.RGB32F ) {

			console.warn( 'THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead.' );
T
Takahiro 已提交
159 160

		}
161

162
		return internalFormat;
163 164 165

	}

166 167
	// Fallback filters for non-power-of-2 textures

M
Mr.doob 已提交
168
	function filterFallback( f ) {
169

W
WestLangley 已提交
170
		if ( f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter ) {
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189

			return _gl.NEAREST;

		}

		return _gl.LINEAR;

	}

	//

	function onTextureDispose( event ) {

		var texture = event.target;

		texture.removeEventListener( 'dispose', onTextureDispose );

		deallocateTexture( texture );

M
Mugen87 已提交
190 191
		if ( texture.isVideoTexture ) {

J
Joel 已提交
192
			_videoTextures.delete( texture );
M
Mugen87 已提交
193 194

		}
195

M
Mugen87 已提交
196
		info.memory.textures --;
197 198 199 200 201 202 203 204 205 206 207

	}

	function onRenderTargetDispose( event ) {

		var renderTarget = event.target;

		renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );

		deallocateRenderTarget( renderTarget );

M
Mugen87 已提交
208
		info.memory.textures --;
209 210 211 212 213 214 215 216 217

	}

	//

	function deallocateTexture( texture ) {

		var textureProperties = properties.get( texture );

M
Mugen87 已提交
218
		if ( textureProperties.__webglInit === undefined ) return;
219

M
Mugen87 已提交
220
		_gl.deleteTexture( textureProperties.__webglTexture );
221

222
		properties.remove( texture );
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244

	}

	function deallocateRenderTarget( renderTarget ) {

		var renderTargetProperties = properties.get( renderTarget );
		var textureProperties = properties.get( renderTarget.texture );

		if ( ! renderTarget ) return;

		if ( textureProperties.__webglTexture !== undefined ) {

			_gl.deleteTexture( textureProperties.__webglTexture );

		}

		if ( renderTarget.depthTexture ) {

			renderTarget.depthTexture.dispose();

		}

245
		if ( renderTarget.isWebGLRenderTargetCube ) {
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260

			for ( var i = 0; i < 6; i ++ ) {

				_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
				if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );

			}

		} else {

			_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
			if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );

		}

261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
		if ( renderTarget.isWebGLMultiviewRenderTarget ) {

			_gl.deleteTexture( renderTargetProperties.__webglColorTexture );
			_gl.deleteTexture( renderTargetProperties.__webglDepthStencilTexture );

			info.memory.textures -= 2;

			for ( var i = 0, il = renderTargetProperties.__webglViewFramebuffers.length; i < il; i ++ ) {

				_gl.deleteFramebuffer( renderTargetProperties.__webglViewFramebuffers[ i ] );

			}

		}

276 277
		properties.remove( renderTarget.texture );
		properties.remove( renderTarget );
278 279 280 281 282

	}

	//

283
	var textureUnits = 0;
284

285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
	function resetTextureUnits() {

		textureUnits = 0;

	}

	function allocateTextureUnit() {

		var textureUnit = textureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

			console.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );

		}

		textureUnits += 1;

		return textureUnit;

	}

	//
308 309 310 311 312

	function setTexture2D( texture, slot ) {

		var textureProperties = properties.get( texture );

313 314
		if ( texture.isVideoTexture ) updateVideoTexture( texture );

315 316 317 318 319 320
		if ( texture.version > 0 && textureProperties.__version !== texture.version ) {

			var image = texture.image;

			if ( image === undefined ) {

321
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined' );
322

323
			} else if ( image.complete === false ) {
324

325
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete' );
326

327
			} else {
328

329 330
				uploadTexture( textureProperties, texture, slot );
				return;
331

332
			}
333 334 335 336 337 338 339 340

		}

		state.activeTexture( _gl.TEXTURE0 + slot );
		state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );

	}

T
Takahiro 已提交
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
	function setTexture2DArray( texture, slot ) {

		var textureProperties = properties.get( texture );

		if ( texture.version > 0 && textureProperties.__version !== texture.version ) {

			uploadTexture( textureProperties, texture, slot );
			return;

		}

		state.activeTexture( _gl.TEXTURE0 + slot );
		state.bindTexture( _gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture );

	}

A
artur.trzesiok 已提交
357
	function setTexture3D( texture, slot ) {
A
artur.trzesiok 已提交
358

A
artur.trzesiok 已提交
359 360 361
		var textureProperties = properties.get( texture );

		if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
A
artur.trzesiok 已提交
362 363 364 365

			uploadTexture( textureProperties, texture, slot );
			return;

A
artur.trzesiok 已提交
366 367 368 369 370 371
		}

		state.activeTexture( _gl.TEXTURE0 + slot );
		state.bindTexture( _gl.TEXTURE_3D, textureProperties.__webglTexture );

	}
A
artur.trzesiok 已提交
372

M
Mr.doob 已提交
373
	function setTextureCube( texture, slot ) {
374

375 376
		if ( texture.image.length !== 6 ) return;

377 378
		var textureProperties = properties.get( texture );

379
		if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
380

381
			initTexture( textureProperties, texture );
382

383 384
			state.activeTexture( _gl.TEXTURE0 + slot );
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
385

386
			_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
387

388 389
			var isCompressed = ( texture && texture.isCompressedTexture );
			var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );
390

391
			var cubeImage = [];
392

393
			for ( var i = 0; i < 6; i ++ ) {
394

395
				if ( ! isCompressed && ! isDataTexture ) {
396

397
					cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, capabilities.maxCubemapSize );
398

399
				} else {
400

401
					cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
402

403
				}
404

405
			}
406

407 408 409 410 411
			var image = cubeImage[ 0 ],
				supportsMips = isPowerOfTwo( image ) || capabilities.isWebGL2,
				glFormat = utils.convert( texture.format ),
				glType = utils.convert( texture.type ),
				glInternalFormat = getInternalFormat( glFormat, glType );
412

413
			setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, supportsMips );
414

415
			var mipmaps;
416

417
			if ( isCompressed ) {
418

419 420
				for ( var i = 0; i < 6; i ++ ) {

421
					mipmaps = cubeImage[ i ].mipmaps;
422

423
					for ( var j = 0; j < mipmaps.length; j ++ ) {
424

425
						var mipmap = mipmaps[ j ];
426

427
						if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
A
angus 已提交
428

429
							if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
A
angus 已提交
430

431 432 433 434 435
								state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );

							} else {

								console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' );
A
angus 已提交
436 437 438

							}

439 440
						} else {

441
							state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
442

443
						}
444

445
					}
446

447
				}
448

449
				textureProperties.__maxMipLevel = mipmaps.length - 1;
450

451
			} else {
452

453
				mipmaps = texture.mipmaps;
454

455
				for ( var i = 0; i < 6; i ++ ) {
456

457
					if ( isDataTexture ) {
458

459
						state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );
460

461
						for ( var j = 0; j < mipmaps.length; j ++ ) {
462

463 464
							var mipmap = mipmaps[ j ];
							var mipmapImage = mipmap.image[ i ].image;
465

466
							state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data );
467

468
						}
469

470
					} else {
471

472
						state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] );
473

474
						for ( var j = 0; j < mipmaps.length; j ++ ) {
475

476
							var mipmap = mipmaps[ j ];
477

478
							state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] );
479 480 481 482 483 484 485

						}

					}

				}

486
				textureProperties.__maxMipLevel = mipmaps.length;
487

488
			}
489

490
			if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
491

492 493
				// We assume images for cube map have the same size.
				generateMipmap( _gl.TEXTURE_CUBE_MAP, texture, image.width, image.height );
494

495
			}
496

497
			textureProperties.__version = texture.version;
498

499
			if ( texture.onUpdate ) texture.onUpdate( texture );
500

501
		} else {
502

503 504
			state.activeTexture( _gl.TEXTURE0 + slot );
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
505 506 507 508 509

		}

	}

M
Mr.doob 已提交
510
	function setTextureCubeDynamic( texture, slot ) {
511 512 513 514 515 516

		state.activeTexture( _gl.TEXTURE0 + slot );
		state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );

	}

517
	function setTextureParameters( textureType, texture, supportsMips ) {
518 519 520

		var extension;

521
		if ( supportsMips ) {
522

523 524
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, utils.convert( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, utils.convert( texture.wrapT ) );
525

T
Takahiro 已提交
526
			if ( textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY ) {
527 528 529 530 531

				_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_R, utils.convert( texture.wrapR ) );

			}

532 533
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, utils.convert( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, utils.convert( texture.minFilter ) );
534 535 536 537 538 539

		} else {

			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );

T
Takahiro 已提交
540
			if ( textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY ) {
541 542 543 544 545

				_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_R, _gl.CLAMP_TO_EDGE );

			}

R
Rich Harris 已提交
546
			if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {
547

548
				console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.' );
549 550 551 552 553 554

			}

			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );

R
Rich Harris 已提交
555
			if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {
556

557
				console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.' );
558 559 560 561 562 563 564 565 566

			}

		}

		extension = extensions.get( 'EXT_texture_filter_anisotropic' );

		if ( extension ) {

R
Rich Harris 已提交
567
			if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
T
Takahiro 已提交
568
			if ( texture.type === HalfFloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) return;
569 570 571 572 573 574 575 576 577 578 579 580

			if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {

				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );
				properties.get( texture ).__currentAnisotropy = texture.anisotropy;

			}

		}

	}

M
Mugen87 已提交
581
	function initTexture( textureProperties, texture ) {
582 583 584 585 586 587 588 589 590

		if ( textureProperties.__webglInit === undefined ) {

			textureProperties.__webglInit = true;

			texture.addEventListener( 'dispose', onTextureDispose );

			textureProperties.__webglTexture = _gl.createTexture();

M
Mugen87 已提交
591
			info.memory.textures ++;
592 593

		}
A
artur.trzesiok 已提交
594

M
Mugen87 已提交
595
	}
A
artur.trzesiok 已提交
596

M
Mugen87 已提交
597 598
	function uploadTexture( textureProperties, texture, slot ) {

T
Takahiro 已提交
599 600 601 602
		var textureType = _gl.TEXTURE_2D;

		if ( texture.isDataTexture2DArray ) textureType = _gl.TEXTURE_2D_ARRAY;
		if ( texture.isDataTexture3D ) textureType = _gl.TEXTURE_3D;
A
artur.trzesiok 已提交
603

M
Mugen87 已提交
604
		initTexture( textureProperties, texture );
A
artur.trzesiok 已提交
605

M
Mugen87 已提交
606 607
		state.activeTexture( _gl.TEXTURE0 + slot );
		state.bindTexture( textureType, textureProperties.__webglTexture );
608 609 610 611 612

		_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
		_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
		_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );

M
Mugen87 已提交
613 614
		var needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false;
		var image = resizeImage( texture.image, needsPowerOfTwo, false, capabilities.maxTextureSize );
615

616
		var supportsMips = isPowerOfTwo( image ) || capabilities.isWebGL2,
M
Mugen87 已提交
617
			glFormat = utils.convert( texture.format ),
T
Takahiro 已提交
618 619
			glType = utils.convert( texture.type ),
			glInternalFormat = getInternalFormat( glFormat, glType );
620

621
		setTextureParameters( textureType, texture, supportsMips );
622 623 624

		var mipmap, mipmaps = texture.mipmaps;

625
		if ( texture.isDepthTexture ) {
626 627 628

			// populate depth texture with dummy data

T
Takahiro 已提交
629
			glInternalFormat = _gl.DEPTH_COMPONENT;
630

R
Rich Harris 已提交
631
			if ( texture.type === FloatType ) {
632

T
Takahiro 已提交
633
				if ( ! capabilities.isWebGL2 ) throw new Error( 'Float Depth Texture only supported in WebGL2.0' );
T
Takahiro 已提交
634
				glInternalFormat = _gl.DEPTH_COMPONENT32F;
635

T
Takahiro 已提交
636
			} else if ( capabilities.isWebGL2 ) {
637 638

				// WebGL 2.0 requires signed internalformat for glTexImage2D
T
Takahiro 已提交
639
				glInternalFormat = _gl.DEPTH_COMPONENT16;
640 641 642

			}

T
Takahiro 已提交
643
			if ( texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT ) {
T
Takahiro 已提交
644 645 646 647 648 649

				// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
				// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT
				// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
				if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {

M
Mugen87 已提交
650
					console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );
T
Takahiro 已提交
651 652

					texture.type = UnsignedShortType;
653
					glType = utils.convert( texture.type );
T
Takahiro 已提交
654 655 656 657 658

				}

			}

659 660
			// Depth stencil textures need the DEPTH_STENCIL internal format
			// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
661
			if ( texture.format === DepthStencilFormat ) {
662

T
Takahiro 已提交
663
				glInternalFormat = _gl.DEPTH_STENCIL;
664

T
Takahiro 已提交
665 666 667 668 669
				// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
				// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.
				// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
				if ( texture.type !== UnsignedInt248Type ) {

M
Mr.doob 已提交
670
					console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );
T
Takahiro 已提交
671 672

					texture.type = UnsignedInt248Type;
673
					glType = utils.convert( texture.type );
T
Takahiro 已提交
674 675 676

				}

677 678
			}

T
Takahiro 已提交
679
			state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null );
680

681
		} else if ( texture.isDataTexture ) {
682 683 684 685 686

			// use manually created mipmaps if available
			// if there are no manual mipmaps
			// set 0 level mipmap and then use GL to generate other mipmap levels

687
			if ( mipmaps.length > 0 && supportsMips ) {
688 689 690 691

				for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {

					mipmap = mipmaps[ i ];
T
Takahiro 已提交
692
					state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
693 694 695 696

				}

				texture.generateMipmaps = false;
697
				textureProperties.__maxMipLevel = mipmaps.length - 1;
698 699 700

			} else {

T
Takahiro 已提交
701
				state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data );
702
				textureProperties.__maxMipLevel = 0;
703 704 705

			}

706
		} else if ( texture.isCompressedTexture ) {
707 708 709 710 711

			for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {

				mipmap = mipmaps[ i ];

R
Rich Harris 已提交
712
				if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
713 714 715

					if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {

T
Takahiro 已提交
716
						state.compressedTexImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );
717 718 719

					} else {

M
Mugen87 已提交
720
						console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' );
721 722 723 724 725

					}

				} else {

T
Takahiro 已提交
726
					state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
727 728 729 730 731

				}

			}

732
			textureProperties.__maxMipLevel = mipmaps.length - 1;
733

T
Takahiro 已提交
734 735 736 737 738
		} else if ( texture.isDataTexture2DArray ) {

			state.texImage3D( _gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data );
			textureProperties.__maxMipLevel = 0;

T
Takahiro 已提交
739
		} else if ( texture.isDataTexture3D ) {
A
artur.trzesiok 已提交
740

T
Takahiro 已提交
741
			state.texImage3D( _gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data );
A
artur.trzesiok 已提交
742 743
			textureProperties.__maxMipLevel = 0;

744 745 746 747 748 749 750 751
		} else {

			// regular Texture (image, video, canvas)

			// use manually created mipmaps if available
			// if there are no manual mipmaps
			// set 0 level mipmap and then use GL to generate other mipmap levels

752
			if ( mipmaps.length > 0 && supportsMips ) {
753 754 755 756

				for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {

					mipmap = mipmaps[ i ];
T
Takahiro 已提交
757
					state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap );
758 759 760 761

				}

				texture.generateMipmaps = false;
762
				textureProperties.__maxMipLevel = mipmaps.length - 1;
763 764 765

			} else {

T
Takahiro 已提交
766
				state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image );
767
				textureProperties.__maxMipLevel = 0;
768 769 770 771 772

			}

		}

773
		if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
774

775
			generateMipmap( _gl.TEXTURE_2D, texture, image.width, image.height );
776 777

		}
778 779 780 781 782 783 784 785 786 787

		textureProperties.__version = texture.version;

		if ( texture.onUpdate ) texture.onUpdate( texture );

	}

	// Render targets

	// Setup storage for target texture and bind it to correct framebuffer
M
Mr.doob 已提交
788
	function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {
789

790 791
		var glFormat = utils.convert( renderTarget.texture.format );
		var glType = utils.convert( renderTarget.texture.type );
T
Takahiro 已提交
792
		var glInternalFormat = getInternalFormat( glFormat, glType );
793
		state.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
794 795 796 797 798 799 800
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );

	}

	// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
801
	function setupRenderBufferStorage( renderbuffer, renderTarget, isMultisample ) {
802 803 804 805 806

		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );

		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {

807 808 809 810 811 812 813 814 815 816 817 818
			if ( isMultisample ) {

				var samples = getRenderTargetSamples( renderTarget );

				_gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );

			} else {

				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );

			}

819 820 821 822
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );

		} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {

823 824 825 826
			if ( isMultisample ) {

				var samples = getRenderTargetSamples( renderTarget );

827
				_gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height );
828 829 830 831 832 833 834 835

			} else {

				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );

			}


836 837 838 839
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );

		} else {

840 841 842 843 844 845 846 847 848 849 850 851 852 853 854
			var glFormat = utils.convert( renderTarget.texture.format );
			var glType = utils.convert( renderTarget.texture.type );
			var glInternalFormat = getInternalFormat( glFormat, glType );

			if ( isMultisample ) {

				var samples = getRenderTargetSamples( renderTarget );

				_gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );

			} else {

				_gl.renderbufferStorage( _gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height );

			}
855 856 857 858 859 860 861 862

		}

		_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );

	}

	// Setup resources for a Depth Texture for a FBO (needs an extension)
M
Mr.doob 已提交
863
	function setupDepthTexture( framebuffer, renderTarget ) {
864

865
		var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );
M
Mugen87 已提交
866
		if ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' );
867 868 869

		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );

M
Mugen87 已提交
870
		if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {
871

M
Mugen87 已提交
872
			throw new Error( 'renderTarget.depthTexture must be an instance of THREE.DepthTexture' );
873 874 875 876

		}

		// upload an empty depth texture with framebuffer size
M
Mugen87 已提交
877
		if ( ! properties.get( renderTarget.depthTexture ).__webglTexture ||
878 879
				renderTarget.depthTexture.image.width !== renderTarget.width ||
				renderTarget.depthTexture.image.height !== renderTarget.height ) {
M
Mugen87 已提交
880

881 882 883
			renderTarget.depthTexture.image.width = renderTarget.width;
			renderTarget.depthTexture.image.height = renderTarget.height;
			renderTarget.depthTexture.needsUpdate = true;
M
Mugen87 已提交
884

885 886 887 888 889
		}

		setTexture2D( renderTarget.depthTexture, 0 );

		var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
890

891
		if ( renderTarget.depthTexture.format === DepthFormat ) {
892 893 894

			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );

895
		} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
896 897 898 899 900

			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );

		} else {

M
Mugen87 已提交
901
			throw new Error( 'Unknown depthTexture format' );
902 903

		}
904 905 906 907 908 909 910 911

	}

	// Setup GL resources for a non-texture depth buffer
	function setupDepthRenderbuffer( renderTarget ) {

		var renderTargetProperties = properties.get( renderTarget );

912
		var isCube = ( renderTarget.isWebGLRenderTargetCube === true );
913 914 915

		if ( renderTarget.depthTexture ) {

M
Mugen87 已提交
916
			if ( isCube ) throw new Error( 'target.depthTexture not supported in Cube render targets' );
917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957

			setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );

		} else {

			if ( isCube ) {

				renderTargetProperties.__webglDepthbuffer = [];

				for ( var i = 0; i < 6; i ++ ) {

					_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
					renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
					setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );

				}

			} else {

				_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
				renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
				setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );

			}

		}

		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );

	}

	// Set up GL resources for the render target
	function setupRenderTarget( renderTarget ) {

		var renderTargetProperties = properties.get( renderTarget );
		var textureProperties = properties.get( renderTarget.texture );

		renderTarget.addEventListener( 'dispose', onRenderTargetDispose );

		textureProperties.__webglTexture = _gl.createTexture();

M
Mugen87 已提交
958
		info.memory.textures ++;
959

960
		var isCube = ( renderTarget.isWebGLRenderTargetCube === true );
961
		var isMultisample = ( renderTarget.isWebGLMultisampleRenderTarget === true );
962
		var isMultiview = ( renderTarget.isWebGLMultiviewRenderTarget === true );
963
		var supportsMips = isPowerOfTwo( renderTarget ) || capabilities.isWebGL2;
964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980

		// Setup framebuffer

		if ( isCube ) {

			renderTargetProperties.__webglFramebuffer = [];

			for ( var i = 0; i < 6; i ++ ) {

				renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();

			}

		} else {

			renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();

981 982
			if ( isMultisample ) {

983
				if ( capabilities.isWebGL2 ) {
984

985 986
					renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer();
					renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer();
987

988 989 990 991 992 993
					_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer );
					var glFormat = utils.convert( renderTarget.texture.format );
					var glType = utils.convert( renderTarget.texture.type );
					var glInternalFormat = getInternalFormat( glFormat, glType );
					var samples = getRenderTargetSamples( renderTarget );
					_gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );
994

995 996 997
					_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer );
					_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer );
					_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
998

999
					if ( renderTarget.depthBuffer ) {
1000

1001 1002 1003 1004 1005 1006 1007 1008 1009
						renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer();
						setupRenderBufferStorage( renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true );

					}

					_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );


				} else {
1010

1011 1012 1013
					console.warn( 'THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.' );

				}
1014

1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
			} else if ( isMultiview ) {

				if ( capabilities.multiview ) {

					var width = renderTarget.width;
					var height = renderTarget.height;
					var numViews = renderTarget.numViews;

					_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );

					var ext = extensions.get( 'OVR_multiview2' );

1027 1028
					info.memory.textures += 2;

1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
					var colorTexture = _gl.createTexture();
					_gl.bindTexture( _gl.TEXTURE_2D_ARRAY, colorTexture );
					_gl.texParameteri( _gl.TEXTURE_2D_ARRAY, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
					_gl.texParameteri( _gl.TEXTURE_2D_ARRAY, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
					_gl.texImage3D( _gl.TEXTURE_2D_ARRAY, 0, _gl.RGBA8, width, height, numViews, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, null );
					ext.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, colorTexture, 0, 0, numViews );

					var depthStencilTexture = _gl.createTexture();
					_gl.bindTexture( _gl.TEXTURE_2D_ARRAY, depthStencilTexture );
					_gl.texParameteri( _gl.TEXTURE_2D_ARRAY, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
					_gl.texParameteri( _gl.TEXTURE_2D_ARRAY, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
					_gl.texImage3D( _gl.TEXTURE_2D_ARRAY, 0, _gl.DEPTH24_STENCIL8, width, height, numViews, 0, _gl.DEPTH_STENCIL, _gl.UNSIGNED_INT_24_8, null );
					ext.framebufferTextureMultiviewOVR( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, depthStencilTexture, 0, 0, numViews );

					var viewFramebuffers = new Array( numViews );
1044
					for ( var i = 0; i < numViews; ++ i ) {
1045

1046 1047 1048
						viewFramebuffers[ i ] = _gl.createFramebuffer();
						_gl.bindFramebuffer( _gl.FRAMEBUFFER, viewFramebuffers[ i ] );
						_gl.framebufferTextureLayer( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, colorTexture, 0, i );
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058

					}

					renderTargetProperties.__webglColorTexture = colorTexture;
					renderTargetProperties.__webglDepthStencilTexture = depthStencilTexture;
					renderTargetProperties.__webglViewFramebuffers = viewFramebuffers;

					_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
					_gl.bindTexture( _gl.TEXTURE_2D_ARRAY, null );

1059
				} else {
1060

1061
					console.warn( 'THREE.WebGLRenderer: WebGLMultiviewRenderTarget can only be used with WebGL2 and Multiview extension support.' );
1062

1063
				}
1064

1065 1066
			}

1067 1068 1069 1070 1071 1072 1073
		}

		// Setup color buffer

		if ( isCube ) {

			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
1074
			setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, supportsMips );
1075 1076 1077 1078 1079 1080 1081

			for ( var i = 0; i < 6; i ++ ) {

				setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );

			}

1082
			if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) {
1083

1084
				generateMipmap( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, renderTarget.width, renderTarget.height );
1085 1086 1087

			}

1088 1089
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

1090
		} else if ( ! isMultiview ) {
1091 1092

			state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
1093
			setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, supportsMips );
1094 1095
			setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );

1096
			if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) {
1097

1098
				generateMipmap( _gl.TEXTURE_2D, renderTarget.texture, renderTarget.width, renderTarget.height );
1099 1100 1101

			}

1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
			state.bindTexture( _gl.TEXTURE_2D, null );

		}

		// Setup depth and stencil buffers

		if ( renderTarget.depthBuffer ) {

			setupDepthRenderbuffer( renderTarget );

		}

	}

	function updateRenderTargetMipmap( renderTarget ) {

		var texture = renderTarget.texture;
1119
		var supportsMips = isPowerOfTwo( renderTarget ) || capabilities.isWebGL2;
1120

1121
		if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
1122

1123
			var target = renderTarget.isWebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
1124 1125 1126
			var webglTexture = properties.get( texture ).__webglTexture;

			state.bindTexture( target, webglTexture );
1127
			generateMipmap( target, texture, renderTarget.width, renderTarget.height );
1128 1129 1130 1131 1132 1133
			state.bindTexture( target, null );

		}

	}

1134 1135 1136 1137
	function updateMultisampleRenderTarget( renderTarget ) {

		if ( renderTarget.isWebGLMultisampleRenderTarget ) {

1138 1139 1140 1141 1142 1143
			if ( capabilities.isWebGL2 ) {

				var renderTargetProperties = properties.get( renderTarget );

				_gl.bindFramebuffer( _gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer );
				_gl.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
1144

1145 1146 1147
				var width = renderTarget.width;
				var height = renderTarget.height;
				var mask = _gl.COLOR_BUFFER_BIT;
1148

1149 1150
				if ( renderTarget.depthBuffer ) mask |= _gl.DEPTH_BUFFER_BIT;
				if ( renderTarget.stencilBuffer ) mask |= _gl.STENCIL_BUFFER_BIT;
1151

1152
				_gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST );
1153

1154 1155 1156 1157 1158
			} else {

				console.warn( 'THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.' );

			}
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170

		}

	}

	function getRenderTargetSamples( renderTarget ) {

		return ( capabilities.isWebGL2 && renderTarget.isWebGLMultisampleRenderTarget ) ?
			Math.min( capabilities.maxSamples, renderTarget.samples ) : 0;

	}

1171 1172
	function updateVideoTexture( texture ) {

M
Mugen87 已提交
1173
		var frame = info.render.frame;
1174 1175

		// Check the last frame we updated the VideoTexture
M
Mugen87 已提交
1176

J
Joel 已提交
1177
		if ( _videoTextures.get( texture ) !== frame ) {
M
Mugen87 已提交
1178

J
Joel 已提交
1179
			_videoTextures.set( texture, frame );
1180
			texture.update();
M
Mugen87 已提交
1181 1182 1183 1184 1185

		}

	}

1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248
	// backwards compatibility

	var warnedTexture2D = false;
	var warnedTextureCube = false;

	function safeSetTexture2D( texture, slot ) {

		if ( texture && texture.isWebGLRenderTarget ) {

			if ( warnedTexture2D === false ) {

				console.warn( "THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead." );
				warnedTexture2D = true;

			}

			texture = texture.texture;

		}

		setTexture2D( texture, slot );

	}

	function safeSetTextureCube( texture, slot ) {

		if ( texture && texture.isWebGLRenderTargetCube ) {

			if ( warnedTextureCube === false ) {

				console.warn( "THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead." );
				warnedTextureCube = true;

			}

			texture = texture.texture;

		}

		// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture
		// TODO: unify these code paths
		if ( ( texture && texture.isCubeTexture ) ||
			( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {

			// CompressedTexture can have Array in image :/

			// this function alone should take care of cube textures
			setTextureCube( texture, slot );

		} else {

			// assumed: texture property of THREE.WebGLRenderTargetCube
			setTextureCubeDynamic( texture, slot );

		}

	}

	//

	this.allocateTextureUnit = allocateTextureUnit;
	this.resetTextureUnits = resetTextureUnits;

1249
	this.setTexture2D = setTexture2D;
T
Takahiro 已提交
1250
	this.setTexture2DArray = setTexture2DArray;
A
artur.trzesiok 已提交
1251
	this.setTexture3D = setTexture3D;
1252 1253 1254 1255
	this.setTextureCube = setTextureCube;
	this.setTextureCubeDynamic = setTextureCubeDynamic;
	this.setupRenderTarget = setupRenderTarget;
	this.updateRenderTargetMipmap = updateRenderTargetMipmap;
1256
	this.updateMultisampleRenderTarget = updateMultisampleRenderTarget;
1257

1258 1259
	this.safeSetTexture2D = safeSetTexture2D;
	this.safeSetTextureCube = safeSetTextureCube;
R
Rich Harris 已提交
1260

1261
}
R
Rich Harris 已提交
1262

1263
export { WebGLTextures };