|
@@ -524,41 +524,91 @@ class WebGLTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
- copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
|
|
|
+ copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {
|
|
|
|
|
|
const { gl, backend } = this;
|
|
|
const { state } = this.backend;
|
|
|
|
|
|
- const width = srcTexture.image.width;
|
|
|
- const height = srcTexture.image.height;
|
|
|
const { textureGPU: dstTextureGPU, glTextureType, glType, glFormat } = backend.get( dstTexture );
|
|
|
|
|
|
+
|
|
|
+ let width, height, minX, minY;
|
|
|
+ let dstX, dstY;
|
|
|
+ if ( srcRegion !== null ) {
|
|
|
+
|
|
|
+ width = srcRegion.max.x - srcRegion.min.x;
|
|
|
+ height = srcRegion.max.y - srcRegion.min.y;
|
|
|
+ minX = srcRegion.min.x;
|
|
|
+ minY = srcRegion.min.y;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ width = srcTexture.image.width;
|
|
|
+ height = srcTexture.image.height;
|
|
|
+ minX = 0;
|
|
|
+ minY = 0;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( dstPosition !== null ) {
|
|
|
+
|
|
|
+ dstX = dstPosition.x;
|
|
|
+ dstY = dstPosition.y;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ dstX = 0;
|
|
|
+ dstY = 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_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
|
|
|
gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
|
|
|
|
|
|
+ const currentUnpackRowLen = gl.getParameter( gl.UNPACK_ROW_LENGTH );
|
|
|
+ const currentUnpackImageHeight = gl.getParameter( gl.UNPACK_IMAGE_HEIGHT );
|
|
|
+ const currentUnpackSkipPixels = gl.getParameter( gl.UNPACK_SKIP_PIXELS );
|
|
|
+ const currentUnpackSkipRows = gl.getParameter( gl.UNPACK_SKIP_ROWS );
|
|
|
+ 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_IMAGE_HEIGHT, image.height );
|
|
|
+ gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, minX );
|
|
|
+ gl.pixelStorei( gl.UNPACK_SKIP_ROWS, minY );
|
|
|
+
|
|
|
+
|
|
|
if ( srcTexture.isDataTexture ) {
|
|
|
|
|
|
- gl.texSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data );
|
|
|
+ gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image.data );
|
|
|
|
|
|
} else {
|
|
|
|
|
|
if ( srcTexture.isCompressedTexture ) {
|
|
|
|
|
|
- gl.compressedTexSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data );
|
|
|
+ gl.compressedTexSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, image.width, image.height, glFormat, image.data );
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- gl.texSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image );
|
|
|
+ gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, glFormat, glType, image );
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
+ gl.pixelStorei( gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
|
|
|
+ gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
|
|
|
+ gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
|
|
|
+ gl.pixelStorei( gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
|
|
|
+ gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
|
|
|
+
|
|
|
// Generate mipmaps only when copying level 0
|
|
|
if ( level === 0 && dstTexture.generateMipmaps ) gl.generateMipmap( gl.TEXTURE_2D );
|
|
|
|