Browse Source

Merge pull request #6827 from dubejf/buff-update

Scene updates with multiple renderers
Ricardo Cabello 10 years ago
parent
commit
d019532145

+ 5 - 1
docs/api/core/BufferAttribute.html

@@ -43,10 +43,14 @@
 		Flag to indicate that this attribute has changed and should be re-send to the GPU. Set this to true when you modify the value of the array.
 		Flag to indicate that this attribute has changed and should be re-send to the GPU. Set this to true when you modify the value of the array.
 		</div>
 		</div>
 
 
+		<h3>[property:Integer version]</h3>
+		<div>
+		A version number, incremented every time the needsUpdate property is set to true.
+		</div>
 
 
 
 
 		<h2>Methods</h2>
 		<h2>Methods</h2>
-		
+
 		<h3>[method:null copyAt] ( [page:Integer index1], attribute, [page:Integer index2] ) </h3>
 		<h3>[method:null copyAt] ( [page:Integer index1], attribute, [page:Integer index2] ) </h3>
 		<div>
 		<div>
 		Copies itemSize values in the array from the vertex at index2 to the vertex at index1.
 		Copies itemSize values in the array from the vertex at index2 to the vertex at index1.

+ 24 - 1
examples/webgl_multiple_renderers.html

@@ -99,6 +99,8 @@
 
 
 			function animate() {
 			function animate() {
 
 
+				updateScene();
+
 				for ( var i = 0; i < apps.length; ++i ) {
 				for ( var i = 0; i < apps.length; ++i ) {
 
 
 					apps[ i ].animate();
 					apps[ i ].animate();
@@ -223,7 +225,10 @@
 				group2.rotation.x = 0;
 				group2.rotation.x = 0;
 				scene.add( group2 );
 				scene.add( group2 );
 
 
-				group3 = THREE.SceneUtils.createMultiMaterialObject( geometry3, materials );
+				group3 = new THREE.Group();
+				group3.add( new THREE.Mesh( new THREE.BufferGeometry().fromGeometry( geometry3 ), materials[0] ) );
+				group3.add( new THREE.Mesh( geometry3, materials[1] ) );
+				group3.name = 'rotating ball';
 				group3.position.x = 0;
 				group3.position.x = 0;
 				group3.rotation.x = 0;
 				group3.rotation.x = 0;
 				scene.add( group3 );
 				scene.add( group3 );
@@ -231,6 +236,24 @@
 				return scene;
 				return scene;
 			}
 			}
 
 
+			function updateScene () {
+
+				var group = scene.getObjectByName( 'rotating ball' )
+				group.rotation.x += Math.PI / 600;
+
+				var geometry = group.children[0].geometry;
+				var array = geometry.attributes.color.array;
+
+				for (var i = 0; i < array.length; i ++) {
+
+					array[i] = ( array[i] + 0.99 ) % 1.0;
+
+				}
+
+				geometry.attributes.color.needsUpdate = true;
+
+			}
+
 			function App( container, fullWidth, fullHeight ) {
 			function App( container, fullWidth, fullHeight ) {
 
 
 				var container, stats;
 				var container, stats;

+ 7 - 1
src/core/BufferAttribute.js

@@ -9,7 +9,7 @@ THREE.BufferAttribute = function ( array, itemSize ) {
 	this.array = array;
 	this.array = array;
 	this.itemSize = itemSize;
 	this.itemSize = itemSize;
 
 
-	this.needsUpdate = false;
+	this.version = 0;
 
 
 };
 };
 
 
@@ -30,6 +30,12 @@ THREE.BufferAttribute.prototype = {
 
 
 	},
 	},
 
 
+	set needsUpdate( value ) {
+
+		if ( value === true ) this.version ++;
+
+	},
+
 	copyAt: function ( index1, attribute, index2 ) {
 	copyAt: function ( index1, attribute, index2 ) {
 
 
 		index1 *= this.itemSize;
 		index1 *= this.itemSize;

+ 7 - 1
src/core/InterleavedBuffer.js

@@ -9,7 +9,7 @@ THREE.InterleavedBuffer = function ( array, stride, dynamic ) {
 	this.array = array;
 	this.array = array;
 	this.stride = stride;
 	this.stride = stride;
 
 
-	this.needsUpdate = false;
+	this.version = 0;
 
 
 	this.dynamic = dynamic || false;
 	this.dynamic = dynamic || false;
 	this.updateRange = { offset: 0, count: -1 };
 	this.updateRange = { offset: 0, count: -1 };
@@ -32,6 +32,12 @@ THREE.InterleavedBuffer.prototype = {
 
 
 	},
 	},
 
 
+	set needsUpdate( value ) {
+
+		if ( value === true ) this.version ++;
+
+	},
+
 	copyAt: function ( index1, attribute, index2 ) {
 	copyAt: function ( index1, attribute, index2 ) {
 
 
 		index1 *= this.stride;
 		index1 *= this.stride;

+ 47 - 31
src/renderers/webgl/WebGLObjects.js

@@ -167,74 +167,90 @@ THREE.WebGLObjects = function ( gl, properties, info ) {
 
 
 		for ( var name in attributes ) {
 		for ( var name in attributes ) {
 
 
-			var attribute = attributes[ name ];
+			updateAttribute( attributes[ name ], name );
 
 
-			var bufferType = ( name === 'index' ) ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;
+		}
 
 
-			var data = ( attribute instanceof THREE.InterleavedBufferAttribute ) ? attribute.data : attribute;
+	}
 
 
-			var attributeProperties = properties.get( data );
+	function updateAttribute ( attribute, name ) {
 
 
-			if ( attributeProperties.__webglBuffer === undefined ) {
+		var bufferType = ( name === 'index' ) ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;
 
 
-				attributeProperties.__webglBuffer = gl.createBuffer();
-				gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
+		var data = ( attribute instanceof THREE.InterleavedBufferAttribute ) ? attribute.data : attribute;
 
 
-				var usage = gl.STATIC_DRAW;
+		var attributeProperties = properties.get( data );
 
 
-				if ( data instanceof THREE.DynamicBufferAttribute
-						 || ( data instanceof THREE.InstancedBufferAttribute && data.dynamic === true )
-						 || ( data instanceof THREE.InterleavedBuffer && data.dynamic === true ) ) {
+		if ( attributeProperties.__webglBuffer === undefined ) {
 
 
-					usage = gl.DYNAMIC_DRAW;
+			createBuffer( attributeProperties, data, bufferType );
 
 
-				}
+		} else if ( attributeProperties.version !== data.version ) {
 
 
-				gl.bufferData( bufferType, data.array, usage );
+			updateBuffer( attributeProperties, data, bufferType );
 
 
-				data.needsUpdate = false;
+		}
 
 
-			} else if ( data.needsUpdate === true ) {
+	}
 
 
-				gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
+	function createBuffer ( attributeProperties, data, bufferType ) {
 
 
-				if ( data.updateRange === undefined || data.updateRange.count === -1 ) { // Not using update ranges
+		attributeProperties.__webglBuffer = gl.createBuffer();
+		gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
 
 
-					gl.bufferSubData( bufferType, 0, data.array );
+		var usage = gl.STATIC_DRAW;
 
 
-				} else if ( data.updateRange.count === 0 ) {
+		if ( data instanceof THREE.DynamicBufferAttribute
+			 || ( data instanceof THREE.InstancedBufferAttribute && data.dynamic === true )
+			 || ( data instanceof THREE.InterleavedBuffer && data.dynamic === true ) ) {
 
 
-					console.error( 'THREE.WebGLRenderer.updateObject: using updateRange for THREE.DynamicBufferAttribute and marked as needsUpdate but count is 0, ensure you are using set methods or updating manually.' );
+			usage = gl.DYNAMIC_DRAW;
 
 
-				} else {
+		}
 
 
-					gl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,
-									 data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );
+		gl.bufferData( bufferType, data.array, usage );
 
 
-					data.updateRange.count = 0; // reset range
+		attributeProperties.version = data.version;
 
 
-				}
+	}
 
 
-				data.needsUpdate = false;
+	function updateBuffer ( attributeProperties, data, bufferType ) {
 
 
-			}
+		gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
+
+		if ( data.updateRange === undefined || data.updateRange.count === -1 ) { // Not using update ranges
+
+			gl.bufferSubData( bufferType, 0, data.array );
+
+		} else if ( data.updateRange.count === 0 ) {
+
+			console.error( 'THREE.WebGLRenderer.updateObject: using updateRange for THREE.DynamicBufferAttribute and marked as needsUpdate but count is 0, ensure you are using set methods or updating manually.' );
+
+		} else {
+
+			gl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,
+							  data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );
+
+			data.updateRange.count = 0; // reset range
 
 
 		}
 		}
 
 
-	};
+		attributeProperties.version = data.version;
+
+	}
 
 
 	// returns the webgl buffer for a specified attribute
 	// returns the webgl buffer for a specified attribute
 	this.getAttributeBuffer = function ( attribute ) {
 	this.getAttributeBuffer = function ( attribute ) {
 
 
 		if ( attribute instanceof THREE.InterleavedBufferAttribute ) {
 		if ( attribute instanceof THREE.InterleavedBufferAttribute ) {
 
 
-			return properties.get( attribute.data ).__webglBuffer
+			return properties.get( attribute.data ).__webglBuffer;
 
 
 		}
 		}
 
 
 		return properties.get( attribute ).__webglBuffer;
 		return properties.get( attribute ).__webglBuffer;
 
 
-	}
+	};
 
 
 	this.update = function ( renderList ) {
 	this.update = function ( renderList ) {