添加关照、全局等高线、修改图层问题
This commit is contained in:
		
							
								
								
									
										258
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLAttributeUtils.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLAttributeUtils.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,258 @@
 | 
			
		||||
import { IntType } from 'three';
 | 
			
		||||
 | 
			
		||||
let _id = 0;
 | 
			
		||||
 | 
			
		||||
class DualAttributeData {
 | 
			
		||||
 | 
			
		||||
	constructor( attributeData, dualBuffer ) {
 | 
			
		||||
 | 
			
		||||
		this.buffers = [ attributeData.bufferGPU, dualBuffer ];
 | 
			
		||||
		this.type = attributeData.type;
 | 
			
		||||
		this.bufferType = attributeData.bufferType;
 | 
			
		||||
		this.pbo = attributeData.pbo;
 | 
			
		||||
		this.byteLength = attributeData.byteLength;
 | 
			
		||||
		this.bytesPerElement = attributeData.BYTES_PER_ELEMENT;
 | 
			
		||||
		this.version = attributeData.version;
 | 
			
		||||
		this.isInteger = attributeData.isInteger;
 | 
			
		||||
		this.activeBufferIndex = 0;
 | 
			
		||||
		this.baseId = attributeData.id;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	get id() {
 | 
			
		||||
 | 
			
		||||
		return `${ this.baseId }|${ this.activeBufferIndex }`;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	get bufferGPU() {
 | 
			
		||||
 | 
			
		||||
		return this.buffers[ this.activeBufferIndex ];
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	get transformBuffer() {
 | 
			
		||||
 | 
			
		||||
		return this.buffers[ this.activeBufferIndex ^ 1 ];
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switchBuffers() {
 | 
			
		||||
 | 
			
		||||
		this.activeBufferIndex ^= 1;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class WebGLAttributeUtils {
 | 
			
		||||
 | 
			
		||||
	constructor( backend ) {
 | 
			
		||||
 | 
			
		||||
		this.backend = backend;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	createAttribute( attribute, bufferType ) {
 | 
			
		||||
 | 
			
		||||
		const backend = this.backend;
 | 
			
		||||
		const { gl } = backend;
 | 
			
		||||
 | 
			
		||||
		const array = attribute.array;
 | 
			
		||||
		const usage = attribute.usage || gl.STATIC_DRAW;
 | 
			
		||||
 | 
			
		||||
		const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute;
 | 
			
		||||
		const bufferData = backend.get( bufferAttribute );
 | 
			
		||||
 | 
			
		||||
		let bufferGPU = bufferData.bufferGPU;
 | 
			
		||||
 | 
			
		||||
		if ( bufferGPU === undefined ) {
 | 
			
		||||
 | 
			
		||||
			bufferGPU = this._createBuffer( gl, bufferType, array, usage );
 | 
			
		||||
 | 
			
		||||
			bufferData.bufferGPU = bufferGPU;
 | 
			
		||||
			bufferData.bufferType = bufferType;
 | 
			
		||||
			bufferData.version = bufferAttribute.version;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//attribute.onUploadCallback();
 | 
			
		||||
 | 
			
		||||
		let type;
 | 
			
		||||
 | 
			
		||||
		if ( array instanceof Float32Array ) {
 | 
			
		||||
 | 
			
		||||
			type = gl.FLOAT;
 | 
			
		||||
 | 
			
		||||
		} else if ( array instanceof Uint16Array ) {
 | 
			
		||||
 | 
			
		||||
			if ( attribute.isFloat16BufferAttribute ) {
 | 
			
		||||
 | 
			
		||||
				type = gl.HALF_FLOAT;
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				type = gl.UNSIGNED_SHORT;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		} else if ( array instanceof Int16Array ) {
 | 
			
		||||
 | 
			
		||||
			type = gl.SHORT;
 | 
			
		||||
 | 
			
		||||
		} else if ( array instanceof Uint32Array ) {
 | 
			
		||||
 | 
			
		||||
			type = gl.UNSIGNED_INT;
 | 
			
		||||
 | 
			
		||||
		} else if ( array instanceof Int32Array ) {
 | 
			
		||||
 | 
			
		||||
			type = gl.INT;
 | 
			
		||||
 | 
			
		||||
		} else if ( array instanceof Int8Array ) {
 | 
			
		||||
 | 
			
		||||
			type = gl.BYTE;
 | 
			
		||||
 | 
			
		||||
		} else if ( array instanceof Uint8Array ) {
 | 
			
		||||
 | 
			
		||||
			type = gl.UNSIGNED_BYTE;
 | 
			
		||||
 | 
			
		||||
		} else if ( array instanceof Uint8ClampedArray ) {
 | 
			
		||||
 | 
			
		||||
			type = gl.UNSIGNED_BYTE;
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			throw new Error( 'THREE.WebGLBackend: Unsupported buffer data format: ' + array );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		let attributeData = {
 | 
			
		||||
			bufferGPU,
 | 
			
		||||
			bufferType,
 | 
			
		||||
			type,
 | 
			
		||||
			byteLength: array.byteLength,
 | 
			
		||||
			bytesPerElement: array.BYTES_PER_ELEMENT,
 | 
			
		||||
			version: attribute.version,
 | 
			
		||||
			pbo: attribute.pbo,
 | 
			
		||||
			isInteger: type === gl.INT || type === gl.UNSIGNED_INT || type === gl.UNSIGNED_SHORT || attribute.gpuType === IntType,
 | 
			
		||||
			id: _id ++
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		if ( attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute ) {
 | 
			
		||||
 | 
			
		||||
			// create buffer for tranform feedback use
 | 
			
		||||
			const bufferGPUDual = this._createBuffer( gl, bufferType, array, usage );
 | 
			
		||||
			attributeData = new DualAttributeData( attributeData, bufferGPUDual );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		backend.set( attribute, attributeData );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	updateAttribute( attribute ) {
 | 
			
		||||
 | 
			
		||||
		const backend = this.backend;
 | 
			
		||||
		const { gl } = backend;
 | 
			
		||||
 | 
			
		||||
		const array = attribute.array;
 | 
			
		||||
		const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute;
 | 
			
		||||
		const bufferData = backend.get( bufferAttribute );
 | 
			
		||||
		const bufferType = bufferData.bufferType;
 | 
			
		||||
		const updateRanges = attribute.isInterleavedBufferAttribute ? attribute.data.updateRanges : attribute.updateRanges;
 | 
			
		||||
 | 
			
		||||
		gl.bindBuffer( bufferType, bufferData.bufferGPU );
 | 
			
		||||
 | 
			
		||||
		if ( updateRanges.length === 0 ) {
 | 
			
		||||
 | 
			
		||||
			// Not using update ranges
 | 
			
		||||
 | 
			
		||||
			gl.bufferSubData( bufferType, 0, array );
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			for ( let i = 0, l = updateRanges.length; i < l; i ++ ) {
 | 
			
		||||
 | 
			
		||||
				const range = updateRanges[ i ];
 | 
			
		||||
				gl.bufferSubData( bufferType, range.start * array.BYTES_PER_ELEMENT,
 | 
			
		||||
					array, range.start, range.count );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bufferAttribute.clearUpdateRanges();
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		gl.bindBuffer( bufferType, null );
 | 
			
		||||
 | 
			
		||||
		bufferData.version = bufferAttribute.version;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	destroyAttribute( attribute ) {
 | 
			
		||||
 | 
			
		||||
		const backend = this.backend;
 | 
			
		||||
		const { gl } = backend;
 | 
			
		||||
 | 
			
		||||
		if ( attribute.isInterleavedBufferAttribute ) {
 | 
			
		||||
 | 
			
		||||
			backend.delete( attribute.data );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const attributeData = backend.get( attribute );
 | 
			
		||||
 | 
			
		||||
		gl.deleteBuffer( attributeData.bufferGPU );
 | 
			
		||||
 | 
			
		||||
		backend.delete( attribute );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	async getArrayBufferAsync( attribute ) {
 | 
			
		||||
 | 
			
		||||
		const backend = this.backend;
 | 
			
		||||
		const { gl } = backend;
 | 
			
		||||
 | 
			
		||||
		const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute;
 | 
			
		||||
		const { bufferGPU } = backend.get( bufferAttribute );
 | 
			
		||||
 | 
			
		||||
		const array = attribute.array;
 | 
			
		||||
		const byteLength = array.byteLength;
 | 
			
		||||
 | 
			
		||||
		gl.bindBuffer( gl.COPY_READ_BUFFER, bufferGPU );
 | 
			
		||||
 | 
			
		||||
		const writeBuffer = gl.createBuffer();
 | 
			
		||||
 | 
			
		||||
		gl.bindBuffer( gl.COPY_WRITE_BUFFER, writeBuffer );
 | 
			
		||||
		gl.bufferData( gl.COPY_WRITE_BUFFER, byteLength, gl.STREAM_READ );
 | 
			
		||||
 | 
			
		||||
		gl.copyBufferSubData( gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, byteLength );
 | 
			
		||||
 | 
			
		||||
		await backend.utils._clientWaitAsync();
 | 
			
		||||
 | 
			
		||||
		const dstBuffer = new attribute.array.constructor( array.length );
 | 
			
		||||
 | 
			
		||||
		gl.getBufferSubData( gl.COPY_WRITE_BUFFER, 0, dstBuffer );
 | 
			
		||||
 | 
			
		||||
		gl.deleteBuffer( writeBuffer );
 | 
			
		||||
 | 
			
		||||
		return dstBuffer.buffer;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_createBuffer( gl, bufferType, array, usage ) {
 | 
			
		||||
 | 
			
		||||
		const bufferGPU = gl.createBuffer();
 | 
			
		||||
 | 
			
		||||
		gl.bindBuffer( bufferType, bufferGPU );
 | 
			
		||||
		gl.bufferData( bufferType, array, usage );
 | 
			
		||||
		gl.bindBuffer( bufferType, null );
 | 
			
		||||
 | 
			
		||||
		return bufferGPU;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default WebGLAttributeUtils;
 | 
			
		||||
							
								
								
									
										36
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLCapabilities.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLCapabilities.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
			
		||||
class WebGLCapabilities {
 | 
			
		||||
 | 
			
		||||
	constructor( backend ) {
 | 
			
		||||
 | 
			
		||||
		this.backend = backend;
 | 
			
		||||
 | 
			
		||||
		this.maxAnisotropy = null;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	getMaxAnisotropy() {
 | 
			
		||||
 | 
			
		||||
		if ( this.maxAnisotropy !== null ) return this.maxAnisotropy;
 | 
			
		||||
 | 
			
		||||
		const gl = this.backend.gl;
 | 
			
		||||
		const extensions = this.backend.extensions;
 | 
			
		||||
 | 
			
		||||
		if ( extensions.has( 'EXT_texture_filter_anisotropic' ) === true ) {
 | 
			
		||||
 | 
			
		||||
			const extension = extensions.get( 'EXT_texture_filter_anisotropic' );
 | 
			
		||||
 | 
			
		||||
			this.maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			this.maxAnisotropy = 0;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return this.maxAnisotropy;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default WebGLCapabilities;
 | 
			
		||||
							
								
								
									
										12
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLConstants.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLConstants.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
export const GLFeatureName = {
 | 
			
		||||
 | 
			
		||||
	'WEBGL_compressed_texture_astc': 'texture-compression-astc',
 | 
			
		||||
	'WEBGL_compressed_texture_etc': 'texture-compression-etc2',
 | 
			
		||||
	'WEBGL_compressed_texture_etc1': 'texture-compression-etc1',
 | 
			
		||||
	'WEBGL_compressed_texture_pvrtc': 'texture-compression-pvrtc',
 | 
			
		||||
	'WEBKIT_WEBGL_compressed_texture_pvrtc': 'texture-compression-pvrtc',
 | 
			
		||||
	'WEBGL_compressed_texture_s3tc': 'texture-compression-bc',
 | 
			
		||||
	'EXT_texture_compression_bptc': 'texture-compression-bptc',
 | 
			
		||||
	'EXT_disjoint_timer_query_webgl2': 'timestamp-query',
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										36
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLExtensions.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLExtensions.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
			
		||||
class WebGLExtensions {
 | 
			
		||||
 | 
			
		||||
	constructor( backend ) {
 | 
			
		||||
 | 
			
		||||
		this.backend = backend;
 | 
			
		||||
 | 
			
		||||
		this.gl = this.backend.gl;
 | 
			
		||||
		this.availableExtensions = this.gl.getSupportedExtensions();
 | 
			
		||||
 | 
			
		||||
		this.extensions = {};
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	get( name ) {
 | 
			
		||||
 | 
			
		||||
		let extension = this.extensions[ name ];
 | 
			
		||||
 | 
			
		||||
		if ( extension === undefined ) {
 | 
			
		||||
 | 
			
		||||
			extension = this.gl.getExtension( name );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return extension;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	has( name ) {
 | 
			
		||||
 | 
			
		||||
		return this.availableExtensions.includes( name );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default WebGLExtensions;
 | 
			
		||||
							
								
								
									
										738
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLState.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										738
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLState.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,738 @@
 | 
			
		||||
import {
 | 
			
		||||
	CullFaceNone, CullFaceBack, CullFaceFront, DoubleSide, BackSide,
 | 
			
		||||
	NormalBlending, NoBlending, CustomBlending, AddEquation,
 | 
			
		||||
	AdditiveBlending, SubtractiveBlending, MultiplyBlending, SubtractEquation, ReverseSubtractEquation,
 | 
			
		||||
	ZeroFactor, OneFactor, SrcColorFactor, SrcAlphaFactor, SrcAlphaSaturateFactor, DstColorFactor, DstAlphaFactor,
 | 
			
		||||
	OneMinusSrcColorFactor, OneMinusSrcAlphaFactor, OneMinusDstColorFactor, OneMinusDstAlphaFactor,
 | 
			
		||||
	NeverDepth, AlwaysDepth, LessDepth, LessEqualDepth, EqualDepth, GreaterEqualDepth, GreaterDepth, NotEqualDepth
 | 
			
		||||
} from 'three';
 | 
			
		||||
 | 
			
		||||
let initialized = false, equationToGL, factorToGL;
 | 
			
		||||
 | 
			
		||||
class WebGLState {
 | 
			
		||||
 | 
			
		||||
	constructor( backend ) {
 | 
			
		||||
 | 
			
		||||
		this.backend = backend;
 | 
			
		||||
 | 
			
		||||
		this.gl = this.backend.gl;
 | 
			
		||||
 | 
			
		||||
		this.enabled = {};
 | 
			
		||||
		this.currentFlipSided = null;
 | 
			
		||||
		this.currentCullFace = null;
 | 
			
		||||
		this.currentProgram = null;
 | 
			
		||||
		this.currentBlendingEnabled = false;
 | 
			
		||||
		this.currentBlending = null;
 | 
			
		||||
		this.currentBlendSrc = null;
 | 
			
		||||
		this.currentBlendDst = null;
 | 
			
		||||
		this.currentBlendSrcAlpha = null;
 | 
			
		||||
		this.currentBlendDstAlpha = null;
 | 
			
		||||
		this.currentPremultipledAlpha = null;
 | 
			
		||||
		this.currentPolygonOffsetFactor = null;
 | 
			
		||||
		this.currentPolygonOffsetUnits = null;
 | 
			
		||||
		this.currentColorMask = null;
 | 
			
		||||
		this.currentDepthFunc = null;
 | 
			
		||||
		this.currentDepthMask = null;
 | 
			
		||||
		this.currentStencilFunc = null;
 | 
			
		||||
		this.currentStencilRef = null;
 | 
			
		||||
		this.currentStencilFuncMask = null;
 | 
			
		||||
		this.currentStencilFail = null;
 | 
			
		||||
		this.currentStencilZFail = null;
 | 
			
		||||
		this.currentStencilZPass = null;
 | 
			
		||||
		this.currentStencilMask = null;
 | 
			
		||||
		this.currentLineWidth = null;
 | 
			
		||||
 | 
			
		||||
		this.currentBoundFramebuffers = {};
 | 
			
		||||
		this.currentDrawbuffers = new WeakMap();
 | 
			
		||||
 | 
			
		||||
		this.maxTextures = this.gl.getParameter( this.gl.MAX_TEXTURE_IMAGE_UNITS );
 | 
			
		||||
		this.currentTextureSlot = null;
 | 
			
		||||
		this.currentBoundTextures = {};
 | 
			
		||||
 | 
			
		||||
		if ( initialized === false ) {
 | 
			
		||||
 | 
			
		||||
			this._init( this.gl );
 | 
			
		||||
 | 
			
		||||
			initialized = true;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_init( gl ) {
 | 
			
		||||
 | 
			
		||||
		// Store only WebGL constants here.
 | 
			
		||||
 | 
			
		||||
		equationToGL = {
 | 
			
		||||
			[ AddEquation ]: gl.FUNC_ADD,
 | 
			
		||||
			[ SubtractEquation ]: gl.FUNC_SUBTRACT,
 | 
			
		||||
			[ ReverseSubtractEquation ]: gl.FUNC_REVERSE_SUBTRACT
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		factorToGL = {
 | 
			
		||||
			[ ZeroFactor ]: gl.ZERO,
 | 
			
		||||
			[ OneFactor ]: gl.ONE,
 | 
			
		||||
			[ SrcColorFactor ]: gl.SRC_COLOR,
 | 
			
		||||
			[ SrcAlphaFactor ]: gl.SRC_ALPHA,
 | 
			
		||||
			[ SrcAlphaSaturateFactor ]: gl.SRC_ALPHA_SATURATE,
 | 
			
		||||
			[ DstColorFactor ]: gl.DST_COLOR,
 | 
			
		||||
			[ DstAlphaFactor ]: gl.DST_ALPHA,
 | 
			
		||||
			[ OneMinusSrcColorFactor ]: gl.ONE_MINUS_SRC_COLOR,
 | 
			
		||||
			[ OneMinusSrcAlphaFactor ]: gl.ONE_MINUS_SRC_ALPHA,
 | 
			
		||||
			[ OneMinusDstColorFactor ]: gl.ONE_MINUS_DST_COLOR,
 | 
			
		||||
			[ OneMinusDstAlphaFactor ]: gl.ONE_MINUS_DST_ALPHA
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	enable( id ) {
 | 
			
		||||
 | 
			
		||||
		const { enabled } = this;
 | 
			
		||||
 | 
			
		||||
		if ( enabled[ id ] !== true ) {
 | 
			
		||||
 | 
			
		||||
			this.gl.enable( id );
 | 
			
		||||
			enabled[ id ] = true;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	disable( id ) {
 | 
			
		||||
 | 
			
		||||
		const { enabled } = this;
 | 
			
		||||
 | 
			
		||||
		if ( enabled[ id ] !== false ) {
 | 
			
		||||
 | 
			
		||||
			this.gl.disable( id );
 | 
			
		||||
			enabled[ id ] = false;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setFlipSided( flipSided ) {
 | 
			
		||||
 | 
			
		||||
		if ( this.currentFlipSided !== flipSided ) {
 | 
			
		||||
 | 
			
		||||
			const { gl } = this;
 | 
			
		||||
 | 
			
		||||
			if ( flipSided ) {
 | 
			
		||||
 | 
			
		||||
				gl.frontFace( gl.CW );
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				gl.frontFace( gl.CCW );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			this.currentFlipSided = flipSided;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setCullFace( cullFace ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		if ( cullFace !== CullFaceNone ) {
 | 
			
		||||
 | 
			
		||||
			this.enable( gl.CULL_FACE );
 | 
			
		||||
 | 
			
		||||
			if ( cullFace !== this.currentCullFace ) {
 | 
			
		||||
 | 
			
		||||
				if ( cullFace === CullFaceBack ) {
 | 
			
		||||
 | 
			
		||||
					gl.cullFace( gl.BACK );
 | 
			
		||||
 | 
			
		||||
				} else if ( cullFace === CullFaceFront ) {
 | 
			
		||||
 | 
			
		||||
					gl.cullFace( gl.FRONT );
 | 
			
		||||
 | 
			
		||||
				} else {
 | 
			
		||||
 | 
			
		||||
					gl.cullFace( gl.FRONT_AND_BACK );
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			this.disable( gl.CULL_FACE );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.currentCullFace = cullFace;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setLineWidth( width ) {
 | 
			
		||||
 | 
			
		||||
		const { currentLineWidth, gl } = this;
 | 
			
		||||
 | 
			
		||||
		if ( width !== currentLineWidth ) {
 | 
			
		||||
 | 
			
		||||
			gl.lineWidth( width );
 | 
			
		||||
 | 
			
		||||
			this.currentLineWidth = width;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		if ( blending === NoBlending ) {
 | 
			
		||||
 | 
			
		||||
			if ( this.currentBlendingEnabled === true ) {
 | 
			
		||||
 | 
			
		||||
				this.disable( gl.BLEND );
 | 
			
		||||
				this.currentBlendingEnabled = false;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( this.currentBlendingEnabled === false ) {
 | 
			
		||||
 | 
			
		||||
			this.enable( gl.BLEND );
 | 
			
		||||
			this.currentBlendingEnabled = true;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( blending !== CustomBlending ) {
 | 
			
		||||
 | 
			
		||||
			if ( blending !== this.currentBlending || premultipliedAlpha !== this.currentPremultipledAlpha ) {
 | 
			
		||||
 | 
			
		||||
				if ( this.currentBlendEquation !== AddEquation || this.currentBlendEquationAlpha !== AddEquation ) {
 | 
			
		||||
 | 
			
		||||
					gl.blendEquation( gl.FUNC_ADD );
 | 
			
		||||
 | 
			
		||||
					this.currentBlendEquation = AddEquation;
 | 
			
		||||
					this.currentBlendEquationAlpha = AddEquation;
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if ( premultipliedAlpha ) {
 | 
			
		||||
 | 
			
		||||
					switch ( blending ) {
 | 
			
		||||
 | 
			
		||||
						case NormalBlending:
 | 
			
		||||
							gl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						case AdditiveBlending:
 | 
			
		||||
							gl.blendFunc( gl.ONE, gl.ONE );
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						case SubtractiveBlending:
 | 
			
		||||
							gl.blendFuncSeparate( gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE );
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						case MultiplyBlending:
 | 
			
		||||
							gl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						default:
 | 
			
		||||
							console.error( 'THREE.WebGLState: Invalid blending: ', blending );
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
				} else {
 | 
			
		||||
 | 
			
		||||
					switch ( blending ) {
 | 
			
		||||
 | 
			
		||||
						case NormalBlending:
 | 
			
		||||
							gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						case AdditiveBlending:
 | 
			
		||||
							gl.blendFunc( gl.SRC_ALPHA, gl.ONE );
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						case SubtractiveBlending:
 | 
			
		||||
							gl.blendFuncSeparate( gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE );
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						case MultiplyBlending:
 | 
			
		||||
							gl.blendFunc( gl.ZERO, gl.SRC_COLOR );
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						default:
 | 
			
		||||
							console.error( 'THREE.WebGLState: Invalid blending: ', blending );
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				this.currentBlendSrc = null;
 | 
			
		||||
				this.currentBlendDst = null;
 | 
			
		||||
				this.currentBlendSrcAlpha = null;
 | 
			
		||||
				this.currentBlendDstAlpha = null;
 | 
			
		||||
 | 
			
		||||
				this.currentBlending = blending;
 | 
			
		||||
				this.currentPremultipledAlpha = premultipliedAlpha;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// custom blending
 | 
			
		||||
 | 
			
		||||
		blendEquationAlpha = blendEquationAlpha || blendEquation;
 | 
			
		||||
		blendSrcAlpha = blendSrcAlpha || blendSrc;
 | 
			
		||||
		blendDstAlpha = blendDstAlpha || blendDst;
 | 
			
		||||
 | 
			
		||||
		if ( blendEquation !== this.currentBlendEquation || blendEquationAlpha !== this.currentBlendEquationAlpha ) {
 | 
			
		||||
 | 
			
		||||
			gl.blendEquationSeparate( equationToGL[ blendEquation ], equationToGL[ blendEquationAlpha ] );
 | 
			
		||||
 | 
			
		||||
			this.currentBlendEquation = blendEquation;
 | 
			
		||||
			this.currentBlendEquationAlpha = blendEquationAlpha;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( blendSrc !== this.currentBlendSrc || blendDst !== this.currentBlendDst || blendSrcAlpha !== this.currentBlendSrcAlpha || blendDstAlpha !== this.currentBlendDstAlpha ) {
 | 
			
		||||
 | 
			
		||||
			gl.blendFuncSeparate( factorToGL[ blendSrc ], factorToGL[ blendDst ], factorToGL[ blendSrcAlpha ], factorToGL[ blendDstAlpha ] );
 | 
			
		||||
 | 
			
		||||
			this.currentBlendSrc = blendSrc;
 | 
			
		||||
			this.currentBlendDst = blendDst;
 | 
			
		||||
			this.currentBlendSrcAlpha = blendSrcAlpha;
 | 
			
		||||
			this.currentBlendDstAlpha = blendDstAlpha;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.currentBlending = blending;
 | 
			
		||||
		this.currentPremultipledAlpha = false;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setColorMask( colorMask ) {
 | 
			
		||||
 | 
			
		||||
		if ( this.currentColorMask !== colorMask ) {
 | 
			
		||||
 | 
			
		||||
			this.gl.colorMask( colorMask, colorMask, colorMask, colorMask );
 | 
			
		||||
			this.currentColorMask = colorMask;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setDepthTest( depthTest ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		if ( depthTest ) {
 | 
			
		||||
 | 
			
		||||
			this.enable( gl.DEPTH_TEST );
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			this.disable( gl.DEPTH_TEST );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setDepthMask( depthMask ) {
 | 
			
		||||
 | 
			
		||||
		if ( this.currentDepthMask !== depthMask ) {
 | 
			
		||||
 | 
			
		||||
			this.gl.depthMask( depthMask );
 | 
			
		||||
			this.currentDepthMask = depthMask;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setDepthFunc( depthFunc ) {
 | 
			
		||||
 | 
			
		||||
		if ( this.currentDepthFunc !== depthFunc ) {
 | 
			
		||||
 | 
			
		||||
			const { gl } = this;
 | 
			
		||||
 | 
			
		||||
			switch ( depthFunc ) {
 | 
			
		||||
 | 
			
		||||
				case NeverDepth:
 | 
			
		||||
 | 
			
		||||
					gl.depthFunc( gl.NEVER );
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case AlwaysDepth:
 | 
			
		||||
 | 
			
		||||
					gl.depthFunc( gl.ALWAYS );
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case LessDepth:
 | 
			
		||||
 | 
			
		||||
					gl.depthFunc( gl.LESS );
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case LessEqualDepth:
 | 
			
		||||
 | 
			
		||||
					gl.depthFunc( gl.LEQUAL );
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case EqualDepth:
 | 
			
		||||
 | 
			
		||||
					gl.depthFunc( gl.EQUAL );
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case GreaterEqualDepth:
 | 
			
		||||
 | 
			
		||||
					gl.depthFunc( gl.GEQUAL );
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case GreaterDepth:
 | 
			
		||||
 | 
			
		||||
					gl.depthFunc( gl.GREATER );
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case NotEqualDepth:
 | 
			
		||||
 | 
			
		||||
					gl.depthFunc( gl.NOTEQUAL );
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				default:
 | 
			
		||||
 | 
			
		||||
					gl.depthFunc( gl.LEQUAL );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			this.currentDepthFunc = depthFunc;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setStencilTest( stencilTest ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		if ( stencilTest ) {
 | 
			
		||||
 | 
			
		||||
			this.enable( gl.STENCIL_TEST );
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			this.disable( gl.STENCIL_TEST );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setStencilMask( stencilMask ) {
 | 
			
		||||
 | 
			
		||||
		if ( this.currentStencilMask !== stencilMask ) {
 | 
			
		||||
 | 
			
		||||
			this.gl.stencilMask( stencilMask );
 | 
			
		||||
			this.currentStencilMask = stencilMask;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setStencilFunc( stencilFunc, stencilRef, stencilMask ) {
 | 
			
		||||
 | 
			
		||||
		if ( this.currentStencilFunc !== stencilFunc ||
 | 
			
		||||
			 this.currentStencilRef !== stencilRef ||
 | 
			
		||||
			 this.currentStencilFuncMask !== stencilMask ) {
 | 
			
		||||
 | 
			
		||||
			this.gl.stencilFunc( stencilFunc, stencilRef, stencilMask );
 | 
			
		||||
 | 
			
		||||
			this.currentStencilFunc = stencilFunc;
 | 
			
		||||
			this.currentStencilRef = stencilRef;
 | 
			
		||||
			this.currentStencilFuncMask = stencilMask;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setStencilOp( stencilFail, stencilZFail, stencilZPass ) {
 | 
			
		||||
 | 
			
		||||
		if ( this.currentStencilFail !== stencilFail ||
 | 
			
		||||
			 this.currentStencilZFail !== stencilZFail ||
 | 
			
		||||
			 this.currentStencilZPass !== stencilZPass ) {
 | 
			
		||||
 | 
			
		||||
			this.gl.stencilOp( stencilFail, stencilZFail, stencilZPass );
 | 
			
		||||
 | 
			
		||||
			this.currentStencilFail = stencilFail;
 | 
			
		||||
			this.currentStencilZFail = stencilZFail;
 | 
			
		||||
			this.currentStencilZPass = stencilZPass;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setMaterial( material, frontFaceCW ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		material.side === DoubleSide
 | 
			
		||||
			? this.disable( gl.CULL_FACE )
 | 
			
		||||
			: this.enable( gl.CULL_FACE );
 | 
			
		||||
 | 
			
		||||
		let flipSided = ( material.side === BackSide );
 | 
			
		||||
		if ( frontFaceCW ) flipSided = ! flipSided;
 | 
			
		||||
 | 
			
		||||
		this.setFlipSided( flipSided );
 | 
			
		||||
 | 
			
		||||
		( material.blending === NormalBlending && material.transparent === false )
 | 
			
		||||
			? this.setBlending( NoBlending )
 | 
			
		||||
			: this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha );
 | 
			
		||||
 | 
			
		||||
		this.setDepthFunc( material.depthFunc );
 | 
			
		||||
		this.setDepthTest( material.depthTest );
 | 
			
		||||
		this.setDepthMask( material.depthWrite );
 | 
			
		||||
		this.setColorMask( material.colorWrite );
 | 
			
		||||
 | 
			
		||||
		const stencilWrite = material.stencilWrite;
 | 
			
		||||
		this.setStencilTest( stencilWrite );
 | 
			
		||||
		if ( stencilWrite ) {
 | 
			
		||||
 | 
			
		||||
			this.setStencilMask( material.stencilWriteMask );
 | 
			
		||||
			this.setStencilFunc( material.stencilFunc, material.stencilRef, material.stencilFuncMask );
 | 
			
		||||
			this.setStencilOp( material.stencilFail, material.stencilZFail, material.stencilZPass );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
 | 
			
		||||
 | 
			
		||||
		material.alphaToCoverage === true
 | 
			
		||||
			? this.enable( gl.SAMPLE_ALPHA_TO_COVERAGE )
 | 
			
		||||
			: this.disable( gl.SAMPLE_ALPHA_TO_COVERAGE );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setPolygonOffset( polygonOffset, factor, units ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		if ( polygonOffset ) {
 | 
			
		||||
 | 
			
		||||
			this.enable( gl.POLYGON_OFFSET_FILL );
 | 
			
		||||
 | 
			
		||||
			if ( this.currentPolygonOffsetFactor !== factor || this.currentPolygonOffsetUnits !== units ) {
 | 
			
		||||
 | 
			
		||||
				gl.polygonOffset( factor, units );
 | 
			
		||||
 | 
			
		||||
				this.currentPolygonOffsetFactor = factor;
 | 
			
		||||
				this.currentPolygonOffsetUnits = units;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			this.disable( gl.POLYGON_OFFSET_FILL );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	useProgram( program ) {
 | 
			
		||||
 | 
			
		||||
		if ( this.currentProgram !== program ) {
 | 
			
		||||
 | 
			
		||||
			this.gl.useProgram( program );
 | 
			
		||||
 | 
			
		||||
			this.currentProgram = program;
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// framebuffer
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	bindFramebuffer( target, framebuffer ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, currentBoundFramebuffers } = this;
 | 
			
		||||
 | 
			
		||||
		if ( currentBoundFramebuffers[ target ] !== framebuffer ) {
 | 
			
		||||
 | 
			
		||||
			gl.bindFramebuffer( target, framebuffer );
 | 
			
		||||
 | 
			
		||||
			currentBoundFramebuffers[ target ] = framebuffer;
 | 
			
		||||
 | 
			
		||||
			// gl.DRAW_FRAMEBUFFER is equivalent to gl.FRAMEBUFFER
 | 
			
		||||
 | 
			
		||||
			if ( target === gl.DRAW_FRAMEBUFFER ) {
 | 
			
		||||
 | 
			
		||||
				currentBoundFramebuffers[ gl.FRAMEBUFFER ] = framebuffer;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if ( target === gl.FRAMEBUFFER ) {
 | 
			
		||||
 | 
			
		||||
				currentBoundFramebuffers[ gl.DRAW_FRAMEBUFFER ] = framebuffer;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	drawBuffers( renderContext, framebuffer ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		let drawBuffers = [];
 | 
			
		||||
 | 
			
		||||
		let needsUpdate = false;
 | 
			
		||||
 | 
			
		||||
		if ( renderContext.textures !== null ) {
 | 
			
		||||
 | 
			
		||||
			drawBuffers = this.currentDrawbuffers.get( framebuffer );
 | 
			
		||||
 | 
			
		||||
			if ( drawBuffers === undefined ) {
 | 
			
		||||
 | 
			
		||||
				drawBuffers = [];
 | 
			
		||||
				this.currentDrawbuffers.set( framebuffer, drawBuffers );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			const textures = renderContext.textures;
 | 
			
		||||
 | 
			
		||||
			if ( drawBuffers.length !== textures.length || drawBuffers[ 0 ] !== gl.COLOR_ATTACHMENT0 ) {
 | 
			
		||||
 | 
			
		||||
				for ( let i = 0, il = textures.length; i < il; i ++ ) {
 | 
			
		||||
 | 
			
		||||
					drawBuffers[ i ] = gl.COLOR_ATTACHMENT0 + i;
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				drawBuffers.length = textures.length;
 | 
			
		||||
 | 
			
		||||
				needsUpdate = true;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			if ( drawBuffers[ 0 ] !== gl.BACK ) {
 | 
			
		||||
 | 
			
		||||
				drawBuffers[ 0 ] = gl.BACK;
 | 
			
		||||
 | 
			
		||||
				needsUpdate = true;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( needsUpdate ) {
 | 
			
		||||
 | 
			
		||||
			gl.drawBuffers( drawBuffers );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// texture
 | 
			
		||||
 | 
			
		||||
	activeTexture( webglSlot ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, currentTextureSlot, maxTextures } = this;
 | 
			
		||||
 | 
			
		||||
		if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;
 | 
			
		||||
 | 
			
		||||
		if ( currentTextureSlot !== webglSlot ) {
 | 
			
		||||
 | 
			
		||||
			gl.activeTexture( webglSlot );
 | 
			
		||||
			this.currentTextureSlot = webglSlot;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bindTexture( webglType, webglTexture, webglSlot ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, currentTextureSlot, currentBoundTextures, maxTextures } = this;
 | 
			
		||||
 | 
			
		||||
		if ( webglSlot === undefined ) {
 | 
			
		||||
 | 
			
		||||
			if ( currentTextureSlot === null ) {
 | 
			
		||||
 | 
			
		||||
				webglSlot = gl.TEXTURE0 + maxTextures - 1;
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				webglSlot = currentTextureSlot;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		let boundTexture = currentBoundTextures[ webglSlot ];
 | 
			
		||||
 | 
			
		||||
		if ( boundTexture === undefined ) {
 | 
			
		||||
 | 
			
		||||
			boundTexture = { type: undefined, texture: undefined };
 | 
			
		||||
			currentBoundTextures[ webglSlot ] = boundTexture;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {
 | 
			
		||||
 | 
			
		||||
			if ( currentTextureSlot !== webglSlot ) {
 | 
			
		||||
 | 
			
		||||
				gl.activeTexture( webglSlot );
 | 
			
		||||
				this.currentTextureSlot = webglSlot;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			gl.bindTexture( webglType, webglTexture );
 | 
			
		||||
 | 
			
		||||
			boundTexture.type = webglType;
 | 
			
		||||
			boundTexture.texture = webglTexture;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	unbindTexture() {
 | 
			
		||||
 | 
			
		||||
		const { gl, currentTextureSlot, currentBoundTextures } = this;
 | 
			
		||||
 | 
			
		||||
		const boundTexture = currentBoundTextures[ currentTextureSlot ];
 | 
			
		||||
 | 
			
		||||
		if ( boundTexture !== undefined && boundTexture.type !== undefined ) {
 | 
			
		||||
 | 
			
		||||
			gl.bindTexture( boundTexture.type, null );
 | 
			
		||||
 | 
			
		||||
			boundTexture.type = undefined;
 | 
			
		||||
			boundTexture.texture = undefined;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default WebGLState;
 | 
			
		||||
							
								
								
									
										751
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLTextureUtils.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										751
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLTextureUtils.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,751 @@
 | 
			
		||||
import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, FloatType, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, SRGBColorSpace, NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare } from 'three';
 | 
			
		||||
 | 
			
		||||
let initialized = false, wrappingToGL, filterToGL, compareToGL;
 | 
			
		||||
 | 
			
		||||
class WebGLTextureUtils {
 | 
			
		||||
 | 
			
		||||
	constructor( backend ) {
 | 
			
		||||
 | 
			
		||||
		this.backend = backend;
 | 
			
		||||
 | 
			
		||||
		this.gl = backend.gl;
 | 
			
		||||
		this.extensions = backend.extensions;
 | 
			
		||||
		this.defaultTextures = {};
 | 
			
		||||
 | 
			
		||||
		if ( initialized === false ) {
 | 
			
		||||
 | 
			
		||||
			this._init( this.gl );
 | 
			
		||||
 | 
			
		||||
			initialized = true;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_init( gl ) {
 | 
			
		||||
 | 
			
		||||
		// Store only WebGL constants here.
 | 
			
		||||
 | 
			
		||||
		wrappingToGL = {
 | 
			
		||||
			[ RepeatWrapping ]: gl.REPEAT,
 | 
			
		||||
			[ ClampToEdgeWrapping ]: gl.CLAMP_TO_EDGE,
 | 
			
		||||
			[ MirroredRepeatWrapping ]: gl.MIRRORED_REPEAT
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		filterToGL = {
 | 
			
		||||
			[ NearestFilter ]: gl.NEAREST,
 | 
			
		||||
			[ NearestMipmapNearestFilter ]: gl.NEAREST_MIPMAP_NEAREST,
 | 
			
		||||
			[ NearestMipmapLinearFilter ]: gl.NEAREST_MIPMAP_LINEAR,
 | 
			
		||||
 | 
			
		||||
			[ LinearFilter ]: gl.LINEAR,
 | 
			
		||||
			[ LinearMipmapNearestFilter ]: gl.LINEAR_MIPMAP_NEAREST,
 | 
			
		||||
			[ LinearMipmapLinearFilter ]: gl.LINEAR_MIPMAP_LINEAR
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		compareToGL = {
 | 
			
		||||
			[ NeverCompare ]: gl.NEVER,
 | 
			
		||||
			[ AlwaysCompare ]: gl.ALWAYS,
 | 
			
		||||
			[ LessCompare ]: gl.LESS,
 | 
			
		||||
			[ LessEqualCompare ]: gl.LEQUAL,
 | 
			
		||||
			[ EqualCompare ]: gl.EQUAL,
 | 
			
		||||
			[ GreaterEqualCompare ]: gl.GEQUAL,
 | 
			
		||||
			[ GreaterCompare ]: gl.GREATER,
 | 
			
		||||
			[ NotEqualCompare ]: gl.NOTEQUAL
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	filterFallback( f ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		if ( f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter ) {
 | 
			
		||||
 | 
			
		||||
			return gl.NEAREST;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return gl.LINEAR;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	getGLTextureType( texture ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		let glTextureType;
 | 
			
		||||
 | 
			
		||||
		if ( texture.isCubeTexture === true ) {
 | 
			
		||||
 | 
			
		||||
			glTextureType = gl.TEXTURE_CUBE_MAP;
 | 
			
		||||
 | 
			
		||||
		} else if ( texture.isDataArrayTexture === true ) {
 | 
			
		||||
 | 
			
		||||
			glTextureType = gl.TEXTURE_2D_ARRAY;
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			glTextureType = gl.TEXTURE_2D;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return glTextureType;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	getInternalFormat( internalFormatName, glFormat, glType, colorSpace, forceLinearTransfer = false ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, extensions } = this;
 | 
			
		||||
 | 
			
		||||
		if ( internalFormatName !== null ) {
 | 
			
		||||
 | 
			
		||||
			if ( gl[ internalFormatName ] !== undefined ) return gl[ internalFormatName ];
 | 
			
		||||
 | 
			
		||||
			console.warn( 'THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'' );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		let internalFormat = glFormat;
 | 
			
		||||
 | 
			
		||||
		if ( glFormat === gl.RED ) {
 | 
			
		||||
 | 
			
		||||
			if ( glType === gl.FLOAT ) internalFormat = gl.R32F;
 | 
			
		||||
			if ( glType === gl.HALF_FLOAT ) internalFormat = gl.R16F;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_BYTE ) internalFormat = gl.R8;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( glFormat === gl.RED_INTEGER ) {
 | 
			
		||||
 | 
			
		||||
			if ( glType === gl.UNSIGNED_BYTE ) internalFormat = gl.R8UI;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_SHORT ) internalFormat = gl.R16UI;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.R32UI;
 | 
			
		||||
			if ( glType === gl.BYTE ) internalFormat = gl.R8I;
 | 
			
		||||
			if ( glType === gl.SHORT ) internalFormat = gl.R16I;
 | 
			
		||||
			if ( glType === gl.INT ) internalFormat = gl.R32I;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( glFormat === gl.RG ) {
 | 
			
		||||
 | 
			
		||||
			if ( glType === gl.FLOAT ) internalFormat = gl.RG32F;
 | 
			
		||||
			if ( glType === gl.HALF_FLOAT ) internalFormat = gl.RG16F;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_BYTE ) internalFormat = gl.RG8;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( glFormat === gl.RGB ) {
 | 
			
		||||
 | 
			
		||||
			if ( glType === gl.FLOAT ) internalFormat = gl.RGB32F;
 | 
			
		||||
			if ( glType === gl.HALF_FLOAT ) internalFormat = gl.RGB16F;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_BYTE ) internalFormat = gl.RGB8;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_SHORT_5_6_5 ) internalFormat = gl.RGB565;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_SHORT_5_5_5_1 ) internalFormat = gl.RGB5_A1;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_SHORT_4_4_4_4 ) internalFormat = gl.RGB4;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_INT_5_9_9_9_REV ) internalFormat = gl.RGB9_E5;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( glFormat === gl.RGBA ) {
 | 
			
		||||
 | 
			
		||||
			if ( glType === gl.FLOAT ) internalFormat = gl.RGBA32F;
 | 
			
		||||
			if ( glType === gl.HALF_FLOAT ) internalFormat = gl.RGBA16F;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_BYTE ) internalFormat = ( colorSpace === SRGBColorSpace && forceLinearTransfer === false ) ? gl.SRGB8_ALPHA8 : gl.RGBA8;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_SHORT_4_4_4_4 ) internalFormat = gl.RGBA4;
 | 
			
		||||
			if ( glType === gl.UNSIGNED_SHORT_5_5_5_1 ) internalFormat = gl.RGB5_A1;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( glFormat === gl.DEPTH_COMPONENT ) {
 | 
			
		||||
 | 
			
		||||
			if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.DEPTH24_STENCIL8;
 | 
			
		||||
			if ( glType === gl.FLOAT ) internalFormat = gl.DEPTH_COMPONENT32F;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( glFormat === gl.DEPTH_STENCIL ) {
 | 
			
		||||
 | 
			
		||||
			if ( glType === gl.UNSIGNED_INT_24_8 ) internalFormat = gl.DEPTH24_STENCIL8;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( internalFormat === gl.R16F || internalFormat === gl.R32F ||
 | 
			
		||||
			internalFormat === gl.RG16F || internalFormat === gl.RG32F ||
 | 
			
		||||
			internalFormat === gl.RGBA16F || internalFormat === gl.RGBA32F ) {
 | 
			
		||||
 | 
			
		||||
			extensions.get( 'EXT_color_buffer_float' );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return internalFormat;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setTextureParameters( textureType, texture ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, extensions, backend } = this;
 | 
			
		||||
 | 
			
		||||
		const { currentAnisotropy } = backend.get( texture );
 | 
			
		||||
 | 
			
		||||
		gl.texParameteri( textureType, gl.TEXTURE_WRAP_S, wrappingToGL[ texture.wrapS ] );
 | 
			
		||||
		gl.texParameteri( textureType, gl.TEXTURE_WRAP_T, wrappingToGL[ texture.wrapT ] );
 | 
			
		||||
 | 
			
		||||
		if ( textureType === gl.TEXTURE_3D || textureType === gl.TEXTURE_2D_ARRAY ) {
 | 
			
		||||
 | 
			
		||||
			gl.texParameteri( textureType, gl.TEXTURE_WRAP_R, wrappingToGL[ texture.wrapR ] );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		gl.texParameteri( textureType, gl.TEXTURE_MAG_FILTER, filterToGL[ texture.magFilter ] );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		// follow WebGPU backend mapping for texture filtering
 | 
			
		||||
		const minFilter = ! texture.isVideoTexture && texture.minFilter === LinearFilter ? LinearMipmapLinearFilter : texture.minFilter;
 | 
			
		||||
 | 
			
		||||
		gl.texParameteri( textureType, gl.TEXTURE_MIN_FILTER, filterToGL[ minFilter ] );
 | 
			
		||||
 | 
			
		||||
		if ( texture.compareFunction ) {
 | 
			
		||||
 | 
			
		||||
			gl.texParameteri( textureType, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE );
 | 
			
		||||
			gl.texParameteri( textureType, gl.TEXTURE_COMPARE_FUNC, compareToGL[ texture.compareFunction ] );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( extensions.has( 'EXT_texture_filter_anisotropic' ) === true ) {
 | 
			
		||||
 | 
			
		||||
			if ( texture.magFilter === NearestFilter ) return;
 | 
			
		||||
			if ( texture.minFilter !== NearestMipmapLinearFilter && texture.minFilter !== LinearMipmapLinearFilter ) return;
 | 
			
		||||
			if ( texture.type === FloatType && extensions.has( 'OES_texture_float_linear' ) === false ) return; // verify extension for WebGL 1 and WebGL 2
 | 
			
		||||
 | 
			
		||||
			if ( texture.anisotropy > 1 || currentAnisotropy !== texture.anisotropy ) {
 | 
			
		||||
 | 
			
		||||
				const extension = extensions.get( 'EXT_texture_filter_anisotropic' );
 | 
			
		||||
				gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, backend.getMaxAnisotropy() ) );
 | 
			
		||||
				backend.get( texture ).currentAnisotropy = texture.anisotropy;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	createDefaultTexture( texture ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, backend, defaultTextures } = this;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		const glTextureType = this.getGLTextureType( texture );
 | 
			
		||||
 | 
			
		||||
		let textureGPU = defaultTextures[ glTextureType ];
 | 
			
		||||
 | 
			
		||||
		if ( textureGPU === undefined ) {
 | 
			
		||||
 | 
			
		||||
			textureGPU = gl.createTexture();
 | 
			
		||||
 | 
			
		||||
			backend.state.bindTexture( glTextureType, textureGPU );
 | 
			
		||||
			gl.texParameteri( glTextureType, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
 | 
			
		||||
			gl.texParameteri( glTextureType, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
 | 
			
		||||
 | 
			
		||||
			// gl.texImage2D( glTextureType, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );
 | 
			
		||||
 | 
			
		||||
			defaultTextures[ glTextureType ] = textureGPU;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		backend.set( texture, {
 | 
			
		||||
			textureGPU,
 | 
			
		||||
			glTextureType,
 | 
			
		||||
			isDefault: true
 | 
			
		||||
		} );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	createTexture( texture, options ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, backend } = this;
 | 
			
		||||
		const { levels, width, height, depth } = options;
 | 
			
		||||
 | 
			
		||||
		const glFormat = backend.utils.convert( texture.format, texture.colorSpace );
 | 
			
		||||
		const glType = backend.utils.convert( texture.type );
 | 
			
		||||
		const glInternalFormat = this.getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace, texture.isVideoTexture );
 | 
			
		||||
 | 
			
		||||
		const textureGPU = gl.createTexture();
 | 
			
		||||
		const glTextureType = this.getGLTextureType( texture );
 | 
			
		||||
 | 
			
		||||
		backend.state.bindTexture( glTextureType, textureGPU );
 | 
			
		||||
 | 
			
		||||
		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 );
 | 
			
		||||
		gl.pixelStorei( gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE );
 | 
			
		||||
 | 
			
		||||
		this.setTextureParameters( glTextureType, texture );
 | 
			
		||||
 | 
			
		||||
		if ( texture.isDataArrayTexture ) {
 | 
			
		||||
 | 
			
		||||
			gl.texStorage3D( gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, width, height, depth );
 | 
			
		||||
 | 
			
		||||
		} else if ( ! texture.isVideoTexture ) {
 | 
			
		||||
 | 
			
		||||
			gl.texStorage2D( glTextureType, levels, glInternalFormat, width, height );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		backend.set( texture, {
 | 
			
		||||
			textureGPU,
 | 
			
		||||
			glTextureType,
 | 
			
		||||
			glFormat,
 | 
			
		||||
			glType,
 | 
			
		||||
			glInternalFormat
 | 
			
		||||
		} );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	copyBufferToTexture( buffer, texture ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, backend } = this;
 | 
			
		||||
 | 
			
		||||
		const { textureGPU, glTextureType, glFormat, glType } = backend.get( texture );
 | 
			
		||||
 | 
			
		||||
		const { width, height } = texture.source.data;
 | 
			
		||||
 | 
			
		||||
		gl.bindBuffer( gl.PIXEL_UNPACK_BUFFER, buffer );
 | 
			
		||||
 | 
			
		||||
		backend.state.bindTexture( glTextureType, textureGPU );
 | 
			
		||||
 | 
			
		||||
		gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, false );
 | 
			
		||||
		gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false );
 | 
			
		||||
		gl.texSubImage2D( glTextureType, 0, 0, 0, width, height, glFormat, glType, 0 );
 | 
			
		||||
 | 
			
		||||
		gl.bindBuffer( gl.PIXEL_UNPACK_BUFFER, null );
 | 
			
		||||
 | 
			
		||||
		backend.state.unbindTexture();
 | 
			
		||||
		// debug
 | 
			
		||||
		// const framebuffer = gl.createFramebuffer();
 | 
			
		||||
		// gl.bindFramebuffer( gl.FRAMEBUFFER, framebuffer );
 | 
			
		||||
		// gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, glTextureType, textureGPU, 0 );
 | 
			
		||||
 | 
			
		||||
		// const readout = new Float32Array( width * height * 4 );
 | 
			
		||||
 | 
			
		||||
		// const altFormat = gl.getParameter( gl.IMPLEMENTATION_COLOR_READ_FORMAT );
 | 
			
		||||
		// const altType = gl.getParameter( gl.IMPLEMENTATION_COLOR_READ_TYPE );
 | 
			
		||||
 | 
			
		||||
		// gl.readPixels( 0, 0, width, height, altFormat, altType, readout );
 | 
			
		||||
		// gl.bindFramebuffer( gl.FRAMEBUFFER, null );
 | 
			
		||||
		// console.log( readout );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	updateTexture( texture, options ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
		const { width, height } = options;
 | 
			
		||||
		const { textureGPU, glTextureType, glFormat, glType, glInternalFormat } = this.backend.get( texture );
 | 
			
		||||
 | 
			
		||||
		if ( texture.isRenderTargetTexture || ( textureGPU === undefined /* unsupported texture format */ ) )
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		const getImage = ( source ) => {
 | 
			
		||||
 | 
			
		||||
			if ( source.isDataTexture ) {
 | 
			
		||||
 | 
			
		||||
				return source.image.data;
 | 
			
		||||
 | 
			
		||||
			} else if ( source instanceof ImageBitmap || source instanceof OffscreenCanvas || source instanceof HTMLImageElement || source instanceof HTMLCanvasElement ) {
 | 
			
		||||
 | 
			
		||||
				return source;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return source.data;
 | 
			
		||||
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		this.backend.state.bindTexture( glTextureType, textureGPU );
 | 
			
		||||
 | 
			
		||||
		if ( texture.isCompressedTexture ) {
 | 
			
		||||
 | 
			
		||||
			const mipmaps = texture.mipmaps;
 | 
			
		||||
 | 
			
		||||
			for ( let i = 0; i < mipmaps.length; i ++ ) {
 | 
			
		||||
 | 
			
		||||
				const mipmap = mipmaps[ i ];
 | 
			
		||||
 | 
			
		||||
				if ( texture.isCompressedArrayTexture ) {
 | 
			
		||||
 | 
			
		||||
					const image = options.image;
 | 
			
		||||
 | 
			
		||||
					if ( texture.format !== gl.RGBA ) {
 | 
			
		||||
 | 
			
		||||
						if ( glFormat !== null ) {
 | 
			
		||||
 | 
			
		||||
							gl.compressedTexSubImage3D( gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data, 0, 0 );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
						} else {
 | 
			
		||||
 | 
			
		||||
							console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' );
 | 
			
		||||
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
					} else {
 | 
			
		||||
 | 
			
		||||
						gl.texSubImage3D( gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data );
 | 
			
		||||
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
				} else {
 | 
			
		||||
 | 
			
		||||
					if ( glFormat !== null ) {
 | 
			
		||||
 | 
			
		||||
						gl.compressedTexSubImage2D( gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data );
 | 
			
		||||
 | 
			
		||||
					} else {
 | 
			
		||||
 | 
			
		||||
						console.warn( 'Unsupported compressed texture format' );
 | 
			
		||||
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		} else if ( texture.isCubeTexture ) {
 | 
			
		||||
 | 
			
		||||
			const images = options.images;
 | 
			
		||||
 | 
			
		||||
			for ( let i = 0; i < 6; i ++ ) {
 | 
			
		||||
 | 
			
		||||
				const image = getImage( images[ i ] );
 | 
			
		||||
 | 
			
		||||
				gl.texSubImage2D( gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, width, height, glFormat, glType, image );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		} else if ( texture.isDataArrayTexture ) {
 | 
			
		||||
 | 
			
		||||
			const image = options.image;
 | 
			
		||||
 | 
			
		||||
			gl.texSubImage3D( gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );
 | 
			
		||||
 | 
			
		||||
		} else if ( texture.isVideoTexture ) {
 | 
			
		||||
 | 
			
		||||
			texture.update();
 | 
			
		||||
 | 
			
		||||
			gl.texImage2D( glTextureType, 0, glInternalFormat, glFormat, glType, options.image );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			const image = getImage( options.image );
 | 
			
		||||
 | 
			
		||||
			gl.texSubImage2D( glTextureType, 0, 0, 0, width, height, glFormat, glType, image );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	generateMipmaps( texture ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, backend } = this;
 | 
			
		||||
		const { textureGPU, glTextureType } = backend.get( texture );
 | 
			
		||||
 | 
			
		||||
		backend.state.bindTexture( glTextureType, textureGPU );
 | 
			
		||||
		gl.generateMipmap( glTextureType );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	deallocateRenderBuffers( renderTarget ) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		const { gl, backend } = this;
 | 
			
		||||
 | 
			
		||||
		// remove framebuffer reference
 | 
			
		||||
		if ( renderTarget ) {
 | 
			
		||||
 | 
			
		||||
			const renderContextData = backend.get( renderTarget );
 | 
			
		||||
 | 
			
		||||
			renderContextData.renderBufferStorageSetup = undefined;
 | 
			
		||||
 | 
			
		||||
			if ( renderContextData.framebuffer ) {
 | 
			
		||||
 | 
			
		||||
				gl.deleteFramebuffer( renderContextData.framebuffer );
 | 
			
		||||
				renderContextData.framebuffer = undefined;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if ( renderContextData.depthRenderbuffer ) {
 | 
			
		||||
 | 
			
		||||
				gl.deleteRenderbuffer( renderContextData.depthRenderbuffer );
 | 
			
		||||
				renderContextData.depthRenderbuffer = undefined;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if ( renderContextData.stencilRenderbuffer ) {
 | 
			
		||||
 | 
			
		||||
				gl.deleteRenderbuffer( renderContextData.stencilRenderbuffer );
 | 
			
		||||
				renderContextData.stencilRenderbuffer = undefined;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if ( renderContextData.msaaFrameBuffer ) {
 | 
			
		||||
 | 
			
		||||
				gl.deleteFramebuffer( renderContextData.msaaFrameBuffer );
 | 
			
		||||
				renderContextData.msaaFrameBuffer = undefined;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if ( renderContextData.msaaRenderbuffers ) {
 | 
			
		||||
 | 
			
		||||
				for ( let i = 0; i < renderContextData.msaaRenderbuffers.length; i ++ ) {
 | 
			
		||||
 | 
			
		||||
					gl.deleteRenderbuffer( renderContextData.msaaRenderbuffers[ i ] );
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				renderContextData.msaaRenderbuffers = undefined;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	destroyTexture( texture ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, backend } = this;
 | 
			
		||||
		const { textureGPU, renderTarget } = backend.get( texture );
 | 
			
		||||
 | 
			
		||||
		this.deallocateRenderBuffers( renderTarget );
 | 
			
		||||
		gl.deleteTexture( textureGPU );
 | 
			
		||||
 | 
			
		||||
		backend.delete( texture );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, backend } = this;
 | 
			
		||||
		const { state } = this.backend;
 | 
			
		||||
 | 
			
		||||
		const width = srcTexture.image.width;
 | 
			
		||||
		const height = srcTexture.image.height;
 | 
			
		||||
		const { textureGPU: dstTextureGPU, glTextureType, glType, glFormat } = backend.get( dstTexture );
 | 
			
		||||
 | 
			
		||||
		state.bindTexture( glTextureType, dstTextureGPU );
 | 
			
		||||
 | 
			
		||||
		// As another texture upload may have changed pixelStorei
 | 
			
		||||
		// parameters, make sure they are correct for the dstTexture
 | 
			
		||||
		gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
 | 
			
		||||
		gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
 | 
			
		||||
		gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
 | 
			
		||||
 | 
			
		||||
		if ( srcTexture.isDataTexture ) {
 | 
			
		||||
 | 
			
		||||
			gl.texSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data );
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			if ( srcTexture.isCompressedTexture ) {
 | 
			
		||||
 | 
			
		||||
				gl.compressedTexSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data );
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				gl.texSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Generate mipmaps only when copying level 0
 | 
			
		||||
		if ( level === 0 && dstTexture.generateMipmaps ) gl.generateMipmap( gl.TEXTURE_2D );
 | 
			
		||||
 | 
			
		||||
		state.unbindTexture();
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	copyFramebufferToTexture( texture, renderContext ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
		const { state } = this.backend;
 | 
			
		||||
 | 
			
		||||
		const { textureGPU } = this.backend.get( texture );
 | 
			
		||||
 | 
			
		||||
		const width = texture.image.width;
 | 
			
		||||
		const height = texture.image.height;
 | 
			
		||||
 | 
			
		||||
		const requireDrawFrameBuffer = texture.isDepthTexture === true || ( renderContext.renderTarget && renderContext.renderTarget.samples > 0 );
 | 
			
		||||
 | 
			
		||||
		if ( requireDrawFrameBuffer ) {
 | 
			
		||||
 | 
			
		||||
			let mask;
 | 
			
		||||
			let attachment;
 | 
			
		||||
 | 
			
		||||
			if ( texture.isDepthTexture === true ) {
 | 
			
		||||
 | 
			
		||||
				mask = gl.DEPTH_BUFFER_BIT;
 | 
			
		||||
				attachment = gl.DEPTH_ATTACHMENT;
 | 
			
		||||
 | 
			
		||||
				if ( renderContext.stencil ) {
 | 
			
		||||
 | 
			
		||||
					mask |= gl.STENCIL_BUFFER_BIT;
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				mask = gl.COLOR_BUFFER_BIT;
 | 
			
		||||
				attachment = gl.COLOR_ATTACHMENT0;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			const fb = gl.createFramebuffer();
 | 
			
		||||
			state.bindFramebuffer( gl.DRAW_FRAMEBUFFER, fb );
 | 
			
		||||
 | 
			
		||||
			gl.framebufferTexture2D( gl.DRAW_FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureGPU, 0 );
 | 
			
		||||
 | 
			
		||||
			gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, gl.NEAREST );
 | 
			
		||||
 | 
			
		||||
			gl.deleteFramebuffer( fb );
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			state.bindTexture( gl.TEXTURE_2D, textureGPU );
 | 
			
		||||
			gl.copyTexSubImage2D( gl.TEXTURE_2D, 0, 0, 0, 0, 0, width, height );
 | 
			
		||||
 | 
			
		||||
			state.unbindTexture();
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( texture.generateMipmaps ) this.generateMipmaps( texture );
 | 
			
		||||
 | 
			
		||||
		this.backend._setFramebuffer( renderContext );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
 | 
			
		||||
	setupRenderBufferStorage( renderbuffer, renderContext ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
		const renderTarget = renderContext.renderTarget;
 | 
			
		||||
 | 
			
		||||
		const { samples, depthTexture, depthBuffer, stencilBuffer, width, height } = renderTarget;
 | 
			
		||||
 | 
			
		||||
		gl.bindRenderbuffer( gl.RENDERBUFFER, renderbuffer );
 | 
			
		||||
 | 
			
		||||
		if ( depthBuffer && ! stencilBuffer ) {
 | 
			
		||||
 | 
			
		||||
			let glInternalFormat = gl.DEPTH_COMPONENT24;
 | 
			
		||||
 | 
			
		||||
			if ( samples > 0 ) {
 | 
			
		||||
 | 
			
		||||
				if ( depthTexture && depthTexture.isDepthTexture ) {
 | 
			
		||||
 | 
			
		||||
					if ( depthTexture.type === gl.FLOAT ) {
 | 
			
		||||
 | 
			
		||||
						glInternalFormat = gl.DEPTH_COMPONENT32F;
 | 
			
		||||
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				gl.renderbufferStorageMultisample( gl.RENDERBUFFER, samples, glInternalFormat, width, height );
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				gl.renderbufferStorage( gl.RENDERBUFFER, glInternalFormat, width, height );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer );
 | 
			
		||||
 | 
			
		||||
		} else if ( depthBuffer && stencilBuffer ) {
 | 
			
		||||
 | 
			
		||||
			if ( samples > 0 ) {
 | 
			
		||||
 | 
			
		||||
				gl.renderbufferStorageMultisample( gl.RENDERBUFFER, samples, gl.DEPTH24_STENCIL8, width, height );
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				gl.renderbufferStorage( gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, renderbuffer );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	async copyTextureToBuffer( texture, x, y, width, height ) {
 | 
			
		||||
 | 
			
		||||
		const { backend, gl } = this;
 | 
			
		||||
 | 
			
		||||
		const { textureGPU, glFormat, glType } = this.backend.get( texture );
 | 
			
		||||
 | 
			
		||||
		const fb = gl.createFramebuffer();
 | 
			
		||||
 | 
			
		||||
		gl.bindFramebuffer( gl.READ_FRAMEBUFFER, fb );
 | 
			
		||||
		gl.framebufferTexture2D( gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureGPU, 0 );
 | 
			
		||||
 | 
			
		||||
		const typedArrayType = this._getTypedArrayType( glType );
 | 
			
		||||
		const bytesPerTexel = this._getBytesPerTexel( glFormat );
 | 
			
		||||
 | 
			
		||||
		const elementCount = width * height;
 | 
			
		||||
		const byteLength = elementCount * bytesPerTexel;
 | 
			
		||||
 | 
			
		||||
		const buffer = gl.createBuffer();
 | 
			
		||||
 | 
			
		||||
		gl.bindBuffer( gl.PIXEL_PACK_BUFFER, buffer );
 | 
			
		||||
		gl.bufferData( gl.PIXEL_PACK_BUFFER, byteLength, gl.STREAM_READ );
 | 
			
		||||
		gl.readPixels( x, y, width, height, glFormat, glType, 0 );
 | 
			
		||||
		gl.bindBuffer( gl.PIXEL_PACK_BUFFER, null );
 | 
			
		||||
 | 
			
		||||
		await backend.utils._clientWaitAsync();
 | 
			
		||||
 | 
			
		||||
		const dstBuffer = new typedArrayType( byteLength / typedArrayType.BYTES_PER_ELEMENT );
 | 
			
		||||
 | 
			
		||||
		gl.bindBuffer( gl.PIXEL_PACK_BUFFER, buffer );
 | 
			
		||||
		gl.getBufferSubData( gl.PIXEL_PACK_BUFFER, 0, dstBuffer );
 | 
			
		||||
		gl.bindBuffer( gl.PIXEL_PACK_BUFFER, null );
 | 
			
		||||
 | 
			
		||||
		gl.deleteFramebuffer( fb );
 | 
			
		||||
 | 
			
		||||
		return dstBuffer;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_getTypedArrayType( glType ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		if ( glType === gl.UNSIGNED_BYTE ) return Uint8Array;
 | 
			
		||||
 | 
			
		||||
		if ( glType === gl.UNSIGNED_SHORT_4_4_4_4 ) return Uint16Array;
 | 
			
		||||
		if ( glType === gl.UNSIGNED_SHORT_5_5_5_1 ) return Uint16Array;
 | 
			
		||||
		if ( glType === gl.UNSIGNED_SHORT_5_6_5 ) return Uint16Array;
 | 
			
		||||
		if ( glType === gl.UNSIGNED_SHORT ) return Uint16Array;
 | 
			
		||||
		if ( glType === gl.UNSIGNED_INT ) return Uint32Array;
 | 
			
		||||
 | 
			
		||||
		if ( glType === gl.FLOAT ) return Float32Array;
 | 
			
		||||
 | 
			
		||||
		throw new Error( `Unsupported WebGL type: ${glType}` );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_getBytesPerTexel( glFormat ) {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		if ( glFormat === gl.RGBA ) return 4;
 | 
			
		||||
		if ( glFormat === gl.RGB ) return 3;
 | 
			
		||||
		if ( glFormat === gl.ALPHA ) return 1;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default WebGLTextureUtils;
 | 
			
		||||
							
								
								
									
										268
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLUtils.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										268
									
								
								dist/electron/static/sdk/three/jsm/renderers/webgl/utils/WebGLUtils.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,268 @@
 | 
			
		||||
import { RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, DepthFormat, DepthStencilFormat, LuminanceAlphaFormat, LuminanceFormat, RedFormat, RGBFormat, RGBAFormat, AlphaFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBAIntegerFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedInt5999Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, RGBA_BPTC_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, SRGBColorSpace, NoColorSpace } from 'three';
 | 
			
		||||
 | 
			
		||||
class WebGLUtils {
 | 
			
		||||
 | 
			
		||||
	constructor( backend ) {
 | 
			
		||||
 | 
			
		||||
		this.backend = backend;
 | 
			
		||||
 | 
			
		||||
		this.gl = this.backend.gl;
 | 
			
		||||
		this.extensions = backend.extensions;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	convert( p, colorSpace = NoColorSpace ) {
 | 
			
		||||
 | 
			
		||||
		const { gl, extensions } = this;
 | 
			
		||||
 | 
			
		||||
		let extension;
 | 
			
		||||
 | 
			
		||||
		if ( p === UnsignedByteType ) return gl.UNSIGNED_BYTE;
 | 
			
		||||
		if ( p === UnsignedShort4444Type ) return gl.UNSIGNED_SHORT_4_4_4_4;
 | 
			
		||||
		if ( p === UnsignedShort5551Type ) return gl.UNSIGNED_SHORT_5_5_5_1;
 | 
			
		||||
		if ( p === UnsignedInt5999Type ) return gl.UNSIGNED_INT_5_9_9_9_REV;
 | 
			
		||||
 | 
			
		||||
		if ( p === ByteType ) return gl.BYTE;
 | 
			
		||||
		if ( p === ShortType ) return gl.SHORT;
 | 
			
		||||
		if ( p === UnsignedShortType ) return gl.UNSIGNED_SHORT;
 | 
			
		||||
		if ( p === IntType ) return gl.INT;
 | 
			
		||||
		if ( p === UnsignedIntType ) return gl.UNSIGNED_INT;
 | 
			
		||||
		if ( p === FloatType ) return gl.FLOAT;
 | 
			
		||||
 | 
			
		||||
		if ( p === HalfFloatType ) {
 | 
			
		||||
 | 
			
		||||
			return gl.HALF_FLOAT;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( p === AlphaFormat ) return gl.ALPHA;
 | 
			
		||||
		if ( p === RGBFormat ) return gl.RGB;
 | 
			
		||||
		if ( p === RGBAFormat ) return gl.RGBA;
 | 
			
		||||
		if ( p === LuminanceFormat ) return gl.LUMINANCE;
 | 
			
		||||
		if ( p === LuminanceAlphaFormat ) return gl.LUMINANCE_ALPHA;
 | 
			
		||||
		if ( p === DepthFormat ) return gl.DEPTH_COMPONENT;
 | 
			
		||||
		if ( p === DepthStencilFormat ) return gl.DEPTH_STENCIL;
 | 
			
		||||
 | 
			
		||||
		// WebGL2 formats.
 | 
			
		||||
 | 
			
		||||
		if ( p === RedFormat ) return gl.RED;
 | 
			
		||||
		if ( p === RedIntegerFormat ) return gl.RED_INTEGER;
 | 
			
		||||
		if ( p === RGFormat ) return gl.RG;
 | 
			
		||||
		if ( p === RGIntegerFormat ) return gl.RG_INTEGER;
 | 
			
		||||
		if ( p === RGBAIntegerFormat ) return gl.RGBA_INTEGER;
 | 
			
		||||
 | 
			
		||||
		// S3TC
 | 
			
		||||
 | 
			
		||||
		if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
 | 
			
		||||
 | 
			
		||||
			if ( colorSpace === SRGBColorSpace ) {
 | 
			
		||||
 | 
			
		||||
				extension = extensions.get( 'WEBGL_compressed_texture_s3tc_srgb' );
 | 
			
		||||
 | 
			
		||||
				if ( extension !== null ) {
 | 
			
		||||
 | 
			
		||||
					if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT;
 | 
			
		||||
					if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
 | 
			
		||||
					if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
 | 
			
		||||
					if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
 | 
			
		||||
 | 
			
		||||
				} else {
 | 
			
		||||
 | 
			
		||||
					return null;
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
 | 
			
		||||
 | 
			
		||||
				if ( extension !== null ) {
 | 
			
		||||
 | 
			
		||||
					if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
 | 
			
		||||
					if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
 | 
			
		||||
					if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
 | 
			
		||||
					if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
 | 
			
		||||
 | 
			
		||||
				} else {
 | 
			
		||||
 | 
			
		||||
					return null;
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// PVRTC
 | 
			
		||||
 | 
			
		||||
		if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
 | 
			
		||||
 | 
			
		||||
			extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );
 | 
			
		||||
 | 
			
		||||
			if ( extension !== null ) {
 | 
			
		||||
 | 
			
		||||
				if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
 | 
			
		||||
				if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
 | 
			
		||||
				if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
 | 
			
		||||
				if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				return null;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// ETC
 | 
			
		||||
 | 
			
		||||
		if ( p === RGB_ETC1_Format || p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format ) {
 | 
			
		||||
 | 
			
		||||
			extension = extensions.get( 'WEBGL_compressed_texture_etc' );
 | 
			
		||||
 | 
			
		||||
			if ( extension !== null ) {
 | 
			
		||||
 | 
			
		||||
				if ( p === RGB_ETC1_Format || p === RGB_ETC2_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2;
 | 
			
		||||
				if ( p === RGBA_ETC2_EAC_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC;
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				return null;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// ASTC
 | 
			
		||||
 | 
			
		||||
		if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format ||
 | 
			
		||||
			p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format ||
 | 
			
		||||
			p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format ||
 | 
			
		||||
			p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format ||
 | 
			
		||||
			p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format ) {
 | 
			
		||||
 | 
			
		||||
			extension = extensions.get( 'WEBGL_compressed_texture_astc' );
 | 
			
		||||
 | 
			
		||||
			if ( extension !== null ) {
 | 
			
		||||
 | 
			
		||||
				if ( p === RGBA_ASTC_4x4_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_5x4_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_5x5_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_6x5_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_6x6_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_8x5_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_8x6_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_8x8_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_10x5_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_10x6_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_10x8_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_10x10_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_12x10_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR;
 | 
			
		||||
				if ( p === RGBA_ASTC_12x12_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR;
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				return null;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// BPTC
 | 
			
		||||
 | 
			
		||||
		if ( p === RGBA_BPTC_Format ) {
 | 
			
		||||
 | 
			
		||||
			extension = extensions.get( 'EXT_texture_compression_bptc' );
 | 
			
		||||
 | 
			
		||||
			if ( extension !== null ) {
 | 
			
		||||
 | 
			
		||||
				if ( p === RGBA_BPTC_Format ) return ( colorSpace === SRGBColorSpace ) ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT;
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				return null;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// RGTC
 | 
			
		||||
 | 
			
		||||
		if ( p === RED_RGTC1_Format || p === SIGNED_RED_RGTC1_Format || p === RED_GREEN_RGTC2_Format || p === SIGNED_RED_GREEN_RGTC2_Format ) {
 | 
			
		||||
 | 
			
		||||
			extension = extensions.get( 'EXT_texture_compression_rgtc' );
 | 
			
		||||
 | 
			
		||||
			if ( extension !== null ) {
 | 
			
		||||
 | 
			
		||||
				if ( p === RGBA_BPTC_Format ) return extension.COMPRESSED_RED_RGTC1_EXT;
 | 
			
		||||
				if ( p === SIGNED_RED_RGTC1_Format ) return extension.COMPRESSED_SIGNED_RED_RGTC1_EXT;
 | 
			
		||||
				if ( p === RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_RED_GREEN_RGTC2_EXT;
 | 
			
		||||
				if ( p === SIGNED_RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT;
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				return null;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//
 | 
			
		||||
 | 
			
		||||
		if ( p === UnsignedInt248Type ) {
 | 
			
		||||
 | 
			
		||||
			return gl.UNSIGNED_INT_24_8;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// if "p" can't be resolved, assume the user defines a WebGL constant as a string (fallback/workaround for packed RGB formats)
 | 
			
		||||
 | 
			
		||||
		return ( gl[ p ] !== undefined ) ? gl[ p ] : null;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_clientWaitAsync() {
 | 
			
		||||
 | 
			
		||||
		const { gl } = this;
 | 
			
		||||
 | 
			
		||||
		const sync = gl.fenceSync( gl.SYNC_GPU_COMMANDS_COMPLETE, 0 );
 | 
			
		||||
 | 
			
		||||
		gl.flush();
 | 
			
		||||
 | 
			
		||||
		return new Promise( ( resolve, reject ) => {
 | 
			
		||||
 | 
			
		||||
			function test() {
 | 
			
		||||
 | 
			
		||||
				const res = gl.clientWaitSync( sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0 );
 | 
			
		||||
 | 
			
		||||
				if ( res === gl.WAIT_FAILED ) {
 | 
			
		||||
 | 
			
		||||
					gl.deleteSync( sync );
 | 
			
		||||
 | 
			
		||||
					reject();
 | 
			
		||||
					return;
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if ( res === gl.TIMEOUT_EXPIRED ) {
 | 
			
		||||
 | 
			
		||||
					requestAnimationFrame( test );
 | 
			
		||||
					return;
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				gl.deleteSync( sync );
 | 
			
		||||
 | 
			
		||||
				resolve();
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			test();
 | 
			
		||||
 | 
			
		||||
		} );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default WebGLUtils;
 | 
			
		||||
		Reference in New Issue
	
	Block a user