Browse Source

WebGLRenderer: Added support for texSubImage2D

Mugen87 7 years ago
parent
commit
19da2d514e

+ 3 - 0
docs/api/renderers/WebGLRenderer.html

@@ -323,6 +323,9 @@
 		<h3>[method:null copyFramebufferToTexture]( [param:Vector2 position], [param:Texture texture], [param:Number level] )</h3>
 		<h3>[method:null copyFramebufferToTexture]( [param:Vector2 position], [param:Texture texture], [param:Number level] )</h3>
 		<div>Copies pixels from the current WebGLFramebuffer into a 2D texture. Enables access to [link:https://developer.mozilla.org/de/docs/Web/API/WebGLRenderingContext/copyTexImage2D WebGLRenderingContext.copyTexImage2D].</div>
 		<div>Copies pixels from the current WebGLFramebuffer into a 2D texture. Enables access to [link:https://developer.mozilla.org/de/docs/Web/API/WebGLRenderingContext/copyTexImage2D WebGLRenderingContext.copyTexImage2D].</div>
 
 
+		<h3>[method:null copyTextureToTexture]( [param:Vector2 position], [param:Texture srcTexture], [param:Texture dstTexture], [param:Number level] )</h3>
+		<div>Copies all pixels of a texture to an existing texture starting from the given position. Enables access to [link:https://developer.mozilla.org/de/docs/Web/API/WebGLRenderingContext/texSubImage2D WebGLRenderingContext.texSubImage2D].</div>
+
 		<h3>[method:null dispose]( )</h3>
 		<h3>[method:null dispose]( )</h3>
 		<div>Dispose of the current rendering context.</div>
 		<div>Dispose of the current rendering context.</div>
 
 

+ 1 - 0
examples/files.js

@@ -169,6 +169,7 @@ var files = {
 		"webgl_materials_texture_canvas",
 		"webgl_materials_texture_canvas",
 		"webgl_materials_texture_filters",
 		"webgl_materials_texture_filters",
 		"webgl_materials_texture_manualmipmap",
 		"webgl_materials_texture_manualmipmap",
+		"webgl_materials_texture_partialupdate",
 		"webgl_materials_texture_rotation",
 		"webgl_materials_texture_rotation",
 		"webgl_materials_transparency",
 		"webgl_materials_transparency",
 		"webgl_materials_variations_basic",
 		"webgl_materials_variations_basic",

+ 161 - 0
examples/webgl_materials_texture_partialupdate.html

@@ -0,0 +1,161 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - texture - partial update</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 {
+				background:#777;
+				padding:0;
+				margin:0;
+				overflow:hidden;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px;
+				width: 100%;
+				color: #ffffff;
+				padding: 5px;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+			}
+
+			a {
+				color: #ffffff;
+			}
+		</style>
+
+		<script src="../build/three.js"></script>
+		<script src="js/Detector.js"></script>
+
+	</head>
+	<body>
+
+		<div id="info">
+			<a href="https://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> - partial texture update <br/>
+			replace parts of an existing texture with all data of another texture
+		</div>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var camera, scene, renderer, clock, dataTexture, diffuseMap;
+
+			init();
+			animate();
+
+			function init() {
+
+				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
+				camera.position.z = 2;
+
+				scene = new THREE.Scene();
+
+				clock = new THREE.Clock();
+
+				var loader = new THREE.TextureLoader();
+				diffuseMap = loader.load( 'textures/floors/FloorsCheckerboard_S_Diffuse.jpg' );
+				diffuseMap.minFilter = THREE.LinearFilter;
+				diffuseMap.generateMipmaps = false;
+
+				var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
+				material = new THREE.MeshBasicMaterial( { map: diffuseMap } );
+
+				var mesh = new THREE.Mesh( geometry, material );
+				scene.add( mesh );
+
+				//
+
+				var width = 32;
+				var height = 32;
+
+				var data = new Uint8Array( width * height * 3 );
+				dataTexture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
+
+				//
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			var last = 0;
+			var position = new THREE.Vector2();
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				var elapsedTime = clock.getElapsedTime();
+
+				if ( elapsedTime - last > 0.1 ) {
+
+					last = elapsedTime;
+
+					position.x = ( 32 * THREE.Math.randInt( 1, 16 ) ) - 32 ;
+					position.y = ( 32 * THREE.Math.randInt( 1, 16 ) ) - 32 ;
+
+					// generate new color data
+
+					updateDataTexture( dataTexture );
+
+					// perform copy from src to dest texture to a random position
+
+					renderer.copyTextureToTexture( position, dataTexture, diffuseMap );
+
+				}
+
+				renderer.render( scene, camera );
+
+			}
+
+			var color = new THREE.Color();
+
+			function updateDataTexture( texture ) {
+
+				var size = texture.image.width * texture.image.height;
+				var data = texture.image.data;
+
+				// generate a random color and update texture data
+
+				color.setHex( Math.random() * 0xffffff );
+
+				var r = Math.floor( color.r * 255 );
+				var g = Math.floor( color.g * 255 );
+				var b = Math.floor( color.b * 255 );
+
+				for ( var i = 0; i < size; i ++ ) {
+
+					var stride = i * 3;
+
+					data[ stride ] = r;
+					data[ stride + 1 ] = g;
+					data[ stride + 2] = b;
+
+				}
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 16 - 2
src/renderers/WebGLRenderer.js

@@ -2568,11 +2568,25 @@ function WebGLRenderer( parameters ) {
 
 
 		var width = texture.image.width;
 		var width = texture.image.width;
 		var height = texture.image.height;
 		var height = texture.image.height;
-		var internalFormat = utils.convert( texture.format );
+		var glFormat = utils.convert( texture.format );
 
 
 		this.setTexture2D( texture, 0 );
 		this.setTexture2D( texture, 0 );
 
 
-		_gl.copyTexImage2D( _gl.TEXTURE_2D, level || 0, internalFormat, position.x, position.y, width, height, 0 );
+		_gl.copyTexImage2D( _gl.TEXTURE_2D, level || 0, glFormat, position.x, position.y, width, height, 0 );
+
+	};
+
+	this.copyTextureToTexture = function ( position, srcTexture, dstTexture, level ) {
+
+		var width = srcTexture.image.width;
+		var height = srcTexture.image.height;
+		var glFormat = utils.convert( dstTexture.format );
+		var glType = utils.convert( dstTexture.type );
+		var pixels = srcTexture.isDataTexture ? srcTexture.image.data : srcTexture.image;
+
+		this.setTexture2D( dstTexture, 0 );
+
+		_gl.texSubImage2D( _gl.TEXTURE_2D, level || 0, position.x, position.y, width, height, glFormat, glType, pixels );
 
 
 	};
 	};