@@ -692,75 +692,98 @@ class WebGLTextureUtils {
692
692
693
693
}
694
694
695
+
695
696
/**
696
697
* Copies data of the given source texture to the given destination texture.
697
698
*
698
699
* @param {Texture } srcTexture - The source texture.
699
700
* @param {Texture } dstTexture - The destination texture.
700
- * @param {?Vector4 } [srcRegion=null] - The region of the source texture to copy.
701
+ * @param {?(Box3|Box2) } [srcRegion=null] - The region of the source texture to copy.
701
702
* @param {?(Vector2|Vector3) } [dstPosition=null] - The destination position of the copy.
702
- * @param {number } [level=0] - The mip level to copy.
703
+ * @param {number } [srcLevel=0] - The source mip level to copy from.
704
+ * @param {number } [dstLevel=null] - The destination mip level to copy to.
703
705
*/
704
- copyTextureToTexture ( srcTexture , dstTexture , srcRegion = null , dstPosition = null , level = 0 ) {
706
+ copyTextureToTexture ( srcTexture , dstTexture , srcRegion = null , dstPosition = null , srcLevel = 0 , dstLevel = null ) {
705
707
706
708
const { gl, backend } = this ;
707
709
const { state } = this . backend ;
708
710
709
711
const { textureGPU : dstTextureGPU , glTextureType, glType, glFormat } = backend . get ( dstTexture ) ;
710
712
711
- let width , height , minX , minY ;
712
- let dstX , dstY ;
713
+ state . bindTexture ( glTextureType , dstTextureGPU ) ;
713
714
715
+ // gather the necessary dimensions to copy
716
+ let width , height , depth , minX , minY , minZ ;
717
+ let dstX , dstY , dstZ ;
718
+ const image = srcTexture . isCompressedTexture ? srcTexture . mipmaps [ dstLevel ] : srcTexture . image ;
714
719
if ( srcRegion !== null ) {
715
720
716
721
width = srcRegion . max . x - srcRegion . min . x ;
717
722
height = srcRegion . max . y - srcRegion . min . y ;
723
+ depth = srcRegion . isBox3 ? srcRegion . max . z - srcRegion . min . z : 1 ;
718
724
minX = srcRegion . min . x ;
719
725
minY = srcRegion . min . y ;
726
+ minZ = srcRegion . isBox3 ? srcRegion . min . z : 0 ;
720
727
721
728
} else {
722
729
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
+ if ( srcTexture . isDataArrayTexture ) {
734
+
735
+ depth = image . depth ;
736
+
737
+ } else if ( srcTexture . isData3DTexture ) {
738
+
739
+ depth = Math . floor ( image . depth * levelScale ) ;
740
+
741
+ } else {
742
+
743
+ depth = 1 ;
744
+
745
+ }
746
+
725
747
minX = 0 ;
726
748
minY = 0 ;
749
+ minZ = 0 ;
727
750
728
751
}
729
752
730
753
if ( dstPosition !== null ) {
731
754
732
755
dstX = dstPosition . x ;
733
756
dstY = dstPosition . y ;
757
+ dstZ = dstPosition . z ;
734
758
735
759
} else {
736
760
737
761
dstX = 0 ;
738
762
dstY = 0 ;
763
+ dstZ = 0 ;
739
764
740
765
}
741
766
742
- state . bindTexture ( glTextureType , dstTextureGPU ) ;
743
767
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 ) ;
747
768
gl . pixelStorei ( gl . UNPACK_FLIP_Y_WEBGL , dstTexture . flipY ) ;
748
769
gl . pixelStorei ( gl . UNPACK_PREMULTIPLY_ALPHA_WEBGL , dstTexture . premultiplyAlpha ) ;
749
770
gl . pixelStorei ( gl . UNPACK_ALIGNMENT , dstTexture . unpackAlignment ) ;
750
771
772
+ // used for copying data from cpu
751
773
const currentUnpackRowLen = gl . getParameter ( gl . UNPACK_ROW_LENGTH ) ;
752
774
const currentUnpackImageHeight = gl . getParameter ( gl . UNPACK_IMAGE_HEIGHT ) ;
753
775
const currentUnpackSkipPixels = gl . getParameter ( gl . UNPACK_SKIP_PIXELS ) ;
754
776
const currentUnpackSkipRows = gl . getParameter ( gl . UNPACK_SKIP_ROWS ) ;
755
777
const currentUnpackSkipImages = gl . getParameter ( gl . UNPACK_SKIP_IMAGES ) ;
756
778
757
- const image = srcTexture . isCompressedTexture ? srcTexture . mipmaps [ level ] : srcTexture . image ;
758
-
759
779
gl . pixelStorei ( gl . UNPACK_ROW_LENGTH , image . width ) ;
760
780
gl . pixelStorei ( gl . UNPACK_IMAGE_HEIGHT , image . height ) ;
761
781
gl . pixelStorei ( gl . UNPACK_SKIP_PIXELS , minX ) ;
762
782
gl . pixelStorei ( gl . UNPACK_SKIP_ROWS , minY ) ;
783
+ gl . pixelStorei ( gl . UNPACK_SKIP_IMAGES , minZ ) ;
763
784
785
+ // set up the src texture
786
+ const isDst3D = dstTexture . isDataArrayTexture || dstTexture . isData3DTexture ;
764
787
if ( srcTexture . isRenderTargetTexture || srcTexture . isDepthTexture ) {
765
788
766
789
const srcTextureData = backend . get ( srcTexture ) ;
@@ -786,34 +809,57 @@ class WebGLTextureUtils {
786
809
787
810
} else {
788
811
789
- if ( srcTexture . isDataTexture ) {
812
+ if ( isDst3D ) {
790
813
791
- gl . texSubImage2D ( gl . TEXTURE_2D , level , dstX , dstY , width , height , glFormat , glType , image . data ) ;
814
+ // copy data into the 3d texture
815
+ if ( srcTexture . isDataTexture || srcTexture . isData3DTexture ) {
816
+
817
+ gl . texSubImage3D ( glTextureType , dstLevel , dstX , dstY , dstZ , width , height , depth , glFormat , glType , image . data ) ;
818
+
819
+ } else if ( dstTexture . isCompressedArrayTexture ) {
820
+
821
+ gl . compressedTexSubImage3D ( glTextureType , dstLevel , dstX , dstY , dstZ , width , height , depth , glFormat , image . data ) ;
822
+
823
+ } else {
824
+
825
+ gl . texSubImage3D ( glTextureType , dstLevel , dstX , dstY , dstZ , width , height , depth , glFormat , glType , image ) ;
826
+
827
+ }
792
828
793
829
} else {
794
830
795
- if ( srcTexture . isCompressedTexture ) {
831
+ // copy data into the 2d texture
832
+ if ( srcTexture . isDataTexture ) {
833
+
834
+ gl . texSubImage2D ( glTextureType , dstLevel , dstX , dstY , width , height , glFormat , glType , image . data ) ;
835
+
836
+ } else if ( srcTexture . isCompressedTexture ) {
796
837
797
- gl . compressedTexSubImage2D ( gl . TEXTURE_2D , level , dstX , dstY , image . width , image . height , glFormat , image . data ) ;
838
+ gl . compressedTexSubImage2D ( glTextureType , dstLevel , dstX , dstY , image . width , image . height , glFormat , image . data ) ;
798
839
799
840
} else {
800
841
801
- gl . texSubImage2D ( gl . TEXTURE_2D , level , dstX , dstY , width , height , glFormat , glType , image ) ;
842
+ gl . texSubImage2D ( glTextureType , dstLevel , dstX , dstY , width , height , glFormat , glType , image ) ;
802
843
803
844
}
804
845
805
846
}
806
847
807
848
}
808
849
850
+ // reset values
809
851
gl . pixelStorei ( gl . UNPACK_ROW_LENGTH , currentUnpackRowLen ) ;
810
852
gl . pixelStorei ( gl . UNPACK_IMAGE_HEIGHT , currentUnpackImageHeight ) ;
811
853
gl . pixelStorei ( gl . UNPACK_SKIP_PIXELS , currentUnpackSkipPixels ) ;
812
854
gl . pixelStorei ( gl . UNPACK_SKIP_ROWS , currentUnpackSkipRows ) ;
813
855
gl . pixelStorei ( gl . UNPACK_SKIP_IMAGES , currentUnpackSkipImages ) ;
814
856
815
857
// Generate mipmaps only when copying level 0
816
- if ( level === 0 && dstTexture . generateMipmaps ) gl . generateMipmap ( gl . TEXTURE_2D ) ;
858
+ if ( dstLevel === 0 && dstTexture . generateMipmaps ) {
859
+
860
+ gl . generateMipmap ( glTextureType ) ;
861
+
862
+ }
817
863
818
864
state . unbindTexture ( ) ;
819
865
0 commit comments