@@ -78,9 +78,6 @@ class Texture {
78
78
/** @protected */
79
79
_invalid = false ;
80
80
81
- /** @protected */
82
- _lockedLevel = - 1 ;
83
-
84
81
/** @protected */
85
82
_lockedMode = TEXTURELOCK_NONE ;
86
83
@@ -295,7 +292,7 @@ class Texture {
295
292
if ( this . _levels ) {
296
293
this . upload ( options . immediate ?? false ) ;
297
294
} else {
298
- this . _levels = this . cubemap ? [ [ null , null , null , null , null , null ] ] : [ null ] ;
295
+ this . _levels = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( null ) ] : [ null ] ;
299
296
}
300
297
301
298
// track the texture
@@ -833,7 +830,7 @@ class Texture {
833
830
834
831
// Force a full resubmission of the texture to the GPU (used on a context restore event)
835
832
dirtyAll ( ) {
836
- this . _levelsUpdated = this . cubemap ? [ [ true , true , true , true , true , true ] ] : [ true ] ;
833
+ this . _levelsUpdated = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( true ) ] : [ true ] ;
837
834
838
835
this . _needsUpload = true ;
839
836
this . _needsMipmapsUpload = this . _mipmaps ;
@@ -850,6 +847,8 @@ class Texture {
850
847
* to 0.
851
848
* @param {number } [options.face] - If the texture is a cubemap, this is the index of the face
852
849
* to lock.
850
+ * @param {number } [options.slice] - If the texture is a texture array, this is the index of the
851
+ * slice to lock.
853
852
* @param {number } [options.mode] - The lock mode. Can be:
854
853
* - {@link TEXTURELOCK_READ}
855
854
* - {@link TEXTURELOCK_WRITE}
@@ -861,6 +860,7 @@ class Texture {
861
860
// Initialize options to some sensible defaults
862
861
options . level ??= 0 ;
863
862
options . face ??= 0 ;
863
+ options . slice ??= 0 ;
864
864
options . mode ??= TEXTURELOCK_WRITE ;
865
865
866
866
Debug . assert (
@@ -875,19 +875,38 @@ class Texture {
875
875
this
876
876
) ;
877
877
878
+ Debug . assert (
879
+ options . level >= 0 && options . level < this . _levels . length ,
880
+ 'Invalid mip level' ,
881
+ this
882
+ ) ;
883
+
884
+ Debug . assert (
885
+ ( ( this . cubemap || this . array ) && options . mode === TEXTURELOCK_WRITE ) ? options . level === 0 : true ,
886
+ 'Only mip level 0 can be locked for writing for cubemaps and texture arrays' ,
887
+ this
888
+ ) ;
889
+
878
890
this . _lockedMode = options . mode ;
879
- this . _lockedLevel = options . level ;
880
891
881
- const levels = this . cubemap ? this . _levels [ options . face ] : this . _levels ;
892
+ const levels = this . cubemap ? this . _levels [ options . face ] : this . array ? this . _levels [ options . slice ] : this . _levels ;
882
893
if ( levels [ options . level ] === null ) {
883
894
// allocate storage for this mip level
884
895
const width = Math . max ( 1 , this . _width >> options . level ) ;
885
896
const height = Math . max ( 1 , this . _height >> options . level ) ;
886
- const depth = Math . max ( 1 , ( this . _dimension === TEXTUREDIMENSION_3D ? this . _slices : 1 ) >> options . level ) ;
897
+ const depth = Math . max ( 1 , this . depth >> options . level ) ;
887
898
const data = new ArrayBuffer ( TextureUtils . calcLevelGpuSize ( width , height , depth , this . _format ) ) ;
888
899
levels [ options . level ] = new ( getPixelFormatArrayType ( this . _format ) ) ( data ) ;
889
900
}
890
901
902
+ if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
903
+ if ( this . cubemap || this . array ) {
904
+ this . _levelsUpdated [ 0 ] [ options . face ?? options . slice ] = true ;
905
+ } else {
906
+ this . _levelsUpdated [ 0 ] = true ;
907
+ }
908
+ }
909
+
891
910
return levels [ options . level ] ;
892
911
}
893
912
@@ -897,22 +916,21 @@ class Texture {
897
916
*
898
917
* @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement|HTMLCanvasElement[]|HTMLImageElement[]|HTMLVideoElement[] } source - A
899
918
* canvas, image or video element, or an array of 6 canvas, image or video elements.
900
- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
901
919
* Defaults to 0, which represents the base image source. A level value of N, that is greater
902
920
* than 0, represents the image source for the Nth mipmap reduction level.
903
921
* @param {boolean } [immediate] - When set to true it forces an immediate upload upon assignment. Defaults to false.
904
922
*/
905
- setSource ( source , mipLevel = 0 , immediate = false ) {
923
+ setSource ( source , immediate = false ) {
906
924
let invalid = false ;
907
925
let width , height ;
908
926
909
- if ( this . cubemap ) {
927
+ if ( this . cubemap || this . array ) {
910
928
if ( source [ 0 ] ) {
911
929
// rely on first face sizes
912
930
width = source [ 0 ] . width || 0 ;
913
931
height = source [ 0 ] . height || 0 ;
914
932
915
- for ( let i = 0 ; i < 6 ; i ++ ) {
933
+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
916
934
const face = source [ i ] ;
917
935
// cubemap becomes invalid if any condition is not satisfied
918
936
if ( ! face || // face is missing
@@ -930,9 +948,9 @@ class Texture {
930
948
931
949
if ( ! invalid ) {
932
950
// mark levels as updated
933
- for ( let i = 0 ; i < 6 ; i ++ ) {
934
- if ( this . _levels [ mipLevel ] [ i ] !== source [ i ] )
935
- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
951
+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
952
+ if ( this . _levels [ 0 ] [ i ] !== source [ i ] )
953
+ this . _levelsUpdated [ 0 ] [ i ] = true ;
936
954
}
937
955
}
938
956
} else {
@@ -942,8 +960,8 @@ class Texture {
942
960
943
961
if ( ! invalid ) {
944
962
// mark level as updated
945
- if ( source !== this . _levels [ mipLevel ] )
946
- this . _levelsUpdated [ mipLevel ] = true ;
963
+ if ( source !== this . _levels [ 0 ] )
964
+ this . _levelsUpdated [ 0 ] = true ;
947
965
948
966
width = source . width ;
949
967
height = source . height ;
@@ -958,23 +976,22 @@ class Texture {
958
976
this . _height = 4 ;
959
977
960
978
// remove levels
961
- if ( this . cubemap ) {
962
- for ( let i = 0 ; i < 6 ; i ++ ) {
963
- this . _levels [ mipLevel ] [ i ] = null ;
964
- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
979
+ if ( this . cubemap || this . array ) {
980
+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
981
+ this . _levels [ 0 ] [ i ] = null ;
982
+ this . _levelsUpdated [ 0 ] [ i ] = true ;
965
983
}
966
984
} else {
967
- this . _levels [ mipLevel ] = null ;
968
- this . _levelsUpdated [ mipLevel ] = true ;
985
+ this . _levels [ 0 ] = null ;
986
+ this . _levelsUpdated [ 0 ] = true ;
969
987
}
970
988
} else {
971
989
// valid texture
972
- if ( mipLevel === 0 ) {
973
- this . _width = width ;
974
- this . _height = height ;
975
- }
976
990
977
- this . _levels [ mipLevel ] = source ;
991
+ this . _width = width ;
992
+ this . _height = height ;
993
+
994
+ this . _levels [ 0 ] = source ;
978
995
}
979
996
980
997
// valid or changed state of validity
@@ -990,14 +1007,11 @@ class Texture {
990
1007
* Get the pixel data of the texture. If this is a cubemap then an array of 6 images will be
991
1008
* returned otherwise a single image.
992
1009
*
993
- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
994
- * Defaults to 0, which represents the base image source. A level value of N, that is greater
995
- * than 0, represents the image source for the Nth mipmap reduction level.
996
1010
* @returns {HTMLImageElement } The source image of this texture. Can be null if source not
997
1011
* assigned for specific image level.
998
1012
*/
999
- getSource ( mipLevel = 0 ) {
1000
- return this . _levels [ mipLevel ] ;
1013
+ getSource ( ) {
1014
+ return this . _levels [ 0 ] ;
1001
1015
}
1002
1016
1003
1017
/**
@@ -1013,7 +1027,6 @@ class Texture {
1013
1027
if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
1014
1028
this . upload ( immediate ) ;
1015
1029
}
1016
- this . _lockedLevel = - 1 ;
1017
1030
this . _lockedMode = TEXTURELOCK_NONE ;
1018
1031
}
1019
1032
0 commit comments