Bläddra i källkod

WebGLBackend: Bring back 3D functionality for copyTextureToTexture (#30584)

* Make dstLevel = 0 by default

* Retrigger actions
ZonkyPop 10 månader sedan
förälder
incheckning
a42a8cf788

+ 4 - 3
src/renderers/common/Renderer.js

@@ -2467,14 +2467,15 @@ class Renderer {
 	 * @param {Texture} dstTexture - The destination texture.
 	 * @param {Texture} dstTexture - The destination texture.
 	 * @param {Box2|Box3} [srcRegion=null] - A bounding box which describes the source region. Can be two or three-dimensional.
 	 * @param {Box2|Box3} [srcRegion=null] - A bounding box which describes the source region. Can be two or three-dimensional.
 	 * @param {Vector2|Vector3} [dstPosition=null] - A vector that represents the origin of the destination region. Can be two or three-dimensional.
 	 * @param {Vector2|Vector3} [dstPosition=null] - A vector that represents the origin of the destination region. Can be two or three-dimensional.
-	 * @param {number} level - The mipmap level to copy.
+	 * @param {number} [srcLevel=0] - The source mip level to copy from.
+	 * @param {number} [dstLevel=0] - The destination mip level to copy to.
 	 */
 	 */
-	copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {
+	copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, srcLevel = 0, dstLevel = 0 ) {
 
 
 		this._textures.updateTexture( srcTexture );
 		this._textures.updateTexture( srcTexture );
 		this._textures.updateTexture( dstTexture );
 		this._textures.updateTexture( dstTexture );
 
 
-		this.backend.copyTextureToTexture( srcTexture, dstTexture, srcRegion, dstPosition, level );
+		this.backend.copyTextureToTexture( srcTexture, dstTexture, srcRegion, dstPosition, srcLevel, dstLevel );
 
 
 	}
 	}
 
 

+ 4 - 3
src/renderers/webgl-fallback/WebGLBackend.js

@@ -1894,11 +1894,12 @@ class WebGLBackend extends Backend {
 	 * @param {Texture} dstTexture - The destination texture.
 	 * @param {Texture} dstTexture - The destination texture.
 	 * @param {?Vector4} [srcRegion=null] - The region of the source texture to copy.
 	 * @param {?Vector4} [srcRegion=null] - The region of the source texture to copy.
 	 * @param {?(Vector2|Vector3)} [dstPosition=null] - The destination position of the copy.
 	 * @param {?(Vector2|Vector3)} [dstPosition=null] - The destination position of the copy.
-	 * @param {number} [level=0] - The mip level to copy.
+	 * @param {number} [srcLevel=0] - The source mip level to copy from.
+	 * @param {number} [dstLevel=0] - The destination mip level to copy to.
 	 */
 	 */
-	copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {
+	copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, srcLevel = 0, dstLevel = 0 ) {
 
 
-		this.textureUtils.copyTextureToTexture( srcTexture, dstTexture, srcRegion, dstPosition, level );
+		this.textureUtils.copyTextureToTexture( srcTexture, dstTexture, srcRegion, dstPosition, srcLevel, dstLevel );
 
 
 	}
 	}
 
 

+ 67 - 19
src/renderers/webgl-fallback/utils/WebGLTextureUtils.js

@@ -697,33 +697,57 @@ class WebGLTextureUtils {
 	 *
 	 *
 	 * @param {Texture} srcTexture - The source texture.
 	 * @param {Texture} srcTexture - The source texture.
 	 * @param {Texture} dstTexture - The destination texture.
 	 * @param {Texture} dstTexture - The destination texture.
-	 * @param {?Vector4} [srcRegion=null] - The region of the source texture to copy.
+	 * @param {?(Box3|Box2)} [srcRegion=null] - The region of the source texture to copy.
 	 * @param {?(Vector2|Vector3)} [dstPosition=null] - The destination position of the copy.
 	 * @param {?(Vector2|Vector3)} [dstPosition=null] - The destination position of the copy.
-	 * @param {number} [level=0] - The mip level to copy.
+	 * @param {number} [srcLevel=0] - The source mip level to copy from.
+	 * @param {number} [dstLevel=0] - The destination mip level to copy to.
 	 */
 	 */
-	copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {
+	copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, srcLevel = 0, dstLevel = 0 ) {
 
 
 		const { gl, backend } = this;
 		const { gl, backend } = this;
 		const { state } = this.backend;
 		const { state } = this.backend;
 
 
 		const { textureGPU: dstTextureGPU, glTextureType, glType, glFormat } = backend.get( dstTexture );
 		const { textureGPU: dstTextureGPU, glTextureType, glType, glFormat } = backend.get( dstTexture );
 
 
-		let width, height, minX, minY;
-		let dstX, dstY;
+		state.bindTexture( glTextureType, dstTextureGPU );
+
+		// gather the necessary dimensions to copy
+		let width, height, depth, minX, minY, minZ;
+		let dstX, dstY, dstZ;
+		const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ dstLevel ] : srcTexture.image;
 
 
 		if ( srcRegion !== null ) {
 		if ( srcRegion !== null ) {
 
 
 			width = srcRegion.max.x - srcRegion.min.x;
 			width = srcRegion.max.x - srcRegion.min.x;
 			height = srcRegion.max.y - srcRegion.min.y;
 			height = srcRegion.max.y - srcRegion.min.y;
+			depth = srcRegion.isBox3 ? srcRegion.max.z - srcRegion.min.z : 1;
 			minX = srcRegion.min.x;
 			minX = srcRegion.min.x;
 			minY = srcRegion.min.y;
 			minY = srcRegion.min.y;
+			minZ = srcRegion.isBox3 ? srcRegion.min.z : 0;
 
 
 		} else {
 		} else {
 
 
-			width = srcTexture.image.width;
-			height = srcTexture.image.height;
+			const levelScale = Math.pow( 2, - srcLevel );
+			width = Math.floor( image.width * levelScale );
+			height = Math.floor( image.height * levelScale );
+
+			if ( srcTexture.isDataArrayTexture ) {
+
+				depth = image.depth;
+
+			} else if ( srcTexture.isData3DTexture ) {
+
+				depth = Math.floor( image.depth * levelScale );
+
+			} else {
+
+				depth = 1;
+
+			}
+
 			minX = 0;
 			minX = 0;
 			minY = 0;
 			minY = 0;
+			minZ = 0;
 
 
 		}
 		}
 
 
@@ -731,36 +755,36 @@ class WebGLTextureUtils {
 
 
 			dstX = dstPosition.x;
 			dstX = dstPosition.x;
 			dstY = dstPosition.y;
 			dstY = dstPosition.y;
+			dstZ = dstPosition.z;
 
 
 		} else {
 		} else {
 
 
 			dstX = 0;
 			dstX = 0;
 			dstY = 0;
 			dstY = 0;
+			dstZ = 0;
 
 
 		}
 		}
 
 
-		state.bindTexture( glTextureType, dstTextureGPU );
 
 
-		// As another texture upload may have changed pixelStorei
-		// parameters, make sure they are correct for the dstTexture
-		gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
 		gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
 		gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
 		gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
 		gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
 		gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
 		gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
 
 
+		// used for copying data from cpu
 		const currentUnpackRowLen = gl.getParameter( gl.UNPACK_ROW_LENGTH );
 		const currentUnpackRowLen = gl.getParameter( gl.UNPACK_ROW_LENGTH );
 		const currentUnpackImageHeight = gl.getParameter( gl.UNPACK_IMAGE_HEIGHT );
 		const currentUnpackImageHeight = gl.getParameter( gl.UNPACK_IMAGE_HEIGHT );
 		const currentUnpackSkipPixels = gl.getParameter( gl.UNPACK_SKIP_PIXELS );
 		const currentUnpackSkipPixels = gl.getParameter( gl.UNPACK_SKIP_PIXELS );
 		const currentUnpackSkipRows = gl.getParameter( gl.UNPACK_SKIP_ROWS );
 		const currentUnpackSkipRows = gl.getParameter( gl.UNPACK_SKIP_ROWS );
 		const currentUnpackSkipImages = gl.getParameter( gl.UNPACK_SKIP_IMAGES );
 		const currentUnpackSkipImages = gl.getParameter( gl.UNPACK_SKIP_IMAGES );
 
 
-		const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ level ] : srcTexture.image;
-
 		gl.pixelStorei( gl.UNPACK_ROW_LENGTH, image.width );
 		gl.pixelStorei( gl.UNPACK_ROW_LENGTH, image.width );
 		gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, image.height );
 		gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, image.height );
 		gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, minX );
 		gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, minX );
 		gl.pixelStorei( gl.UNPACK_SKIP_ROWS, minY );
 		gl.pixelStorei( gl.UNPACK_SKIP_ROWS, minY );
+		gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, minZ );
 
 
+		// set up the src texture
+		const isDst3D = dstTexture.isDataArrayTexture || dstTexture.isData3DTexture;
 		if ( srcTexture.isRenderTargetTexture || srcTexture.isDepthTexture ) {
 		if ( srcTexture.isRenderTargetTexture || srcTexture.isDepthTexture ) {
 
 
 			const srcTextureData = backend.get( srcTexture );
 			const srcTextureData = backend.get( srcTexture );
@@ -786,19 +810,37 @@ class WebGLTextureUtils {
 
 
 		} else {
 		} else {
 
 
-			if ( srcTexture.isDataTexture ) {
+			if ( isDst3D ) {
 
 
-				gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image.data );
+				// copy data into the 3d texture
+				if ( srcTexture.isDataTexture || srcTexture.isData3DTexture ) {
+
+					gl.texSubImage3D( glTextureType, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, glType, image.data );
+
+				} else if ( dstTexture.isCompressedArrayTexture ) {
+
+					gl.compressedTexSubImage3D( glTextureType, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, image.data );
+
+				} else {
+
+					gl.texSubImage3D( glTextureType, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, glType, image );
+
+				}
 
 
 			} else {
 			} else {
 
 
-				if ( srcTexture.isCompressedTexture ) {
+				// copy data into the 2d texture
+				if ( srcTexture.isDataTexture ) {
+
+					gl.texSubImage2D( glTextureType, dstLevel, dstX, dstY, width, height, glFormat, glType, image.data );
 
 
-					gl.compressedTexSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, image.width, image.height, glFormat, image.data );
+				} else if ( srcTexture.isCompressedTexture ) {
+
+					gl.compressedTexSubImage2D( glTextureType, dstLevel, dstX, dstY, image.width, image.height, glFormat, image.data );
 
 
 				} else {
 				} else {
 
 
-					gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image );
+					gl.texSubImage2D( glTextureType, dstLevel, dstX, dstY, width, height, glFormat, glType, image );
 
 
 				}
 				}
 
 
@@ -806,6 +848,7 @@ class WebGLTextureUtils {
 
 
 		}
 		}
 
 
+		// reset values
 		gl.pixelStorei( gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
 		gl.pixelStorei( gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
 		gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
 		gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
 		gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
 		gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
@@ -813,12 +856,17 @@ class WebGLTextureUtils {
 		gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
 		gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
 
 
 		// Generate mipmaps only when copying level 0
 		// Generate mipmaps only when copying level 0
-		if ( level === 0 && dstTexture.generateMipmaps ) gl.generateMipmap( gl.TEXTURE_2D );
+		if ( dstLevel === 0 && dstTexture.generateMipmaps ) {
+
+			gl.generateMipmap( glTextureType );
+
+		}
 
 
 		state.unbindTexture();
 		state.unbindTexture();
 
 
 	}
 	}
 
 
+
 	/**
 	/**
 	 * Copies the current bound framebuffer to the given texture.
 	 * Copies the current bound framebuffer to the given texture.
 	 *
 	 *

粤ICP备19079148号