Quellcode durchsuchen

Create texture data and draw texture

Mu Daosheng vor 11 Jahren
Ursprung
Commit
5e2412d26e
2 geänderte Dateien mit 286 neuen und 20 gelöschten Zeilen
  1. 110 20
      examples/js/renderers/SoftwareRenderer.js
  2. 176 0
      examples/software_geometry_earth.html

+ 110 - 20
examples/js/renderers/SoftwareRenderer.js

@@ -236,26 +236,45 @@ THREE.SoftwareRenderer = function ( parameters ) {
 			     material instanceof THREE.SpriteMaterial ) {
 
 				var string;
-
-				if ( material.vertexColors === THREE.FaceColors ) {
-
-					string = [
-						'buffer[ offset ] = face.color.r * 255;',
-						'buffer[ offset + 1 ] = face.color.g * 255;',
-						'buffer[ offset + 2 ] = face.color.b * 255;',
-						'buffer[ offset + 3 ] = material.opacity * 255;',
-					].join('\n');
-
-				} else {
-
-					string = [
-						'buffer[ offset ] = material.color.r * 255;',
-						'buffer[ offset + 1 ] = material.color.g * 255;',
-						'buffer[ offset + 2 ] = material.color.b * 255;',
-						'buffer[ offset + 3 ] = material.opacity * 255;',
-					].join('\n');
-
-				}
+                
+                if ( material.map ) {
+                    var texture = new THREE.SoftwareRenderer.Texture();
+                    texture.CreateFromImage( material.map.image );
+                    material.texture = texture;
+                     
+                    string = [
+                            'var tdim = material.texture.width;',
+                            'var tbound = tdim - 1;',
+                            'var tdata = material.texture.data;',
+                            'var texel = tdata[((v * tdim) & tbound) * tdim + ((u * tdim) & tbound)];',
+                            'buffer[ offset ] = (texel & 0xff0000) >> 16;',
+                            'buffer[ offset + 1 ] = (texel & 0xff00) >> 8;',
+                            'buffer[ offset + 2 ] = (texel & 0xff);',
+                            'buffer[ offset + 3 ] = material.opacity * 255;',
+                        ].join('\n');
+                    
+                } else {
+                    
+                    if ( material.vertexColors === THREE.FaceColors ) {
+
+                        string = [
+                            'buffer[ offset ] = face.color.r * 255;',
+                            'buffer[ offset + 1 ] = face.color.g * 255;',
+                            'buffer[ offset + 2 ] = face.color.b * 255;',
+                            'buffer[ offset + 3 ] = material.opacity * 255;',
+                        ].join('\n');
+
+                    } else {
+
+                        string = [
+                            'buffer[ offset ] = material.color.r * 255;',
+                            'buffer[ offset + 1 ] = material.color.g * 255;',
+                            'buffer[ offset + 2 ] = material.color.b * 255;',
+                            'buffer[ offset + 3 ] = material.opacity * 255;',
+                        ].join('\n');
+
+                    }
+                }
 
 				shader = new Function( 'buffer, offset, u, v, face, material', string );
 
@@ -627,3 +646,74 @@ THREE.SoftwareRenderer = function ( parameters ) {
 	}
 
 };
+
+THREE.SoftwareRenderer.Texture = function() {
+    var canvas = null;
+    
+    this.CreateFromImage = function( image ) {
+        
+        if(image.width <=0 || image.height <=0)
+            return;
+    
+        var isCanvasClean = false;
+        var canvas = THREE.SoftwareRenderer.Texture.canvas;
+        if ( !canvas ) {
+
+            try {
+
+                canvas = document.createElement('canvas');
+                THREE.SoftwareRenderer.Texture.canvas = canvas;
+                isCanvasClean = true;
+            } catch( e ) {
+                return;
+            }
+
+        }
+
+        var dim = image.width > image.height ? image.width : image.height;
+        if(dim <= 32)
+            dim = 32;
+        else if(dim <= 64)
+            dim = 64;
+        else if(dim <= 128)
+            dim = 128;
+        else if(dim <= 256)
+            dim = 256;
+        else if(dim <= 512)
+            dim = 512;
+        else
+            dim = 1024;
+
+        if(canvas.width != dim || canvas.height != dim) {
+            canvas.width = canvas.height = dim;
+            isCanvasClean = true;
+        }
+
+        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;
+        }
+
+        var size = data.length / 4;
+        this.data = new Array(size);
+        var alpha;
+        for(var i=0, j=0; i<size; i++, j+=4) {
+            alpha = data[j + 3];
+            this.data[i] = alpha << 24 | data[j] << 16 | data[j+1] << 8 | data[j+2];
+            if(alpha < 255)
+                this.hasTransparency = true;
+        }
+
+        this.width = dim;
+        this.height = dim;
+        this.srcUrl = image.src;
+    };
+};

+ 176 - 0
examples/software_geometry_earth.html

@@ -0,0 +1,176 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js canvas - geometry - earth</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: #ffffff;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				padding: 5px;
+			}
+
+			a {
+
+				color: #0080ff;
+			}
+
+		</style>
+	</head>
+	<body>
+
+		<div id="container"></div>
+		<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - earth demo</div>
+
+		<script src="../build/three.min.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+        <script src="js/renderers/SoftwareRenderer.js"></script>
+
+		<script>
+
+			var container, stats;
+			var camera, scene, renderer;
+			var group;
+			var mouseX = 0, mouseY = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			init();
+			animate();
+
+			function init() {
+
+				container = document.getElementById( 'container' );
+
+				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 2000 );
+				camera.position.z = 500;
+
+				scene = new THREE.Scene();
+
+				group = new THREE.Object3D();
+				scene.add( group );
+
+				// earth
+
+				var loader = new THREE.TextureLoader();
+				loader.load( 'textures/land_ocean_ice_cloud_2048.jpg', function ( texture ) {
+
+					var geometry = new THREE.SphereGeometry( 200, 20, 20 );
+
+					var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
+					var mesh = new THREE.Mesh( geometry, material );
+					group.add( mesh );
+
+				} );
+
+				// 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 texture = new THREE.Texture( canvas );
+				texture.needsUpdate = true;
+
+				var geometry = new THREE.PlaneGeometry( 300, 300, 3, 3 );
+				var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
+
+				var mesh = new THREE.Mesh( geometry, material );
+				mesh.position.y = - 250;
+				mesh.rotation.x = - Math.PI / 2;
+				group.add( mesh );
+
+				renderer = new THREE.SoftwareRenderer();
+				renderer.setClearColor( 0x000000 );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				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 );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				windowHalfX = window.innerWidth / 2;
+				windowHalfY = window.innerHeight / 2;
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function onDocumentMouseMove( event ) {
+
+				mouseX = ( event.clientX - windowHalfX );
+				mouseY = ( event.clientY - windowHalfY );
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				camera.position.x += ( mouseX - camera.position.x ) * 0.05;
+				camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
+				camera.lookAt( scene.position );
+
+				group.rotation.y -= 0.005;
+
+				renderer.render( scene, camera );
+
+			}
+
+
+		</script>
+
+	</body>
+</html>