Explorar el Código

WebGLRenderer: Basic support for webgl context lost. See #11435

Mr.doob hace 8 años
padre
commit
da7b874db1
Se han modificado 2 ficheros con 70 adiciones y 64 borrados
  1. 58 49
      src/renderers/WebGLRenderer.js
  2. 12 15
      src/renderers/webgl/WebGLState.js

+ 58 - 49
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 = '';

+ 12 - 15
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,