@@ -697,70 +697,94 @@ class WebGLTextureUtils {
697697 *
698698 * @param {Texture } srcTexture - The source texture.
699699 * @param {Texture } dstTexture - The destination texture.
700- * @param {?Vector4 } [srcRegion=null] - The region of the source texture to copy.
700+ * @param {?(Box3|Box2) } [srcRegion=null] - The region of the source texture to copy.
701701 * @param {?(Vector2|Vector3) } [dstPosition=null] - The destination position of the copy.
702- * @param {number } [level=0] - The mip level to copy.
702+ * @param {number } [srcLevel=0] - The source mip level to copy from.
703+ * @param {number } [dstLevel=0] - The destination mip level to copy to.
703704 */
704- copyTextureToTexture ( srcTexture , dstTexture , srcRegion = null , dstPosition = null , level = 0 ) {
705+ copyTextureToTexture ( srcTexture , dstTexture , srcRegion = null , dstPosition = null , srcLevel = 0 , dstLevel = 0 ) {
705706
706707 const { gl, backend } = this ;
707708 const { state } = this . backend ;
708709
709710 const { textureGPU : dstTextureGPU , glTextureType, glType, glFormat } = backend . get ( dstTexture ) ;
710711
711- let width , height , minX , minY ;
712- let dstX , dstY ;
712+ state . bindTexture ( glTextureType , dstTextureGPU ) ;
713+
714+ // gather the necessary dimensions to copy
715+ let width , height , depth , minX , minY , minZ ;
716+ let dstX , dstY , dstZ ;
717+ const image = srcTexture . isCompressedTexture ? srcTexture . mipmaps [ dstLevel ] : srcTexture . image ;
713718
714719 if ( srcRegion !== null ) {
715720
716721 width = srcRegion . max . x - srcRegion . min . x ;
717722 height = srcRegion . max . y - srcRegion . min . y ;
723+ depth = srcRegion . isBox3 ? srcRegion . max . z - srcRegion . min . z : 1 ;
718724 minX = srcRegion . min . x ;
719725 minY = srcRegion . min . y ;
726+ minZ = srcRegion . isBox3 ? srcRegion . min . z : 0 ;
720727
721728 } else {
722729
723- width = srcTexture . image . width ;
724- height = srcTexture . image . height ;
730+ const levelScale = Math . pow ( 2 , - srcLevel ) ;
731+ width = Math . floor ( image . width * levelScale ) ;
732+ height = Math . floor ( image . height * levelScale ) ;
733+
734+ if ( srcTexture . isDataArrayTexture ) {
735+
736+ depth = image . depth ;
737+
738+ } else if ( srcTexture . isData3DTexture ) {
739+
740+ depth = Math . floor ( image . depth * levelScale ) ;
741+
742+ } else {
743+
744+ depth = 1 ;
745+
746+ }
747+
725748 minX = 0 ;
726749 minY = 0 ;
750+ minZ = 0 ;
727751
728752 }
729753
730754 if ( dstPosition !== null ) {
731755
732756 dstX = dstPosition . x ;
733757 dstY = dstPosition . y ;
758+ dstZ = dstPosition . z ;
734759
735760 } else {
736761
737762 dstX = 0 ;
738763 dstY = 0 ;
764+ dstZ = 0 ;
739765
740766 }
741767
742- state . bindTexture ( glTextureType , dstTextureGPU ) ;
743768
744- // As another texture upload may have changed pixelStorei
745- // parameters, make sure they are correct for the dstTexture
746- gl . pixelStorei ( gl . UNPACK_ALIGNMENT , dstTexture . unpackAlignment ) ;
747769 gl . pixelStorei ( gl . UNPACK_FLIP_Y_WEBGL , dstTexture . flipY ) ;
748770 gl . pixelStorei ( gl . UNPACK_PREMULTIPLY_ALPHA_WEBGL , dstTexture . premultiplyAlpha ) ;
749771 gl . pixelStorei ( gl . UNPACK_ALIGNMENT , dstTexture . unpackAlignment ) ;
750772
773+ // used for copying data from cpu
751774 const currentUnpackRowLen = gl . getParameter ( gl . UNPACK_ROW_LENGTH ) ;
752775 const currentUnpackImageHeight = gl . getParameter ( gl . UNPACK_IMAGE_HEIGHT ) ;
753776 const currentUnpackSkipPixels = gl . getParameter ( gl . UNPACK_SKIP_PIXELS ) ;
754777 const currentUnpackSkipRows = gl . getParameter ( gl . UNPACK_SKIP_ROWS ) ;
755778 const currentUnpackSkipImages = gl . getParameter ( gl . UNPACK_SKIP_IMAGES ) ;
756779
757- const image = srcTexture . isCompressedTexture ? srcTexture . mipmaps [ level ] : srcTexture . image ;
758-
759780 gl . pixelStorei ( gl . UNPACK_ROW_LENGTH , image . width ) ;
760781 gl . pixelStorei ( gl . UNPACK_IMAGE_HEIGHT , image . height ) ;
761782 gl . pixelStorei ( gl . UNPACK_SKIP_PIXELS , minX ) ;
762783 gl . pixelStorei ( gl . UNPACK_SKIP_ROWS , minY ) ;
784+ gl . pixelStorei ( gl . UNPACK_SKIP_IMAGES , minZ ) ;
763785
786+ // set up the src texture
787+ const isDst3D = dstTexture . isDataArrayTexture || dstTexture . isData3DTexture ;
764788 if ( srcTexture . isRenderTargetTexture || srcTexture . isDepthTexture ) {
765789
766790 const srcTextureData = backend . get ( srcTexture ) ;
@@ -786,39 +810,63 @@ class WebGLTextureUtils {
786810
787811 } else {
788812
789- if ( srcTexture . isDataTexture ) {
813+ if ( isDst3D ) {
790814
791- gl . texSubImage2D ( gl . TEXTURE_2D , level , dstX , dstY , width , height , glFormat , glType , image . data ) ;
815+ // copy data into the 3d texture
816+ if ( srcTexture . isDataTexture || srcTexture . isData3DTexture ) {
817+
818+ gl . texSubImage3D ( glTextureType , dstLevel , dstX , dstY , dstZ , width , height , depth , glFormat , glType , image . data ) ;
819+
820+ } else if ( dstTexture . isCompressedArrayTexture ) {
821+
822+ gl . compressedTexSubImage3D ( glTextureType , dstLevel , dstX , dstY , dstZ , width , height , depth , glFormat , image . data ) ;
823+
824+ } else {
825+
826+ gl . texSubImage3D ( glTextureType , dstLevel , dstX , dstY , dstZ , width , height , depth , glFormat , glType , image ) ;
827+
828+ }
792829
793830 } else {
794831
795- if ( srcTexture . isCompressedTexture ) {
832+ // copy data into the 2d texture
833+ if ( srcTexture . isDataTexture ) {
834+
835+ gl . texSubImage2D ( glTextureType , dstLevel , dstX , dstY , width , height , glFormat , glType , image . data ) ;
796836
797- gl . compressedTexSubImage2D ( gl . TEXTURE_2D , level , dstX , dstY , image . width , image . height , glFormat , image . data ) ;
837+ } else if ( srcTexture . isCompressedTexture ) {
838+
839+ gl . compressedTexSubImage2D ( glTextureType , dstLevel , dstX , dstY , image . width , image . height , glFormat , image . data ) ;
798840
799841 } else {
800842
801- gl . texSubImage2D ( gl . TEXTURE_2D , level , dstX , dstY , width , height , glFormat , glType , image ) ;
843+ gl . texSubImage2D ( glTextureType , dstLevel , dstX , dstY , width , height , glFormat , glType , image ) ;
802844
803845 }
804846
805847 }
806848
807849 }
808850
851+ // reset values
809852 gl . pixelStorei ( gl . UNPACK_ROW_LENGTH , currentUnpackRowLen ) ;
810853 gl . pixelStorei ( gl . UNPACK_IMAGE_HEIGHT , currentUnpackImageHeight ) ;
811854 gl . pixelStorei ( gl . UNPACK_SKIP_PIXELS , currentUnpackSkipPixels ) ;
812855 gl . pixelStorei ( gl . UNPACK_SKIP_ROWS , currentUnpackSkipRows ) ;
813856 gl . pixelStorei ( gl . UNPACK_SKIP_IMAGES , currentUnpackSkipImages ) ;
814857
815858 // Generate mipmaps only when copying level 0
816- if ( level === 0 && dstTexture . generateMipmaps ) gl . generateMipmap ( gl . TEXTURE_2D ) ;
859+ if ( dstLevel === 0 && dstTexture . generateMipmaps ) {
860+
861+ gl . generateMipmap ( glTextureType ) ;
862+
863+ }
817864
818865 state . unbindTexture ( ) ;
819866
820867 }
821868
869+
822870 /**
823871 * Copies the current bound framebuffer to the given texture.
824872 *
0 commit comments