diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 7ef6e276e261e8..d7f52e45e533a3 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -720,6 +720,12 @@ Object.assign( Object3D.prototype, EventDispatcher.prototype, { return this; + }, + + dispose: function () { + + this.dispatchEvent( { type: 'dispose' } ); + } } ); diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index ec3c6cc867cf7f..49865b4ab40065 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -57,10 +57,8 @@ function WebGLRenderer( parameters ) { var lights = []; - var opaqueObjects = []; - var opaqueObjectsLastIndex = - 1; - var transparentObjects = []; - var transparentObjectsLastIndex = - 1; + var opaqueObjects = null; + var transparentObjects = null; var morphInfluences = new Float32Array( 8 ); @@ -546,10 +544,8 @@ function WebGLRenderer( parameters ) { this.dispose = function() { - transparentObjects = []; - transparentObjectsLastIndex = -1; - opaqueObjects = []; - opaqueObjectsLastIndex = -1; + opaqueObjects = null; + transparentObjects = null; _canvas.removeEventListener( 'webglcontextlost', onContextLost, false ); @@ -603,6 +599,16 @@ function WebGLRenderer( parameters ) { } + function onSceneDispose( event ) { + + var scene = event.target; + + scene.removeEventListener( 'dispose', onSceneDispose ); + + properties.delete( scene ); + + } + // Buffer rendering this.renderBufferImmediate = function ( object, program, material ) { @@ -1148,8 +1154,22 @@ function WebGLRenderer( parameters ) { lights.length = 0; - opaqueObjectsLastIndex = - 1; - transparentObjectsLastIndex = - 1; + var sceneProperties = properties.get( scene ); + + if ( sceneProperties.opaqueRenderList === undefined ) { + + sceneProperties.opaqueRenderList = []; + sceneProperties.transparentRenderList = []; + + scene.addEventListener( 'dispose', onSceneDispose ); + + } + + opaqueObjects = sceneProperties.opaqueRenderList; + transparentObjects = sceneProperties.transparentRenderList; + + opaqueObjects.liveEntries = 0; + transparentObjects.liveEntries = 0; sprites.length = 0; lensFlares.length = 0; @@ -1159,8 +1179,8 @@ function WebGLRenderer( parameters ) { projectObject( scene, camera ); - opaqueObjects.length = opaqueObjectsLastIndex + 1; - transparentObjects.length = transparentObjectsLastIndex + 1; + opaqueObjects.length = opaqueObjects.liveEntries; + transparentObjects.length = transparentObjects.liveEntries; if ( _this.sortObjects === true ) { @@ -1288,25 +1308,23 @@ function WebGLRenderer( parameters ) { function pushRenderItem( object, geometry, material, z, group ) { - var array, index; + var array; // allocate the next position in the appropriate array if ( material.transparent ) { array = transparentObjects; - index = ++ transparentObjectsLastIndex; } else { array = opaqueObjects; - index = ++ opaqueObjectsLastIndex; } // recycle existing render item or grow the array - var renderItem = array[ index ]; + var renderItem = array[ array.liveEntries ++ ]; if ( renderItem !== undefined ) {