diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index a4e906a2d56306bb60e2bd192501f5edce06a06a..1decec4b7cb54530786d57ed0dcb0e12fd2b5dfb 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -110,6 +110,8 @@ function WebGLRenderer( parameters ) { var _this = this, + _isContextLost = false, + // internal state cache _currentRenderTarget = null, @@ -252,6 +254,7 @@ function WebGLRenderer( parameters ) { } _canvas.addEventListener( 'webglcontextlost', onContextLost, false ); + _canvas.addEventListener( 'webglcontextrestored', onContextRestore, false ); } catch ( error ) { @@ -259,73 +262,65 @@ function WebGLRenderer( parameters ) { } - var extensions = new WebGLExtensions( _gl ); - - extensions.get( 'WEBGL_depth_texture' ); - extensions.get( 'OES_texture_float' ); - extensions.get( 'OES_texture_float_linear' ); - extensions.get( 'OES_texture_half_float' ); - extensions.get( 'OES_texture_half_float_linear' ); - extensions.get( 'OES_standard_derivatives' ); - extensions.get( 'ANGLE_instanced_arrays' ); + var extensions, capabilities, state; + var properties, textures, attributes, geometries, objects; + var programCache, lightCache, renderLists; - if ( extensions.get( 'OES_element_index_uint' ) ) { + var background, bufferRenderer, indexedBufferRenderer; - BufferGeometry.MaxIndex = 4294967296; + function initGLContext() { - } + extensions = new WebGLExtensions( _gl ); + extensions.get( 'WEBGL_depth_texture' ); + extensions.get( 'OES_texture_float' ); + extensions.get( 'OES_texture_float_linear' ); + extensions.get( 'OES_texture_half_float' ); + extensions.get( 'OES_texture_half_float_linear' ); + extensions.get( 'OES_standard_derivatives' ); + extensions.get( 'ANGLE_instanced_arrays' ); - var capabilities = new WebGLCapabilities( _gl, extensions, parameters ); + if ( extensions.get( 'OES_element_index_uint' ) ) { - var state = new WebGLState( _gl, extensions, paramThreeToGL ); + BufferGeometry.MaxIndex = 4294967296; - var properties = new WebGLProperties(); - var textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, _infoMemory ); - var attributes = new WebGLAttributes( _gl ); - var geometries = new WebGLGeometries( _gl, attributes, _infoMemory ); - var objects = new WebGLObjects( _gl, geometries, _infoRender ); - var programCache = new WebGLPrograms( this, capabilities ); - var lightCache = new WebGLLights(); - var renderLists = new WebGLRenderLists(); + } - var background = new WebGLBackground( this, state, objects, _premultipliedAlpha ); - var vr = new WebVRManager( this ); + capabilities = new WebGLCapabilities( _gl, extensions, parameters ); - this.info.programs = programCache.programs; + state = new WebGLState( _gl, extensions, paramThreeToGL ); + state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) ); + state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) ); - var bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender ); - var indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender ); + properties = new WebGLProperties(); + textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, _infoMemory ); + attributes = new WebGLAttributes( _gl ); + geometries = new WebGLGeometries( _gl, attributes, _infoMemory ); + objects = new WebGLObjects( _gl, geometries, _infoRender ); + programCache = new WebGLPrograms( _this, capabilities ); + lightCache = new WebGLLights(); + renderLists = new WebGLRenderLists(); - // + background = new WebGLBackground( _this, state, objects, _premultipliedAlpha ); - function getTargetPixelRatio() { + bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender ); + indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender ); - return _currentRenderTarget === null ? _pixelRatio : 1; + _this.info.programs = programCache.programs; } - function setDefaultGLState() { - - state.init(); - - state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) ); - state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) ); - - } + initGLContext(); - function resetGLState() { + var vr = new WebVRManager( _this ); - _currentCamera = null; + // - _currentGeometryProgram = ''; - _currentMaterialId = - 1; + function getTargetPixelRatio() { - state.reset(); + return _currentRenderTarget === null ? _pixelRatio : 1; } - setDefaultGLState(); - this.context = _gl; this.capabilities = capabilities; this.extensions = extensions; @@ -367,6 +362,13 @@ function WebGLRenderer( parameters ) { }; + this.forceContextRestore = function () { + + var extension = extensions.get( 'WEBGL_lose_context' ); + if ( extension ) extension.restoreContext(); + + }; + this.getMaxAnisotropy = function () { return capabilities.getMaxAnisotropy(); @@ -524,6 +526,7 @@ function WebGLRenderer( parameters ) { this.dispose = function () { _canvas.removeEventListener( 'webglcontextlost', onContextLost, false ); + _canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false ); renderLists.dispose(); @@ -535,11 +538,15 @@ function WebGLRenderer( parameters ) { event.preventDefault(); - resetGLState(); - setDefaultGLState(); + _isContextLost = true; + + } + + function onContextRestore( event ) { - properties.clear(); - objects.clear(); + initGLContext(); + + _isContextLost = false; } @@ -1098,6 +1105,8 @@ function WebGLRenderer( parameters ) { } + if ( _isContextLost ) return; + // reset caching for this frame _currentGeometryProgram = ''; diff --git a/src/renderers/webgl/WebGLState.js b/src/renderers/webgl/WebGLState.js index c7e37098bfb106ebfea980ffdc65e52d32d23fd8..31fe6237488466e908fb9625e34f0a3c23009361 100644 --- a/src/renderers/webgl/WebGLState.js +++ b/src/renderers/webgl/WebGLState.js @@ -376,25 +376,23 @@ function WebGLState( gl, extensions, paramThreeToGL ) { 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 ); - // - - function init() { + // init - colorBuffer.setClear( 0, 0, 0, 1 ); - depthBuffer.setClear( 1 ); - stencilBuffer.setClear( 0 ); + colorBuffer.setClear( 0, 0, 0, 1 ); + depthBuffer.setClear( 1 ); + stencilBuffer.setClear( 0 ); - enable( gl.DEPTH_TEST ); - depthBuffer.setFunc( LessEqualDepth ); + enable( gl.DEPTH_TEST ); + depthBuffer.setFunc( LessEqualDepth ); - setFlipSided( false ); - setCullFace( CullFaceBack ); - enable( gl.CULL_FACE ); + setFlipSided( false ); + setCullFace( CullFaceBack ); + enable( gl.CULL_FACE ); - enable( gl.BLEND ); - setBlending( NormalBlending ); + enable( gl.BLEND ); + setBlending( NormalBlending ); - } + // function initAttributes() { @@ -917,7 +915,6 @@ function WebGLState( gl, extensions, paramThreeToGL ) { stencil: stencilBuffer }, - init: init, initAttributes: initAttributes, enableAttribute: enableAttribute, enableAttributeAndDivisor: enableAttributeAndDivisor,