Browse Source

webgl props are removed in one go in object deallocation, added better example, removed other examples, added check for properties at entrance of each function that uses properties

Fordy 10 years ago
parent
commit
37828617bb

+ 1 - 2
examples/index.html

@@ -314,8 +314,7 @@
 				"webgl_multiple_canvases_grid",
 				"webgl_multiple_elements",
 				"webgl_multiple_renderers_cube",
-				"webgl_multiple_renderers_horse",
-				"webgl_multiple_renderers_cubemap",
+				"webgl_multiple_renderers_complex",
 				"webgl_multiple_views",
 				"webgl_nearestneighbour",
 				"webgl_octree",

+ 300 - 0
examples/webgl_multiple_renderers_complex.html

@@ -0,0 +1,300 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - multiple canvases - 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;
+			}
+
+			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.05;
+					camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
+
+					camera.lookAt( scene.position );
+
+					renderer.render( scene, camera );
+
+				}
+			}
+
+		</script>
+
+	</body>
+</html>

+ 34 - 11
src/renderers/WebGLRenderer.js

@@ -664,8 +664,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			_gl.deleteTexture( objectRendererWebGLProps[texture.uuid].__image__webglTextureCube );
 
-			delete objectRendererWebGLProps[texture.uuid].__image__webglTextureCube;
-
 		} else {
 
 			// 2D texture
@@ -674,11 +672,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			_gl.deleteTexture( objectRendererWebGLProps[texture.uuid].__webglTexture );
 
-			delete objectRendererWebGLProps[texture.uuid].__webglTexture;
-			delete objectRendererWebGLProps[texture.uuid].__webglInit;
-
 		}
 
+		// remove all webgl props at once
+		delete objectRendererWebGLProps[texture.uuid];
+
 	};
 
 	var deallocateRenderTarget = function ( renderTarget ) {
@@ -687,8 +685,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		_gl.deleteTexture( objectRendererWebGLProps[renderTarget.uuid].__webglTexture );
 
-		delete objectRendererWebGLProps[renderTarget.uuid].__webglTexture;
-
 		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
 
 			for ( var i = 0; i < 6; i ++ ) {
@@ -705,8 +701,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		delete objectRendererWebGLProps[renderTarget.uuid].__webglFramebuffer;
-		delete objectRendererWebGLProps[renderTarget.uuid].__webglRenderbuffer;
+		delete objectRendererWebGLProps[renderTarget.uuid];
 
 	};
 
@@ -716,7 +711,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		if ( program === undefined ) return;
 
-		objectRendererWebGLProps[material.uuid].program = undefined;
+		material.program = undefined;
 
 		// only deallocate GL program if this was the last use of shared program
 		// assumed there is only single copy of any program in the _programs list
@@ -771,6 +766,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
+		delete objectRendererWebGLProps[material.uuid];
+
 	};
 
 	// Buffer rendering
@@ -3198,6 +3195,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
 
+		if ( ! objectRendererWebGLProps[texture.uuid] ) {
+
+			objectRendererWebGLProps[texture.uuid] = {};
+
+		}
+
 		var extension;
 
 		if ( isImagePowerOfTwo ) {
@@ -3247,6 +3250,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	this.uploadTexture = function ( texture, slot ) {
 
+		if ( ! objectRendererWebGLProps[texture.uuid] ) {
+
+			objectRendererWebGLProps[texture.uuid] = {};
+
+		}
+
 		if ( objectRendererWebGLProps[texture.uuid].__webglInit === undefined ) {
 
 			objectRendererWebGLProps[texture.uuid].__webglInit = true;
@@ -3370,7 +3379,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		}
 
 		// if the image has been uploaded into a separate renderer, will need to reupload to this renderer
-		if ( ( texture.image && texture.image.complete ) && texture.__webglInit === true && objectRendererWebGLProps[texture.uuid].__webglInit === undefined ) {
+		if ( ( texture.image && texture.image.complete !== false ) && texture.__webglInit === true && objectRendererWebGLProps[texture.uuid].__webglInit === undefined ) {
 
 			texture.needsUpdate = true;
 
@@ -3609,7 +3618,9 @@ THREE.WebGLRenderer = function ( parameters ) {
 	this.setRenderTarget = function ( renderTarget ) {
 
 		if ( renderTarget && ! objectRendererWebGLProps[renderTarget.uuid] ) {
+
 			objectRendererWebGLProps[renderTarget.uuid] = {};
+
 		}
 
 		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
@@ -3773,6 +3784,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
+		if ( ! objectRendererWebGLProps[renderTarget.uuid] ) {
+
+			objectRendererWebGLProps[renderTarget.uuid] = {};
+
+		}
+
 		if ( objectRendererWebGLProps[renderTarget.uuid].__webglFramebuffer ) {
 
 			if ( renderTarget.format !== THREE.RGBAFormat ) {
@@ -3814,6 +3831,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	function updateRenderTargetMipmap ( renderTarget ) {
 
+		if ( ! objectRendererWebGLProps[renderTarget.uuid] ) {
+
+			objectRendererWebGLProps[renderTarget.uuid] = {};
+
+		}
+
 		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
 
 			state.bindTexture( _gl.TEXTURE_CUBE_MAP, objectRendererWebGLProps[renderTarget.uuid].__webglTexture );

+ 1 - 2
src/renderers/webgl/WebGLObjects.js

@@ -43,11 +43,10 @@ THREE.WebGLObjects = function ( gl, info ) {
 
 		}
 
-		delete objectWebglProperties[object.uuid].__webglInit;
 		delete object._modelViewMatrix;
 		delete object._normalMatrix;
 
-		delete objectWebglProperties[object.uuid].__webglActive;
+		delete objectWebglProperties[object.uuid];
 
 	}