| |
| |
| |
|
|
| import { NotEqualDepth, GreaterDepth, GreaterEqualDepth, EqualDepth, LessEqualDepth, LessDepth, AlwaysDepth, NeverDepth, CullFaceFront, CullFaceBack, CullFaceNone, CustomBlending, MultiplyBlending, SubtractiveBlending, AdditiveBlending, NoBlending, NormalBlending, AddEquation, DoubleSide, BackSide } from '../../constants.js'; |
| import { Vector4 } from '../../math/Vector4.js'; |
|
|
| function WebGLState( gl, extensions, utils, capabilities ) { |
|
|
| function ColorBuffer() { |
|
|
| var locked = false; |
|
|
| var color = new Vector4(); |
| var currentColorMask = null; |
| var currentColorClear = new Vector4( 0, 0, 0, 0 ); |
|
|
| return { |
|
|
| setMask: function ( colorMask ) { |
|
|
| if ( currentColorMask !== colorMask && ! locked ) { |
|
|
| gl.colorMask( colorMask, colorMask, colorMask, colorMask ); |
| currentColorMask = colorMask; |
|
|
| } |
|
|
| }, |
|
|
| setLocked: function ( lock ) { |
|
|
| locked = lock; |
|
|
| }, |
|
|
| setClear: function ( r, g, b, a, premultipliedAlpha ) { |
|
|
| if ( premultipliedAlpha === true ) { |
|
|
| r *= a; g *= a; b *= a; |
|
|
| } |
|
|
| color.set( r, g, b, a ); |
|
|
| if ( currentColorClear.equals( color ) === false ) { |
|
|
| gl.clearColor( r, g, b, a ); |
| currentColorClear.copy( color ); |
|
|
| } |
|
|
| }, |
|
|
| reset: function () { |
|
|
| locked = false; |
|
|
| currentColorMask = null; |
| currentColorClear.set( - 1, 0, 0, 0 ); |
|
|
| } |
|
|
| }; |
|
|
| } |
|
|
| function DepthBuffer() { |
|
|
| var locked = false; |
|
|
| var currentDepthMask = null; |
| var currentDepthFunc = null; |
| var currentDepthClear = null; |
|
|
| return { |
|
|
| setTest: function ( depthTest ) { |
|
|
| if ( depthTest ) { |
|
|
| enable( gl.DEPTH_TEST ); |
|
|
| } else { |
|
|
| disable( gl.DEPTH_TEST ); |
|
|
| } |
|
|
| }, |
|
|
| setMask: function ( depthMask ) { |
|
|
| if ( currentDepthMask !== depthMask && ! locked ) { |
|
|
| gl.depthMask( depthMask ); |
| currentDepthMask = depthMask; |
|
|
| } |
|
|
| }, |
|
|
| setFunc: function ( depthFunc ) { |
|
|
| if ( currentDepthFunc !== depthFunc ) { |
|
|
| if ( depthFunc ) { |
|
|
| 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 ); |
|
|
| } |
|
|
| } else { |
|
|
| gl.depthFunc( gl.LEQUAL ); |
|
|
| } |
|
|
| currentDepthFunc = depthFunc; |
|
|
| } |
|
|
| }, |
|
|
| setLocked: function ( lock ) { |
|
|
| locked = lock; |
|
|
| }, |
|
|
| setClear: function ( depth ) { |
|
|
| if ( currentDepthClear !== depth ) { |
|
|
| gl.clearDepth( depth ); |
| currentDepthClear = depth; |
|
|
| } |
|
|
| }, |
|
|
| reset: function () { |
|
|
| locked = false; |
|
|
| currentDepthMask = null; |
| currentDepthFunc = null; |
| currentDepthClear = null; |
|
|
| } |
|
|
| }; |
|
|
| } |
|
|
| function StencilBuffer() { |
|
|
| var locked = false; |
|
|
| var currentStencilMask = null; |
| var currentStencilFunc = null; |
| var currentStencilRef = null; |
| var currentStencilFuncMask = null; |
| var currentStencilFail = null; |
| var currentStencilZFail = null; |
| var currentStencilZPass = null; |
| var currentStencilClear = null; |
|
|
| return { |
|
|
| setTest: function ( stencilTest ) { |
|
|
| if ( stencilTest ) { |
|
|
| enable( gl.STENCIL_TEST ); |
|
|
| } else { |
|
|
| disable( gl.STENCIL_TEST ); |
|
|
| } |
|
|
| }, |
|
|
| setMask: function ( stencilMask ) { |
|
|
| if ( currentStencilMask !== stencilMask && ! locked ) { |
|
|
| gl.stencilMask( stencilMask ); |
| currentStencilMask = stencilMask; |
|
|
| } |
|
|
| }, |
|
|
| setFunc: function ( stencilFunc, stencilRef, stencilMask ) { |
|
|
| if ( currentStencilFunc !== stencilFunc || |
| currentStencilRef !== stencilRef || |
| currentStencilFuncMask !== stencilMask ) { |
|
|
| gl.stencilFunc( stencilFunc, stencilRef, stencilMask ); |
|
|
| currentStencilFunc = stencilFunc; |
| currentStencilRef = stencilRef; |
| currentStencilFuncMask = stencilMask; |
|
|
| } |
|
|
| }, |
|
|
| setOp: function ( stencilFail, stencilZFail, stencilZPass ) { |
|
|
| if ( currentStencilFail !== stencilFail || |
| currentStencilZFail !== stencilZFail || |
| currentStencilZPass !== stencilZPass ) { |
|
|
| gl.stencilOp( stencilFail, stencilZFail, stencilZPass ); |
|
|
| currentStencilFail = stencilFail; |
| currentStencilZFail = stencilZFail; |
| currentStencilZPass = stencilZPass; |
|
|
| } |
|
|
| }, |
|
|
| setLocked: function ( lock ) { |
|
|
| locked = lock; |
|
|
| }, |
|
|
| setClear: function ( stencil ) { |
|
|
| if ( currentStencilClear !== stencil ) { |
|
|
| gl.clearStencil( stencil ); |
| currentStencilClear = stencil; |
|
|
| } |
|
|
| }, |
|
|
| reset: function () { |
|
|
| locked = false; |
|
|
| currentStencilMask = null; |
| currentStencilFunc = null; |
| currentStencilRef = null; |
| currentStencilFuncMask = null; |
| currentStencilFail = null; |
| currentStencilZFail = null; |
| currentStencilZPass = null; |
| currentStencilClear = null; |
|
|
| } |
|
|
| }; |
|
|
| } |
|
|
| |
|
|
| var colorBuffer = new ColorBuffer(); |
| var depthBuffer = new DepthBuffer(); |
| var stencilBuffer = new StencilBuffer(); |
|
|
| var maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); |
| var newAttributes = new Uint8Array( maxVertexAttributes ); |
| var enabledAttributes = new Uint8Array( maxVertexAttributes ); |
| var attributeDivisors = new Uint8Array( maxVertexAttributes ); |
|
|
| var enabledCapabilities = {}; |
|
|
| var compressedTextureFormats = null; |
|
|
| var currentProgram = null; |
|
|
| var currentBlendingEnabled = null; |
| var currentBlending = null; |
| var currentBlendEquation = null; |
| var currentBlendSrc = null; |
| var currentBlendDst = null; |
| var currentBlendEquationAlpha = null; |
| var currentBlendSrcAlpha = null; |
| var currentBlendDstAlpha = null; |
| var currentPremultipledAlpha = false; |
|
|
| var currentFlipSided = null; |
| var currentCullFace = null; |
|
|
| var currentLineWidth = null; |
|
|
| var currentPolygonOffsetFactor = null; |
| var currentPolygonOffsetUnits = null; |
|
|
| var maxTextures = gl.getParameter( gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS ); |
|
|
| var lineWidthAvailable = false; |
| var version = 0; |
| var glVersion = gl.getParameter( gl.VERSION ); |
|
|
| if ( glVersion.indexOf( 'WebGL' ) !== - 1 ) { |
|
|
| version = parseFloat( /^WebGL\ ([0-9])/.exec( glVersion )[ 1 ] ); |
| lineWidthAvailable = ( version >= 1.0 ); |
|
|
| } else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) { |
|
|
| version = parseFloat( /^OpenGL\ ES\ ([0-9])/.exec( glVersion )[ 1 ] ); |
| lineWidthAvailable = ( version >= 2.0 ); |
|
|
| } |
|
|
| var currentTextureSlot = null; |
| var currentBoundTextures = {}; |
|
|
| var currentScissor = new Vector4(); |
| var currentViewport = new Vector4(); |
|
|
| function createTexture( type, target, count ) { |
|
|
| var data = new Uint8Array( 4 ); |
| var texture = gl.createTexture(); |
|
|
| gl.bindTexture( type, texture ); |
| gl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST ); |
| gl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST ); |
|
|
| for ( var i = 0; i < count; i ++ ) { |
|
|
| gl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data ); |
|
|
| } |
|
|
| return texture; |
|
|
| } |
|
|
| var emptyTextures = {}; |
| emptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 ); |
| emptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 ); |
|
|
| |
|
|
| colorBuffer.setClear( 0, 0, 0, 1 ); |
| depthBuffer.setClear( 1 ); |
| stencilBuffer.setClear( 0 ); |
|
|
| enable( gl.DEPTH_TEST ); |
| depthBuffer.setFunc( LessEqualDepth ); |
|
|
| setFlipSided( false ); |
| setCullFace( CullFaceBack ); |
| enable( gl.CULL_FACE ); |
|
|
| setBlending( NoBlending ); |
|
|
| |
|
|
| function initAttributes() { |
|
|
| for ( var i = 0, l = newAttributes.length; i < l; i ++ ) { |
|
|
| newAttributes[ i ] = 0; |
|
|
| } |
|
|
| } |
|
|
| function enableAttribute( attribute ) { |
|
|
| enableAttributeAndDivisor( attribute, 0 ); |
|
|
| } |
|
|
| function enableAttributeAndDivisor( attribute, meshPerAttribute ) { |
|
|
| newAttributes[ attribute ] = 1; |
|
|
| if ( enabledAttributes[ attribute ] === 0 ) { |
|
|
| gl.enableVertexAttribArray( attribute ); |
| enabledAttributes[ attribute ] = 1; |
|
|
| } |
|
|
| if ( attributeDivisors[ attribute ] !== meshPerAttribute ) { |
|
|
| var extension = capabilities.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' ); |
|
|
| extension[ capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute ); |
| attributeDivisors[ attribute ] = meshPerAttribute; |
|
|
| } |
|
|
| } |
|
|
| function disableUnusedAttributes() { |
|
|
| for ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) { |
|
|
| if ( enabledAttributes[ i ] !== newAttributes[ i ] ) { |
|
|
| gl.disableVertexAttribArray( i ); |
| enabledAttributes[ i ] = 0; |
|
|
| } |
|
|
| } |
|
|
| } |
|
|
| function enable( id ) { |
|
|
| if ( enabledCapabilities[ id ] !== true ) { |
|
|
| gl.enable( id ); |
| enabledCapabilities[ id ] = true; |
|
|
| } |
|
|
| } |
|
|
| function disable( id ) { |
|
|
| if ( enabledCapabilities[ id ] !== false ) { |
|
|
| gl.disable( id ); |
| enabledCapabilities[ id ] = false; |
|
|
| } |
|
|
| } |
|
|
| function getCompressedTextureFormats() { |
|
|
| if ( compressedTextureFormats === null ) { |
|
|
| compressedTextureFormats = []; |
|
|
| if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) || |
| extensions.get( 'WEBGL_compressed_texture_s3tc' ) || |
| extensions.get( 'WEBGL_compressed_texture_etc1' ) || |
| extensions.get( 'WEBGL_compressed_texture_astc' ) ) { |
|
|
| var formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS ); |
|
|
| for ( var i = 0; i < formats.length; i ++ ) { |
|
|
| compressedTextureFormats.push( formats[ i ] ); |
|
|
| } |
|
|
| } |
|
|
| } |
|
|
| return compressedTextureFormats; |
|
|
| } |
|
|
| function useProgram( program ) { |
|
|
| if ( currentProgram !== program ) { |
|
|
| gl.useProgram( program ); |
|
|
| currentProgram = program; |
|
|
| return true; |
|
|
| } |
|
|
| return false; |
|
|
| } |
|
|
| function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) { |
|
|
| if ( blending === NoBlending ) { |
|
|
| if ( currentBlendingEnabled ) { |
|
|
| disable( gl.BLEND ); |
| currentBlendingEnabled = false; |
|
|
| } |
|
|
| return; |
|
|
| } |
|
|
| if ( ! currentBlendingEnabled ) { |
|
|
| enable( gl.BLEND ); |
| currentBlendingEnabled = true; |
|
|
| } |
|
|
| if ( blending !== CustomBlending ) { |
|
|
| if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) { |
|
|
| if ( currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation ) { |
|
|
| gl.blendEquation( gl.FUNC_ADD ); |
|
|
| currentBlendEquation = AddEquation; |
| 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.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA ); |
| 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.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR ); |
| break; |
|
|
| case MultiplyBlending: |
| gl.blendFunc( gl.ZERO, gl.SRC_COLOR ); |
| break; |
|
|
| default: |
| console.error( 'THREE.WebGLState: Invalid blending: ', blending ); |
| break; |
|
|
| } |
|
|
| } |
|
|
| currentBlendSrc = null; |
| currentBlendDst = null; |
| currentBlendSrcAlpha = null; |
| currentBlendDstAlpha = null; |
|
|
| currentBlending = blending; |
| currentPremultipledAlpha = premultipliedAlpha; |
|
|
| } |
|
|
| return; |
|
|
| } |
|
|
| |
|
|
| blendEquationAlpha = blendEquationAlpha || blendEquation; |
| blendSrcAlpha = blendSrcAlpha || blendSrc; |
| blendDstAlpha = blendDstAlpha || blendDst; |
|
|
| if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) { |
|
|
| gl.blendEquationSeparate( utils.convert( blendEquation ), utils.convert( blendEquationAlpha ) ); |
|
|
| currentBlendEquation = blendEquation; |
| currentBlendEquationAlpha = blendEquationAlpha; |
|
|
| } |
|
|
| if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) { |
|
|
| gl.blendFuncSeparate( utils.convert( blendSrc ), utils.convert( blendDst ), utils.convert( blendSrcAlpha ), utils.convert( blendDstAlpha ) ); |
|
|
| currentBlendSrc = blendSrc; |
| currentBlendDst = blendDst; |
| currentBlendSrcAlpha = blendSrcAlpha; |
| currentBlendDstAlpha = blendDstAlpha; |
|
|
| } |
|
|
| currentBlending = blending; |
| currentPremultipledAlpha = null; |
|
|
| } |
|
|
| function setMaterial( material, frontFaceCW ) { |
|
|
| material.side === DoubleSide |
| ? disable( gl.CULL_FACE ) |
| : enable( gl.CULL_FACE ); |
|
|
| var flipSided = ( material.side === BackSide ); |
| if ( frontFaceCW ) flipSided = ! flipSided; |
|
|
| setFlipSided( flipSided ); |
|
|
| ( material.blending === NormalBlending && material.transparent === false ) |
| ? setBlending( NoBlending ) |
| : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha ); |
|
|
| depthBuffer.setFunc( material.depthFunc ); |
| depthBuffer.setTest( material.depthTest ); |
| depthBuffer.setMask( material.depthWrite ); |
| colorBuffer.setMask( material.colorWrite ); |
|
|
| setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); |
|
|
| } |
|
|
| |
|
|
| function setFlipSided( flipSided ) { |
|
|
| if ( currentFlipSided !== flipSided ) { |
|
|
| if ( flipSided ) { |
|
|
| gl.frontFace( gl.CW ); |
|
|
| } else { |
|
|
| gl.frontFace( gl.CCW ); |
|
|
| } |
|
|
| currentFlipSided = flipSided; |
|
|
| } |
|
|
| } |
|
|
| function setCullFace( cullFace ) { |
|
|
| if ( cullFace !== CullFaceNone ) { |
|
|
| enable( gl.CULL_FACE ); |
|
|
| if ( cullFace !== currentCullFace ) { |
|
|
| if ( cullFace === CullFaceBack ) { |
|
|
| gl.cullFace( gl.BACK ); |
|
|
| } else if ( cullFace === CullFaceFront ) { |
|
|
| gl.cullFace( gl.FRONT ); |
|
|
| } else { |
|
|
| gl.cullFace( gl.FRONT_AND_BACK ); |
|
|
| } |
|
|
| } |
|
|
| } else { |
|
|
| disable( gl.CULL_FACE ); |
|
|
| } |
|
|
| currentCullFace = cullFace; |
|
|
| } |
|
|
| function setLineWidth( width ) { |
|
|
| if ( width !== currentLineWidth ) { |
|
|
| if ( lineWidthAvailable ) gl.lineWidth( width ); |
|
|
| currentLineWidth = width; |
|
|
| } |
|
|
| } |
|
|
| function setPolygonOffset( polygonOffset, factor, units ) { |
|
|
| if ( polygonOffset ) { |
|
|
| enable( gl.POLYGON_OFFSET_FILL ); |
|
|
| if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) { |
|
|
| gl.polygonOffset( factor, units ); |
|
|
| currentPolygonOffsetFactor = factor; |
| currentPolygonOffsetUnits = units; |
|
|
| } |
|
|
| } else { |
|
|
| disable( gl.POLYGON_OFFSET_FILL ); |
|
|
| } |
|
|
| } |
|
|
| function setScissorTest( scissorTest ) { |
|
|
| if ( scissorTest ) { |
|
|
| enable( gl.SCISSOR_TEST ); |
|
|
| } else { |
|
|
| disable( gl.SCISSOR_TEST ); |
|
|
| } |
|
|
| } |
|
|
| |
|
|
| function activeTexture( webglSlot ) { |
|
|
| if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1; |
|
|
| if ( currentTextureSlot !== webglSlot ) { |
|
|
| gl.activeTexture( webglSlot ); |
| currentTextureSlot = webglSlot; |
|
|
| } |
|
|
| } |
|
|
| function bindTexture( webglType, webglTexture ) { |
|
|
| if ( currentTextureSlot === null ) { |
|
|
| activeTexture(); |
|
|
| } |
|
|
| var boundTexture = currentBoundTextures[ currentTextureSlot ]; |
|
|
| if ( boundTexture === undefined ) { |
|
|
| boundTexture = { type: undefined, texture: undefined }; |
| currentBoundTextures[ currentTextureSlot ] = boundTexture; |
|
|
| } |
|
|
| if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) { |
|
|
| gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] ); |
|
|
| boundTexture.type = webglType; |
| boundTexture.texture = webglTexture; |
|
|
| } |
|
|
| } |
|
|
| function compressedTexImage2D() { |
|
|
| try { |
|
|
| gl.compressedTexImage2D.apply( gl, arguments ); |
|
|
| } catch ( error ) { |
|
|
| console.error( 'THREE.WebGLState:', error ); |
|
|
| } |
|
|
| } |
|
|
| function texImage2D() { |
|
|
| try { |
|
|
| gl.texImage2D.apply( gl, arguments ); |
|
|
| } catch ( error ) { |
|
|
| console.error( 'THREE.WebGLState:', error ); |
|
|
| } |
|
|
| } |
|
|
| function texImage3D() { |
|
|
| try { |
|
|
| gl.texImage3D.apply( gl, arguments ); |
|
|
| } catch ( error ) { |
|
|
| console.error( 'THREE.WebGLState:', error ); |
|
|
| } |
|
|
| } |
|
|
| |
|
|
| function scissor( scissor ) { |
|
|
| if ( currentScissor.equals( scissor ) === false ) { |
|
|
| gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w ); |
| currentScissor.copy( scissor ); |
|
|
| } |
|
|
| } |
|
|
| function viewport( viewport ) { |
|
|
| if ( currentViewport.equals( viewport ) === false ) { |
|
|
| gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w ); |
| currentViewport.copy( viewport ); |
|
|
| } |
|
|
| } |
|
|
| |
|
|
| function reset() { |
|
|
| for ( var i = 0; i < enabledAttributes.length; i ++ ) { |
|
|
| if ( enabledAttributes[ i ] === 1 ) { |
|
|
| gl.disableVertexAttribArray( i ); |
| enabledAttributes[ i ] = 0; |
|
|
| } |
|
|
| } |
|
|
| enabledCapabilities = {}; |
|
|
| compressedTextureFormats = null; |
|
|
| currentTextureSlot = null; |
| currentBoundTextures = {}; |
|
|
| currentProgram = null; |
|
|
| currentBlending = null; |
|
|
| currentFlipSided = null; |
| currentCullFace = null; |
|
|
| colorBuffer.reset(); |
| depthBuffer.reset(); |
| stencilBuffer.reset(); |
|
|
| } |
|
|
| return { |
|
|
| buffers: { |
| color: colorBuffer, |
| depth: depthBuffer, |
| stencil: stencilBuffer |
| }, |
|
|
| initAttributes: initAttributes, |
| enableAttribute: enableAttribute, |
| enableAttributeAndDivisor: enableAttributeAndDivisor, |
| disableUnusedAttributes: disableUnusedAttributes, |
| enable: enable, |
| disable: disable, |
| getCompressedTextureFormats: getCompressedTextureFormats, |
|
|
| useProgram: useProgram, |
|
|
| setBlending: setBlending, |
| setMaterial: setMaterial, |
|
|
| setFlipSided: setFlipSided, |
| setCullFace: setCullFace, |
|
|
| setLineWidth: setLineWidth, |
| setPolygonOffset: setPolygonOffset, |
|
|
| setScissorTest: setScissorTest, |
|
|
| activeTexture: activeTexture, |
| bindTexture: bindTexture, |
| compressedTexImage2D: compressedTexImage2D, |
| texImage2D: texImage2D, |
| texImage3D: texImage3D, |
|
|
| scissor: scissor, |
| viewport: viewport, |
|
|
| reset: reset |
|
|
| }; |
|
|
| } |
|
|
|
|
| export { WebGLState }; |
|
|