Explorar o código

Merge pull request #6827 from dubejf/buff-update

Scene updates with multiple renderers
Ricardo Cabello %!s(int64=10) %!d(string=hai) anos
pai
achega
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.
 		</div>
 
+		<h3>[property:Integer version]</h3>
+		<div>
+		A version number, incremented every time the needsUpdate property is set to true.
+		</div>
 
 
 		<h2>Methods</h2>
-		
+
 		<h3>[method:null copyAt] ( [page:Integer index1], attribute, [page:Integer index2] ) </h3>
 		<div>
 		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() {
 
+				updateScene();
+
 				for ( var i = 0; i < apps.length; ++i ) {
 
 					apps[ i ].animate();
@@ -223,7 +225,10 @@
 				group2.rotation.x = 0;
 				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.rotation.x = 0;
 				scene.add( group3 );
@@ -231,6 +236,24 @@
 				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 ) {
 
 				var container, stats;

+ 7 - 1
src/core/BufferAttribute.js

@@ -9,7 +9,7 @@ THREE.BufferAttribute = function ( array, itemSize ) {
 	this.array = array;
 	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 ) {
 
 		index1 *= this.itemSize;

+ 7 - 1
src/core/InterleavedBuffer.js

@@ -9,7 +9,7 @@ THREE.InterleavedBuffer = function ( array, stride, dynamic ) {
 	this.array = array;
 	this.stride = stride;
 
-	this.needsUpdate = false;
+	this.version = 0;
 
 	this.dynamic = dynamic || false;
 	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 ) {
 
 		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 ) {
 
-			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
 	this.getAttributeBuffer = function ( attribute ) {
 
 		if ( attribute instanceof THREE.InterleavedBufferAttribute ) {
 
-			return properties.get( attribute.data ).__webglBuffer
+			return properties.get( attribute.data ).__webglBuffer;
 
 		}
 
 		return properties.get( attribute ).__webglBuffer;
 
-	}
+	};
 
 	this.update = function ( renderList ) {