Browse Source

SoftwareRenderer: Simplified Texture logic and using material/texture update events.

Mr.doob 10 years ago
parent
commit
72d38a502a
1 changed files with 50 additions and 51 deletions
  1. 50 51
      examples/js/renderers/SoftwareRenderer.js

+ 50 - 51
examples/js/renderers/SoftwareRenderer.js

@@ -20,6 +20,7 @@ THREE.SoftwareRenderer = function ( parameters ) {
 	} );
 
 	var shaders = {};
+	var textures = {};
 
 	var canvasWidth, canvasHeight;
 	var canvasWBlocks, canvasHBlocks;
@@ -341,18 +342,15 @@ THREE.SoftwareRenderer = function ( parameters ) {
 
 		var colorOffset = offset * 4;
 
-		if ( material.map.needsUpdate === true ) {
-			material.texture.CreateFromImage( material.map.image );
-			material.map.needsUpdate = false;
-		}
+		var texture = textures[ material.map.id ];
 
-		if ( !material.texture.data )
+		if ( !texture.data )
 			return;
 
-		var tdim = material.texture.width;
+		var tdim = texture.width;
 		var isTransparent = material.transparent;
 		var tbound = tdim - 1;
-		var tdata = material.texture.data;
+		var tdata = texture.data;
 		var tIndex = (((v * tdim) & tbound) * tdim + ((u * tdim) & tbound)) * 4;
 
 		if ( !isTransparent ) {
@@ -381,19 +379,16 @@ THREE.SoftwareRenderer = function ( parameters ) {
 
 		var colorOffset = offset * 4;
 
-		if ( material.map.needsUpdate === true ) {
-			material.texture.CreateFromImage( material.map.image );
-			material.map.needsUpdate = false;
-		}
+		var texture = textures[ material.map.id ];
 
-		if ( !material.texture.data )
+		if ( !texture.data )
 			return;
 
-		var tdim = material.texture.width;
+		var tdim = texture.width;
 		var isTransparent = material.transparent;
 		var cIndex = (n > 0 ? (~~n) : 0) * 3;
 		var tbound = tdim - 1;
-		var tdata = material.texture.data;
+		var tdata = texture.data;
 		var tIndex = (((v * tdim) & tbound) * tdim + ((u * tdim) & tbound)) * 4;
 
 		if ( !isTransparent ) {
@@ -421,12 +416,24 @@ THREE.SoftwareRenderer = function ( parameters ) {
 
 	}
 
+	function onMaterialUpdate ( event ) {
+
+		var material = event.target;
+
+		material.removeEventListener( 'update', onMaterialUpdate );
+
+		delete shaders[ material.id ];
+
+	}
+
 	function getMaterialShader( material ) {
 
 		var id = material.id;
 		var shader = shaders[ id ];
 
-		if ( shaders[ id ] === undefined || material.needsUpdate === true ) {
+		if ( shaders[ id ] === undefined ) {
+
+			material.addEventListener( 'update', onMaterialUpdate );
 
 			if ( material instanceof THREE.MeshBasicMaterial ||
 				 material instanceof THREE.MeshLambertMaterial ||
@@ -451,7 +458,15 @@ THREE.SoftwareRenderer = function ( parameters ) {
 				if ( material.map ) {
 
 					var texture = new THREE.SoftwareRenderer.Texture();
-					material.texture = texture;
+					texture.fromImage( material.map.image );
+
+					material.map.addEventListener( 'update', function ( event ) {
+
+						texture.fromImage( event.target.image );
+
+					} );
+
+					textures[ material.map.id ] = texture;
 
 					if ( material instanceof THREE.MeshBasicMaterial
 						|| material instanceof THREE.SpriteMaterial ) {
@@ -509,8 +524,6 @@ THREE.SoftwareRenderer = function ( parameters ) {
 
 			shaders[ id ] = shader;
 
-			material.needsUpdate = false;
-
 		}
 
 		return shader;
@@ -1063,51 +1076,37 @@ THREE.SoftwareRenderer = function ( parameters ) {
 };
 
 THREE.SoftwareRenderer.Texture = function() {
-	var canvas = null;
 
-	this.CreateFromImage = function( image ) {
+	var canvas;
+
+	this.fromImage = function( image ) {
 
 		if( !image || image.width <= 0 || image.height <= 0 )
 			return;
 
-		var isCanvasClean = false;
-		var canvas = THREE.SoftwareRenderer.Texture.canvas;
-		if ( !canvas ) {
-
-			try {
+		if ( canvas === undefined ) {
 
-				canvas = document.createElement('canvas');
-				THREE.SoftwareRenderer.Texture.canvas = canvas;
-				isCanvasClean = true;
-			} catch( e ) {
-				return;
-			}
+			canvas = document.createElement( 'canvas' );
 
 		}
 
-		var dim = image.width > image.height ? image.width : image.height;
-		dim = THREE.Math.nextPowerOfTwo( dim );
+		var size = image.width > image.height ? image.width : image.height;
+		size = THREE.Math.nextPowerOfTwo( size );
 
-		if(canvas.width != dim || canvas.height != dim) {
-			canvas.width = canvas.height = dim;
-			isCanvasClean = true;
+		if ( canvas.width != size || canvas.height != size) {
+			canvas.width = size;
+			canvas.height = size;
 		}
 
-		var data;
-		try {
-			var ctx = canvas.getContext('2d');
-			if(!isCanvasClean)
-				ctx.clearRect(0, 0, dim, dim);
-			ctx.drawImage(image, 0, 0, dim, dim);
-			var imgData = ctx.getImageData(0, 0, dim, dim);
-			data = imgData.data;
-		}
-		catch(e) {
-			return;
-		}
-		this.data = data;
-		this.width = dim;
-		this.height = dim;
+		var ctx = canvas.getContext('2d');
+		ctx.clearRect( 0, 0, size, size );
+		ctx.drawImage( image, 0, 0, size, size );
+
+		var imgData = ctx.getImageData( 0, 0, size, size );
+
+		this.data = imgData.data;
+		this.width = size;
+		this.height = size;
 		this.srcUrl = image.src;
 	};
 };