Browse Source

Added class WebGLProperties, webgl properties now stored in that class. Checks for uuids and existance of properties encapsulated in this class

Fordy 10 years ago
parent
commit
82837942e1

+ 1 - 1
examples/index.html

@@ -313,7 +313,7 @@
 				"webgl_multiple_canvases_complex",
 				"webgl_multiple_canvases_complex",
 				"webgl_multiple_canvases_grid",
 				"webgl_multiple_canvases_grid",
 				"webgl_multiple_elements",
 				"webgl_multiple_elements",
-				"webgl_multiple_renderers_complex",
+				"webgl_multiple_renderers",
 				"webgl_multiple_views",
 				"webgl_multiple_views",
 				"webgl_nearestneighbour",
 				"webgl_nearestneighbour",
 				"webgl_octree",
 				"webgl_octree",

+ 301 - 0
examples/webgl_multiple_renderers.html

@@ -0,0 +1,301 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - multiple Renderers - complex</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				color: #808080;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+
+				background-color: #fff;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				padding: 5px;
+			}
+
+			#container1, #container2, #container3 {
+				position: absolute;
+				border-style: solid;
+			}
+
+			#container1 {
+				width: 400px;
+				height: 200px;
+				left: 150px;
+			}
+
+			#container2 {
+				width: 400px;
+				height: 200px;
+				left: 150px;
+				top: 400px;
+			}
+
+			#container3 {
+				width: 300px;
+				height: 300px;
+				left: 75px;
+				top: 300px;
+  				box-shadow: 0px 0px 100px 0px #000;
+			}
+
+			a {
+
+				color: #0080ff;
+			}
+
+		</style>
+	</head>
+	<body>
+
+		<div id="container">
+			<div id="container1"></div>
+			<div id="container2"></div>
+			<div id="container3"></div>
+		</div>
+		<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> webgl - multiple canvases - complex</div>
+
+		<script src="../build/three.min.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var apps = [];
+
+			var scene = createScene();
+
+			init();
+			animate();
+
+			function init() {
+
+				var container1 = document.getElementById( 'container1' );
+				var container2 = document.getElementById( 'container2' );
+				var container3 = document.getElementById( 'container3' );
+
+				var WIDTH = 800;
+				var HEIGHT = 600;
+
+				apps.push( new App( container1, WIDTH, HEIGHT ) );
+				apps.push( new App( container2, WIDTH, HEIGHT ) );
+				apps.push( new App( container3, WIDTH, HEIGHT ) );
+
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+
+			}
+
+			function animate() {
+
+				for ( var i = 0; i < apps.length; ++i ) {
+
+					apps[ i ].animate();
+
+				}
+
+				requestAnimationFrame( animate );
+
+			}
+
+			function onDocumentMouseMove (e) {
+
+				var container3 = document.getElementById( 'container3' );
+
+				container3.style.left = e.pageX - container3.clientWidth / 2 + "px"
+				container3.style.top = e.pageY - container3.clientHeight / 2 + "px"
+
+			}
+
+			function createScene () {
+
+				var mesh, group1, group2, group3, light;
+
+				scene = new THREE.Scene();
+
+				light = new THREE.DirectionalLight( 0xffffff );
+				light.position.set( 0, 0, 1 ).normalize();
+				scene.add( light );
+
+				// shadow
+
+				var canvas = document.createElement( 'canvas' );
+				canvas.width = 128;
+				canvas.height = 128;
+
+				var context = canvas.getContext( '2d' );
+				var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );
+				gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
+				gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
+
+				context.fillStyle = gradient;
+				context.fillRect( 0, 0, canvas.width, canvas.height );
+
+				var shadowTexture = new THREE.Texture( canvas );
+				shadowTexture.needsUpdate = true;
+
+				var shadowMaterial = new THREE.MeshBasicMaterial( { map: shadowTexture } );
+				var shadowGeo = new THREE.PlaneBufferGeometry( 300, 300, 1, 1 );
+
+				mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
+				mesh.position.y = - 250;
+				mesh.rotation.x = - Math.PI / 2;
+				scene.add( mesh );
+
+				mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
+				mesh.position.x = - 400;
+				mesh.position.y = - 250;
+				mesh.rotation.x = - Math.PI / 2;
+				scene.add( mesh );
+
+				mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
+				mesh.position.x = 400;
+				mesh.position.y = - 250;
+				mesh.rotation.x = - Math.PI / 2;
+				scene.add( mesh );
+
+				var faceIndices = [ 'a', 'b', 'c' ];
+
+				var color, f1, f2, f3, p, vertexIndex,
+
+					radius = 200,
+
+					geometry1 = new THREE.IcosahedronGeometry( radius, 1 ),
+					geometry2 = new THREE.IcosahedronGeometry( radius, 1 ),
+					geometry3 = new THREE.IcosahedronGeometry( radius, 1 );
+
+				for ( var i = 0; i < geometry1.faces.length; i ++ ) {
+
+					f1 = geometry1.faces[ i ];
+					f2 = geometry2.faces[ i ];
+					f3 = geometry3.faces[ i ];
+
+					for( var j = 0; j < 3; j ++ ) {
+
+						vertexIndex = f1[ faceIndices[ j ] ];
+
+						p = geometry1.vertices[ vertexIndex ];
+
+						color = new THREE.Color( 0xffffff );
+						color.setHSL( ( p.y / radius + 1 ) / 2, 1.0, 0.5 );
+
+						f1.vertexColors[ j ] = color;
+
+						color = new THREE.Color( 0xffffff );
+						color.setHSL( 0.0, ( p.y / radius + 1 ) / 2, 0.5 );
+
+						f2.vertexColors[ j ] = color;
+
+						color = new THREE.Color( 0xffffff );
+						color.setHSL( 0.125 * vertexIndex / geometry1.vertices.length, 1.0, 0.5 );
+
+						f3.vertexColors[ j ] = color;
+
+					}
+
+				}
+
+				var materials = [
+
+					new THREE.MeshLambertMaterial( { color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors } ),
+					new THREE.MeshBasicMaterial( { color: 0x000000, shading: THREE.FlatShading, wireframe: true, transparent: true } )
+
+				];
+
+				group1 = THREE.SceneUtils.createMultiMaterialObject( geometry1, materials );
+				group1.position.x = -400;
+				group1.rotation.x = -1.87;
+				scene.add( group1 );
+
+				group2 = THREE.SceneUtils.createMultiMaterialObject( geometry2, materials );
+				group2.position.x = 400;
+				group2.rotation.x = 0;
+				scene.add( group2 );
+
+				group3 = THREE.SceneUtils.createMultiMaterialObject( geometry3, materials );
+				group3.position.x = 0;
+				group3.rotation.x = 0;
+				scene.add( group3 );
+
+				return scene;
+			}
+
+			function App( container, fullWidth, fullHeight ) {
+
+				var container, stats;
+
+				var camera, renderer;
+
+				var mouseX = 0, mouseY = 0;
+
+				var windowHalfX = window.innerWidth / 2;
+				var windowHalfY = window.innerHeight / 2;
+
+				init();
+
+				function init() {
+
+					camera = new THREE.PerspectiveCamera( 20, container.clientWidth / container.clientHeight, 1, 10000 );
+					camera.setViewOffset( fullWidth, fullHeight, container.offsetLeft, container.offsetTop, container.clientWidth, container.clientHeight );
+					camera.position.z = 1800;
+
+					renderer = new THREE.WebGLRenderer( { antialias: true } );
+					renderer.setClearColor( 0xffffff );
+					renderer.setPixelRatio( window.devicePixelRatio );
+					renderer.setSize( container.clientWidth, container.clientHeight );
+					container.appendChild( renderer.domElement );
+
+					stats = new Stats();
+					stats.domElement.style.position = 'absolute';
+					stats.domElement.style.top = '0px';
+					container.appendChild( stats.domElement );
+
+					document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+
+				}
+
+				function onDocumentMouseMove( event ) {
+
+					mouseX = ( event.clientX - windowHalfX );
+					mouseY = ( event.clientY - windowHalfY );
+
+				}
+
+				//
+
+				this.animate = function() {
+
+					render();
+					stats.update();
+
+				};
+
+				function render() {
+
+					camera.setViewOffset( fullWidth, fullHeight, container.offsetLeft, container.offsetTop, container.clientWidth, container.clientHeight );
+
+					camera.position.x += ( -mouseX - camera.position.x ) * 0.5;
+					camera.position.y += ( - mouseY - camera.position.y ) * 0.5;
+
+					camera.lookAt( scene.position );
+
+					renderer.render( scene, camera );
+
+				}
+			}
+
+		</script>
+
+	</body>
+</html>

+ 6 - 0
src/core/BufferGeometry.js

@@ -40,6 +40,12 @@ THREE.BufferGeometry.prototype = {
 
 
 		}
 		}
 
 
+		if ( ! attribute.uuid ) {
+
+			attribute.uuid = THREE.Math.generateUUID();
+
+		}
+
 		this.attributes[ name ] = attribute;
 		this.attributes[ name ] = attribute;
 
 
 	},
 	},

+ 83 - 150
src/renderers/WebGLRenderer.js

@@ -32,10 +32,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 	_clearColor = new THREE.Color( 0x000000 ),
 	_clearColor = new THREE.Color( 0x000000 ),
 	_clearAlpha = 0;
 	_clearAlpha = 0;
 
 
-	// tracks context specific properties to allow sharing of objects across webgl renderers
-	// each object stores relevant webgl properties that are specific to this renderer
-	// objects are stored by their uuids
-	var objectRendererWebGLProps = {};
+	var webGLProps = new THREE.WebGLProperties();
 
 
 	var lights = [];
 	var lights = [];
 
 
@@ -645,56 +642,60 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	var deallocateTexture = function ( texture ) {
 	var deallocateTexture = function ( texture ) {
 
 
-		if ( texture.image && objectRendererWebGLProps[texture.uuid].__image__webglTextureCube ) {
+		var textureWebGLProperties = webGLProps.getProperties( texture );
+
+		if ( texture.image && textureWebGLProperties.__image__webglTextureCube ) {
 
 
 			// cube texture
 			// cube texture
 
 
-			_gl.deleteTexture( objectRendererWebGLProps[texture.uuid].__image__webglTextureCube );
+			_gl.deleteTexture( textureWebGLProperties.__image__webglTextureCube );
 
 
 		} else {
 		} else {
 
 
 			// 2D texture
 			// 2D texture
 
 
-			if ( objectRendererWebGLProps[texture.uuid].__webglInit === undefined ) return;
+			if ( textureWebGLProperties.__webglInit === undefined ) return;
 
 
-			_gl.deleteTexture( objectRendererWebGLProps[texture.uuid].__webglTexture );
+			_gl.deleteTexture( textureWebGLProperties.__webglTexture );
 
 
 		}
 		}
 
 
-		// remove all webgl props at once
-		delete objectRendererWebGLProps[texture.uuid];
+		// remove all webgl properties
+		delete webGLProps.deleteProperties( texture );
 
 
 	};
 	};
 
 
 	var deallocateRenderTarget = function ( renderTarget ) {
 	var deallocateRenderTarget = function ( renderTarget ) {
 
 
-		if ( ! renderTarget || objectRendererWebGLProps[renderTarget.uuid].__webglTexture === undefined ) return;
+		var renderTargetWebGLProperties = webGLProps.getProperties( renderTarget );
+
+		if ( ! renderTarget || renderTargetWebGLProperties.__webglTexture === undefined ) return;
 
 
-		_gl.deleteTexture( objectRendererWebGLProps[renderTarget.uuid].__webglTexture );
+		_gl.deleteTexture( renderTargetWebGLProperties.__webglTexture );
 
 
 		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
 		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
 
 
 			for ( var i = 0; i < 6; i ++ ) {
 			for ( var i = 0; i < 6; i ++ ) {
 
 
-				_gl.deleteFramebuffer( objectRendererWebGLProps[renderTarget.uuid].__webglFramebuffer[ i ] );
-				_gl.deleteRenderbuffer( objectRendererWebGLProps[renderTarget.uuid].__webglRenderbuffer[ i ] );
+				_gl.deleteFramebuffer( renderTargetWebGLProperties.__webglFramebuffer[ i ] );
+				_gl.deleteRenderbuffer( renderTargetWebGLProperties.__webglRenderbuffer[ i ] );
 
 
 			}
 			}
 
 
 		} else {
 		} else {
 
 
-			_gl.deleteFramebuffer( objectRendererWebGLProps[renderTarget.uuid].__webglFramebuffer );
-			_gl.deleteRenderbuffer( objectRendererWebGLProps[renderTarget.uuid].__webglRenderbuffer );
+			_gl.deleteFramebuffer( renderTargetWebGLProperties.__webglFramebuffer );
+			_gl.deleteRenderbuffer( renderTargetWebGLProperties.__webglRenderbuffer );
 
 
 		}
 		}
 
 
-		delete objectRendererWebGLProps[renderTarget.uuid];
+		delete webGLProps.deleteProperties( renderTargetWebGLProperties );
 
 
 	};
 	};
 
 
 	var deallocateMaterial = function ( material ) {
 	var deallocateMaterial = function ( material ) {
 
 
-		var program = objectRendererWebGLProps[material.uuid].program.program;
+		var program = webGLProps.getProperties( material ).program.program;
 
 
 		if ( program === undefined ) return;
 		if ( program === undefined ) return;
 
 
@@ -753,7 +754,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		}
 		}
 
 
-		delete objectRendererWebGLProps[material.uuid];
+		delete webGLProps.deleteProperties( material );
 
 
 	};
 	};
 
 
@@ -763,13 +764,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		state.initAttributes();
 		state.initAttributes();
 
 
-		if ( ! objectRendererWebGLProps[object.uuid] ) {
-
-			objectRendererWebGLProps[object.uuid] = {};
-
-		}
-
-		var webglProps = objectRendererWebGLProps[object.uuid];
+		var webglProps = webGLProps.getProperties( object );
 
 
 		if ( object.hasPositions && ! webglProps.__webglVertexBuffer ) webglProps.__webglVertexBuffer = _gl.createBuffer();
 		if ( object.hasPositions && ! webglProps.__webglVertexBuffer ) webglProps.__webglVertexBuffer = _gl.createBuffer();
 		if ( object.hasNormals && ! webglProps.__webglNormalBuffer ) webglProps.__webglNormalBuffer = _gl.createBuffer();
 		if ( object.hasNormals && ! webglProps.__webglNormalBuffer ) webglProps.__webglNormalBuffer = _gl.createBuffer();
@@ -1370,7 +1365,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			var type, size;
 			var type, size;
 
 
-			var indexBuffer = objects.getAttributeBuffer(indexBuffer);
+			var indexBuffer = objects.getAttributeBuffer( index );
 
 
 			if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
 			if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
 
 
@@ -1695,9 +1690,9 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 						var material = object.material;
 						var material = object.material;
 
 
-						if ( objectRendererWebGLProps[material.uuid] ) {
+						if ( webGLProps.getProperties( material ) ) {
 
 
-							material.program = objectRendererWebGLProps[material.uuid].program;
+							material.program = webGLProps.getProperties( material ).program;
 
 
 						}
 						}
 
 
@@ -1826,13 +1821,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	function initMaterial( material, lights, fog, object ) {
 	function initMaterial( material, lights, fog, object ) {
 
 
-		if ( ! objectRendererWebGLProps[material.uuid] ) {
-
-			objectRendererWebGLProps[material.uuid] = {};
-
-		}
-
-		var webglProps = objectRendererWebGLProps[material.uuid];
+		var materialWebGLProperties = webGLProps.getProperties( material );
 
 
 		var shaderID = shaderIDs[ material.type ];
 		var shaderID = shaderIDs[ material.type ];
 
 
@@ -1934,12 +1923,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		var code = chunks.join();
 		var code = chunks.join();
 
 
-		if ( !webglProps.program ) {
+		if ( !materialWebGLProperties.program ) {
 
 
 			// new material
 			// new material
 			material.addEventListener( 'dispose', onMaterialDispose );
 			material.addEventListener( 'dispose', onMaterialDispose );
 
 
-		} else if ( webglProps.program.code !== code ) {
+		} else if ( materialWebGLProperties.program.code !== code ) {
 
 
 			// changed glsl or parameters
 			// changed glsl or parameters
 			deallocateMaterial( material );
 			deallocateMaterial( material );
@@ -1949,7 +1938,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			// same glsl
 			// same glsl
 			return;
 			return;
 
 
-		} else if ( webglProps.__webglShader.uniforms === material.uniforms ) {
+		} else if ( materialWebGLProperties.__webglShader.uniforms === material.uniforms ) {
 
 
 			// same uniforms (container object)
 			// same uniforms (container object)
 			return;
 			return;
@@ -1960,7 +1949,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			var shader = THREE.ShaderLib[ shaderID ];
 			var shader = THREE.ShaderLib[ shaderID ];
 
 
-			webglProps.__webglShader = {
+			materialWebGLProperties.__webglShader = {
 				name: material.type,
 				name: material.type,
 				uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
 				uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
 				vertexShader: shader.vertexShader,
 				vertexShader: shader.vertexShader,
@@ -1969,7 +1958,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		} else {
 		} else {
 
 
-			webglProps.__webglShader = {
+			materialWebGLProperties.__webglShader = {
 				name: material.type,
 				name: material.type,
 				uniforms: material.uniforms,
 				uniforms: material.uniforms,
 				vertexShader: material.vertexShader,
 				vertexShader: material.vertexShader,
@@ -1999,7 +1988,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		if ( program === undefined ) {
 		if ( program === undefined ) {
 
 
-			material.__webglShader = webglProps.__webglShader;
+			material.__webglShader = materialWebGLProperties.__webglShader;
 			program = new THREE.WebGLProgram( _this, code, material, parameters );
 			program = new THREE.WebGLProgram( _this, code, material, parameters );
 			_programs.push( program );
 			_programs.push( program );
 
 
@@ -2007,7 +1996,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		}
 		}
 
 
-		webglProps.program = program;
+		materialWebGLProperties.program = program;
 
 
 		var attributes = program.getAttributes();
 		var attributes = program.getAttributes();
 
 
@@ -2043,15 +2032,15 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		}
 		}
 
 
-		webglProps.uniformsList = [];
+		materialWebGLProperties.uniformsList = [];
 
 
-		var uniformLocations = webglProps.program.getUniforms();
-		for ( var u in webglProps.__webglShader.uniforms ) {
+		var uniformLocations = materialWebGLProperties.program.getUniforms();
+		for ( var u in materialWebGLProperties.__webglShader.uniforms ) {
 
 
 			var location = uniformLocations[ u ];
 			var location = uniformLocations[ u ];
 
 
 			if ( location ) {
 			if ( location ) {
-				webglProps.uniformsList.push( [ webglProps.__webglShader.uniforms[ u ], location ] );
+				materialWebGLProperties.uniformsList.push( [ materialWebGLProperties.__webglShader.uniforms[ u ], location ] );
 			}
 			}
 
 
 		}
 		}
@@ -2091,15 +2080,9 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		_usedTextureUnits = 0;
 		_usedTextureUnits = 0;
 
 
-		if ( ! objectRendererWebGLProps[material.uuid] ) {
-
-			objectRendererWebGLProps[material.uuid] = {};
-			// need to reinitialize material for this renderer if from different renderer
-			material.needsUpdate = true;
-
-		}
+		var materialWebGLProperties = webGLProps.getProperties( material );
 
 
-		if ( material.needsUpdate ) {
+		if ( material.needsUpdate || ! materialWebGLProperties.program ) {
 
 
 			initMaterial( material, lights, fog, object );
 			initMaterial( material, lights, fog, object );
 			material.needsUpdate = false;
 			material.needsUpdate = false;
@@ -2110,9 +2093,9 @@ THREE.WebGLRenderer = function ( parameters ) {
 		var refreshMaterial = false;
 		var refreshMaterial = false;
 		var refreshLights = false;
 		var refreshLights = false;
 
 
-		var program = objectRendererWebGLProps[material.uuid].program,
+		var program = materialWebGLProperties.program,
 			p_uniforms = program.getUniforms(),
 			p_uniforms = program.getUniforms(),
-			m_uniforms = objectRendererWebGLProps[material.uuid].__webglShader.uniforms;
+			m_uniforms = materialWebGLProperties.__webglShader.uniforms;
 
 
 		if ( program.id !== _currentProgram ) {
 		if ( program.id !== _currentProgram ) {
 
 
@@ -2317,7 +2300,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			// load common uniforms
 			// load common uniforms
 
 
-			loadUniformsGeneric( objectRendererWebGLProps[material.uuid].uniformsList );
+			loadUniformsGeneric( materialWebGLProperties.uniformsList );
 
 
 		}
 		}
 
 
@@ -3192,12 +3175,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
 	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
 
 
-		if ( ! objectRendererWebGLProps[texture.uuid] ) {
-
-			objectRendererWebGLProps[texture.uuid] = {};
-
-		}
-
 		var extension;
 		var extension;
 
 
 		if ( isImagePowerOfTwo ) {
 		if ( isImagePowerOfTwo ) {
@@ -3234,10 +3211,10 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		if ( extension && texture.type !== THREE.FloatType && texture.type !== THREE.HalfFloatType ) {
 		if ( extension && texture.type !== THREE.FloatType && texture.type !== THREE.HalfFloatType ) {
 
 
-			if ( texture.anisotropy > 1 || objectRendererWebGLProps[texture.uuid].__currentAnisotropy ) {
+			if ( texture.anisotropy > 1 || webGLProps.getProperties( texture ).__currentAnisotropy ) {
 
 
 				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
 				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
-				objectRendererWebGLProps[texture.uuid].__currentAnisotropy = texture.anisotropy;
+				webGLProps.getProperties( texture ).__currentAnisotropy = texture.anisotropy;
 
 
 			}
 			}
 
 
@@ -3247,28 +3224,24 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	this.uploadTexture = function ( texture, slot ) {
 	this.uploadTexture = function ( texture, slot ) {
 
 
-		if ( ! objectRendererWebGLProps[texture.uuid] ) {
-
-			objectRendererWebGLProps[texture.uuid] = {};
+		var textureWebGLProperties = webGLProps.getProperties( texture );
 
 
-		}
-
-		if ( objectRendererWebGLProps[texture.uuid].__webglInit === undefined ) {
+		if ( textureWebGLProperties.__webglInit === undefined ) {
 
 
-			objectRendererWebGLProps[texture.uuid].__webglInit = true;
+			textureWebGLProperties.__webglInit = true;
 
 
 			texture.__webglInit = true;
 			texture.__webglInit = true;
 
 
 			texture.addEventListener( 'dispose', onTextureDispose );
 			texture.addEventListener( 'dispose', onTextureDispose );
 
 
-			objectRendererWebGLProps[texture.uuid].__webglTexture = _gl.createTexture();
+			textureWebGLProperties.__webglTexture = _gl.createTexture();
 
 
 			_this.info.memory.textures ++;
 			_this.info.memory.textures ++;
 
 
 		}
 		}
 
 
 		state.activeTexture( _gl.TEXTURE0 + slot );
 		state.activeTexture( _gl.TEXTURE0 + slot );
-		state.bindTexture( _gl.TEXTURE_2D, objectRendererWebGLProps[texture.uuid].__webglTexture );
+		state.bindTexture( _gl.TEXTURE_2D, textureWebGLProperties.__webglTexture );
 
 
 		_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
 		_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
 		_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
 		_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
@@ -3369,14 +3342,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	this.setTexture = function ( texture, slot ) {
 	this.setTexture = function ( texture, slot ) {
 
 
-		if ( ! objectRendererWebGLProps[texture.uuid] ) {
-
-			objectRendererWebGLProps[texture.uuid] = {};
-
-		}
-
 		// if the image has been uploaded into a separate renderer, will need to reupload to this renderer
 		// if the image has been uploaded into a separate renderer, will need to reupload to this renderer
-		if ( ( texture.image && texture.image.complete !== false ) && texture.__webglInit === true && objectRendererWebGLProps[texture.uuid].__webglInit === undefined ) {
+		if ( ( texture.image && texture.image.complete !== false ) && texture.__webglInit === true && webGLProps.getProperties( texture ).__webglInit === undefined ) {
 
 
 			texture.needsUpdate = true;
 			texture.needsUpdate = true;
 
 
@@ -3406,7 +3373,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		}
 		}
 
 
 		state.activeTexture( _gl.TEXTURE0 + slot );
 		state.activeTexture( _gl.TEXTURE0 + slot );
-		state.bindTexture( _gl.TEXTURE_2D, objectRendererWebGLProps[texture.uuid].__webglTexture );
+		state.bindTexture( _gl.TEXTURE_2D, webGLProps.getProperties( texture ).__webglTexture );
 
 
 	};
 	};
 
 
@@ -3438,28 +3405,24 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	function setCubeTexture ( texture, slot ) {
 	function setCubeTexture ( texture, slot ) {
 
 
-		if ( ! objectRendererWebGLProps[texture.uuid] ) {
-
-			objectRendererWebGLProps[texture.uuid] = {};
-
-		}
+		var textureWebGLProperties = webGLProps.getProperties( texture );
 
 
 		if ( texture.image.length === 6 ) {
 		if ( texture.image.length === 6 ) {
 
 
 			if ( texture.needsUpdate ) {
 			if ( texture.needsUpdate ) {
 
 
-				if ( ! objectRendererWebGLProps[texture.uuid].__image__webglTextureCube ) {
+				if ( ! textureWebGLProperties.__image__webglTextureCube ) {
 
 
 					texture.addEventListener( 'dispose', onTextureDispose );
 					texture.addEventListener( 'dispose', onTextureDispose );
 
 
-					objectRendererWebGLProps[texture.uuid].__image__webglTextureCube = _gl.createTexture();
+					textureWebGLProperties.__image__webglTextureCube = _gl.createTexture();
 
 
 					_this.info.memory.textures ++;
 					_this.info.memory.textures ++;
 
 
 				}
 				}
 
 
 				state.activeTexture( _gl.TEXTURE0 + slot );
 				state.activeTexture( _gl.TEXTURE0 + slot );
-				state.bindTexture( _gl.TEXTURE_CUBE_MAP, objectRendererWebGLProps[texture.uuid].__image__webglTextureCube );
+				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureWebGLProperties.__image__webglTextureCube );
 
 
 				_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
 				_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
 
 
@@ -3548,7 +3511,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			} else {
 			} else {
 
 
 				state.activeTexture( _gl.TEXTURE0 + slot );
 				state.activeTexture( _gl.TEXTURE0 + slot );
-				state.bindTexture( _gl.TEXTURE_CUBE_MAP, objectRendererWebGLProps[texture.uuid].__image__webglTextureCube );
+				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureWebGLProperties.__image__webglTextureCube );
 
 
 			}
 			}
 
 
@@ -3558,14 +3521,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	function setCubeTextureDynamic ( texture, slot ) {
 	function setCubeTextureDynamic ( texture, slot ) {
 
 
-		if ( ! objectRendererWebGLProps[texture.uuid] ) {
-
-			objectRendererWebGLProps[texture.uuid] = {};
-
-		}
-
 		state.activeTexture( _gl.TEXTURE0 + slot );
 		state.activeTexture( _gl.TEXTURE0 + slot );
-		state.bindTexture( _gl.TEXTURE_CUBE_MAP, objectRendererWebGLProps[texture.uuid].__webglTexture );
+		state.bindTexture( _gl.TEXTURE_CUBE_MAP, webGLProps.getProperties( texture ).__webglTexture );
 
 
 	}
 	}
 
 
@@ -3573,14 +3530,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
 	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
 
 
-		if ( ! objectRendererWebGLProps[renderTarget.uuid] ) {
-
-			objectRendererWebGLProps[renderTarget.uuid] = {};
-
-		}
-
 		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
 		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
-		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, objectRendererWebGLProps[renderTarget.uuid].__webglTexture, 0 );
+		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, webGLProps.getProperties( renderTarget ).__webglTexture, 0 );
 
 
 	}
 	}
 
 
@@ -3614,24 +3565,18 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	this.setRenderTarget = function ( renderTarget ) {
 	this.setRenderTarget = function ( renderTarget ) {
 
 
-		if ( renderTarget && ! objectRendererWebGLProps[renderTarget.uuid] ) {
-
-			objectRendererWebGLProps[renderTarget.uuid] = {};
-
-		}
-
 		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
 		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
 
 
-		if ( renderTarget && objectRendererWebGLProps[renderTarget.uuid].__webglFramebuffer === undefined ) {
+		if ( renderTarget && webGLProps.getProperties( renderTarget ).__webglFramebuffer === undefined ) {
 
 
-			var webglProps = objectRendererWebGLProps[renderTarget.uuid];
+			var renderTargetWebGLProperties = webGLProps.getProperties( renderTarget );
 
 
 			if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
 			if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
 			if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
 			if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
 
 
 			renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
 			renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
 
 
-			webglProps.__webglTexture = _gl.createTexture();
+			renderTargetWebGLProperties.__webglTexture = _gl.createTexture();
 
 
 			_this.info.memory.textures ++;
 			_this.info.memory.textures ++;
 
 
@@ -3643,22 +3588,22 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			if ( isCube ) {
 			if ( isCube ) {
 
 
-				webglProps.__webglFramebuffer = [];
-				webglProps.__webglRenderbuffer = [];
+				renderTargetWebGLProperties.__webglFramebuffer = [];
+				renderTargetWebGLProperties.__webglRenderbuffer = [];
 
 
-				state.bindTexture( _gl.TEXTURE_CUBE_MAP, webglProps.__webglTexture );
+				state.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTargetWebGLProperties.__webglTexture );
 
 
 				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
 				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
 
 
 				for ( var i = 0; i < 6; i ++ ) {
 				for ( var i = 0; i < 6; i ++ ) {
 
 
-					webglProps.__webglFramebuffer[ i ] = _gl.createFramebuffer();
-					webglProps.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
+					renderTargetWebGLProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
+					renderTargetWebGLProperties.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
 
 
 					state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
 					state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
 
 
-					setupFrameBuffer( webglProps.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
-					setupRenderBuffer( webglProps.__webglRenderbuffer[ i ], renderTarget );
+					setupFrameBuffer( renderTargetWebGLProperties.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
+					setupRenderBuffer( renderTargetWebGLProperties.__webglRenderbuffer[ i ], renderTarget );
 
 
 				}
 				}
 
 
@@ -3666,40 +3611,40 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			} else {
 			} else {
 
 
-				webglProps.__webglFramebuffer = _gl.createFramebuffer();
+				renderTargetWebGLProperties.__webglFramebuffer = _gl.createFramebuffer();
 
 
 				if ( renderTarget.shareDepthFrom ) {
 				if ( renderTarget.shareDepthFrom ) {
 
 
-					webglProps.__webglRenderbuffer = renderTarget.shareDepthFrom.__webglRenderbuffer;
+					renderTargetWebGLProperties.__webglRenderbuffer = renderTarget.shareDepthFrom.__webglRenderbuffer;
 
 
 				} else {
 				} else {
 
 
-					webglProps.__webglRenderbuffer = _gl.createRenderbuffer();
+					renderTargetWebGLProperties.__webglRenderbuffer = _gl.createRenderbuffer();
 
 
 				}
 				}
 
 
-				state.bindTexture( _gl.TEXTURE_2D, webglProps.__webglTexture );
+				state.bindTexture( _gl.TEXTURE_2D, renderTargetWebGLProperties.__webglTexture );
 				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
 				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
 
 
 				state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
 				state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
 
 
-				setupFrameBuffer( webglProps.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
+				setupFrameBuffer( renderTargetWebGLProperties.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
 
 
 				if ( renderTarget.shareDepthFrom ) {
 				if ( renderTarget.shareDepthFrom ) {
 
 
 					if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
 					if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
 
 
-						_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, webglProps.__webglRenderbuffer );
+						_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTargetWebGLProperties.__webglRenderbuffer );
 
 
 					} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
 					} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
 
 
-						_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, webglProps.__webglRenderbuffer );
+						_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTargetWebGLProperties.__webglRenderbuffer );
 
 
 					}
 					}
 
 
 				} else {
 				} else {
 
 
-					setupRenderBuffer( webglProps.__webglRenderbuffer, renderTarget );
+					setupRenderBuffer( renderTargetWebGLProperties.__webglRenderbuffer, renderTarget );
 
 
 				}
 				}
 
 
@@ -3728,15 +3673,15 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		if ( renderTarget ) {
 		if ( renderTarget ) {
 
 
-			var webglProps = objectRendererWebGLProps[renderTarget.uuid];
+			var renderTargetWebGLProperties = webGLProps.getProperties( renderTarget );
 
 
 			if ( isCube ) {
 			if ( isCube ) {
 
 
-				framebuffer = webglProps.__webglFramebuffer[ renderTarget.activeCubeFace ];
+				framebuffer = renderTargetWebGLProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
 
 
 			} else {
 			} else {
 
 
-				framebuffer = webglProps.__webglFramebuffer;
+				framebuffer = renderTargetWebGLProperties.__webglFramebuffer;
 
 
 			}
 			}
 
 
@@ -3781,13 +3726,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		}
 		}
 
 
-		if ( ! objectRendererWebGLProps[renderTarget.uuid] ) {
-
-			objectRendererWebGLProps[renderTarget.uuid] = {};
-
-		}
-
-		if ( objectRendererWebGLProps[renderTarget.uuid].__webglFramebuffer ) {
+		if ( webGLProps.getProperties( renderTarget ).__webglFramebuffer ) {
 
 
 			if ( renderTarget.format !== THREE.RGBAFormat ) {
 			if ( renderTarget.format !== THREE.RGBAFormat ) {
 
 
@@ -3798,9 +3737,9 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			var restore = false;
 			var restore = false;
 
 
-			if ( objectRendererWebGLProps[renderTarget.uuid].__webglFramebuffer !== _currentFramebuffer ) {
+			if ( webGLProps.getProperties( renderTarget ).__webglFramebuffer !== _currentFramebuffer ) {
 
 
-				_gl.bindFramebuffer( _gl.FRAMEBUFFER, objectRendererWebGLProps[renderTarget.uuid].__webglFramebuffer );
+				_gl.bindFramebuffer( _gl.FRAMEBUFFER, webGLProps.getProperties( renderTarget ).__webglFramebuffer );
 
 
 				restore = true;
 				restore = true;
 
 
@@ -3828,21 +3767,15 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	function updateRenderTargetMipmap ( renderTarget ) {
 	function updateRenderTargetMipmap ( renderTarget ) {
 
 
-		if ( ! objectRendererWebGLProps[renderTarget.uuid] ) {
-
-			objectRendererWebGLProps[renderTarget.uuid] = {};
-
-		}
-
 		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
 		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
 
 
-			state.bindTexture( _gl.TEXTURE_CUBE_MAP, objectRendererWebGLProps[renderTarget.uuid].__webglTexture );
+			state.bindTexture( _gl.TEXTURE_CUBE_MAP, webGLProps.getProperties( renderTarget ).__webglTexture );
 			_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
 			_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
 			state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
 			state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
 
 
 		} else {
 		} else {
 
 
-			state.bindTexture( _gl.TEXTURE_2D, objectRendererWebGLProps[renderTarget.uuid].__webglTexture );
+			state.bindTexture( _gl.TEXTURE_2D, webGLProps.getProperties( renderTarget ).__webglTexture );
 			_gl.generateMipmap( _gl.TEXTURE_2D );
 			_gl.generateMipmap( _gl.TEXTURE_2D );
 			state.bindTexture( _gl.TEXTURE_2D, null );
 			state.bindTexture( _gl.TEXTURE_2D, null );
 
 

+ 14 - 29
src/renderers/webgl/WebGLObjects.js

@@ -7,8 +7,7 @@ THREE.WebGLObjects = function ( gl, info ) {
 	var objects = {};
 	var objects = {};
 	var objectsImmediate = [];
 	var objectsImmediate = [];
 
 
-	// stores attributes by uuid in order to decouple buffers from attribute objects
-	var objectWebglProperties = {};
+	var webGLProps = new THREE.WebGLProperties();
 
 
 	var morphInfluences = new Float32Array( 8 );
 	var morphInfluences = new Float32Array( 8 );
 
 
@@ -46,7 +45,7 @@ THREE.WebGLObjects = function ( gl, info ) {
 		delete object._modelViewMatrix;
 		delete object._modelViewMatrix;
 		delete object._normalMatrix;
 		delete object._normalMatrix;
 
 
-		delete objectWebglProperties[object.uuid];
+		delete webGLProps.deleteProperties( object );
 
 
 	}
 	}
 
 
@@ -73,15 +72,11 @@ THREE.WebGLObjects = function ( gl, info ) {
 
 
 	this.init = function ( object ) {
 	this.init = function ( object ) {
 
 
-		if ( ! objectWebglProperties[object.uuid] ) {
+		var objectWebglProperties = webGLProps.getProperties( object );
 
 
-			objectWebglProperties[object.uuid] = {};
+		if ( objectWebglProperties.__webglInit === undefined ) {
 
 
-		}
-
-		if ( objectWebglProperties[object.uuid].__webglInit === undefined ) {
-
-			objectWebglProperties[object.uuid].__webglInit = true;
+			objectWebglProperties.__webglInit = true;
 			object._modelViewMatrix = new THREE.Matrix4();
 			object._modelViewMatrix = new THREE.Matrix4();
 			object._normalMatrix = new THREE.Matrix3();
 			object._normalMatrix = new THREE.Matrix3();
 
 
@@ -89,9 +84,9 @@ THREE.WebGLObjects = function ( gl, info ) {
 
 
 		}
 		}
 
 
-		if ( objectWebglProperties[object.uuid].__webglActive === undefined ) {
+		if ( objectWebglProperties.__webglActive === undefined ) {
 
 
-			objectWebglProperties[object.uuid].__webglActive = true;
+			objectWebglProperties.__webglActive = true;
 
 
 			if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.PointCloud ) {
 			if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.PointCloud ) {
 
 
@@ -192,26 +187,16 @@ THREE.WebGLObjects = function ( gl, info ) {
 
 
 			var attribute = attributes[ name ];
 			var attribute = attributes[ name ];
 
 
-			if ( ! attribute.uuid ) {
-
-				attribute.uuid = THREE.Math.generateUUID();
-
-			}
-
-			if ( ! objectWebglProperties[attribute.uuid] ) {
-
-				objectWebglProperties[attribute.uuid] = {};
-
-			}
-
 			var bufferType = ( name === 'index' ) ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;
 			var bufferType = ( name === 'index' ) ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;
 
 
 			var data = ( attribute instanceof THREE.InterleavedBufferAttribute ) ? attribute.data : attribute;
 			var data = ( attribute instanceof THREE.InterleavedBufferAttribute ) ? attribute.data : attribute;
 
 
-			if ( objectWebglProperties[attribute.uuid].__webglBuffer === undefined ) {
+			var attributeWebGLProperties = webGLProps.getProperties( attribute );
+
+			if ( attributeWebGLProperties.__webglBuffer === undefined ) {
 
 
-				objectWebglProperties[attribute.uuid].__webglBuffer = gl.createBuffer();
-				gl.bindBuffer( bufferType, objectWebglProperties[attribute.uuid].__webglBuffer );
+				attributeWebGLProperties.__webglBuffer = gl.createBuffer();
+				gl.bindBuffer( bufferType, attributeWebGLProperties.__webglBuffer );
 
 
 				var usage = gl.STATIC_DRAW;
 				var usage = gl.STATIC_DRAW;
 
 
@@ -229,7 +214,7 @@ THREE.WebGLObjects = function ( gl, info ) {
 
 
 			} else if ( data.needsUpdate === true ) {
 			} else if ( data.needsUpdate === true ) {
 
 
-				gl.bindBuffer( bufferType, objectWebglProperties[attribute.uuid].__webglBuffer );
+				gl.bindBuffer( bufferType, attributeWebGLProperties.__webglBuffer );
 
 
 				if ( data.updateRange === undefined || data.updateRange.count === -1 ) { // Not using update ranges
 				if ( data.updateRange === undefined || data.updateRange.count === -1 ) { // Not using update ranges
 
 
@@ -258,7 +243,7 @@ THREE.WebGLObjects = function ( gl, info ) {
 
 
 	// returns the webgl buffer for a specified attribute
 	// returns the webgl buffer for a specified attribute
 	this.getAttributeBuffer = function (attribute) {
 	this.getAttributeBuffer = function (attribute) {
-		return objectWebglProperties[attribute.uuid] ? objectWebglProperties[attribute.uuid].__webglBuffer : undefined;
+		return webGLProps.getProperties( attribute ).__webglBuffer;
 	}
 	}
 
 
 	this.update = function ( renderList ) {
 	this.update = function ( renderList ) {

+ 39 - 0
src/renderers/webgl/WebGLProperties.js

@@ -0,0 +1,39 @@
+/**
+* @author fordacious / fordacious.github.io
+*/
+
+THREE.WebGLProperties = function () {
+
+	var properties = {};
+
+	this.deleteProperties = function ( object ) {
+
+		delete properties[ object.uuid ];
+
+	};
+
+	this.getProperties = function ( object ) {
+
+		initObject( object );
+
+		return properties[ object.uuid ];
+
+	};
+
+	this.propertiesExist = function ( object ) {
+
+		return properties[ object.uuid ] !== undefined;
+
+	}
+
+	function initObject ( object ) {
+
+		if ( properties[ object.uuid ] === undefined ) {
+
+			properties[ object.uuid ] = {};
+
+		}
+
+	}
+
+};