@@ -70,9 +70,6 @@ class Texture {
70
70
/** @protected */
71
71
_invalid = false ;
72
72
73
- /** @protected */
74
- _lockedLevel = - 1 ;
75
-
76
73
/** @protected */
77
74
_lockedMode = TEXTURELOCK_NONE ;
78
75
@@ -286,7 +283,7 @@ class Texture {
286
283
if ( this . _levels ) {
287
284
this . upload ( options . immediate ?? false ) ;
288
285
} else {
289
- this . _levels = this . cubemap ? [ [ null , null , null , null , null , null ] ] : [ null ] ;
286
+ this . _levels = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( null ) ] : [ null ] ;
290
287
}
291
288
292
289
// track the texture
@@ -825,7 +822,7 @@ class Texture {
825
822
826
823
// Force a full resubmission of the texture to the GPU (used on a context restore event)
827
824
dirtyAll ( ) {
828
- this . _levelsUpdated = this . cubemap ? [ [ true , true , true , true , true , true ] ] : [ true ] ;
825
+ this . _levelsUpdated = ( this . cubemap || this . array ) ? [ Array ( this . _slices ) . fill ( true ) ] : [ true ] ;
829
826
830
827
this . _needsUpload = true ;
831
828
this . _needsMipmapsUpload = this . _mipmaps ;
@@ -842,6 +839,8 @@ class Texture {
842
839
* to 0.
843
840
* @param {number } [options.face] - If the texture is a cubemap, this is the index of the face
844
841
* to lock.
842
+ * @param {number } [options.slice] - If the texture is a texture array, this is the index of the
843
+ * slice to lock.
845
844
* @param {number } [options.mode] - The lock mode. Can be:
846
845
* - {@link TEXTURELOCK_READ}
847
846
* - {@link TEXTURELOCK_WRITE}
@@ -853,6 +852,7 @@ class Texture {
853
852
// Initialize options to some sensible defaults
854
853
options . level ??= 0 ;
855
854
options . face ??= 0 ;
855
+ options . slice ??= 0 ;
856
856
options . mode ??= TEXTURELOCK_WRITE ;
857
857
858
858
Debug . assert (
@@ -867,19 +867,38 @@ class Texture {
867
867
this
868
868
) ;
869
869
870
+ Debug . assert (
871
+ options . level >= 0 && options . level < this . _levels . length ,
872
+ 'Invalid mip level' ,
873
+ this
874
+ ) ;
875
+
876
+ Debug . assert (
877
+ ( ( this . cubemap || this . array ) && options . mode === TEXTURELOCK_WRITE ) ? options . level === 0 : true ,
878
+ 'Only mip level 0 can be locked for writing for cubemaps and texture arrays' ,
879
+ this
880
+ ) ;
881
+
870
882
this . _lockedMode = options . mode ;
871
- this . _lockedLevel = options . level ;
872
883
873
- const levels = this . cubemap ? this . _levels [ options . face ] : this . _levels ;
884
+ const levels = this . cubemap ? this . _levels [ options . face ] : this . array ? this . _levels [ options . slice ] : this . _levels ;
874
885
if ( levels [ options . level ] === null ) {
875
886
// allocate storage for this mip level
876
887
const width = Math . max ( 1 , this . _width >> options . level ) ;
877
888
const height = Math . max ( 1 , this . _height >> options . level ) ;
878
- const depth = Math . max ( 1 , ( this . _dimension === TEXTUREDIMENSION_3D ? this . _slices : 1 ) >> options . level ) ;
889
+ const depth = Math . max ( 1 , this . depth >> options . level ) ;
879
890
const data = new ArrayBuffer ( TextureUtils . calcLevelGpuSize ( width , height , depth , this . _format ) ) ;
880
891
levels [ options . level ] = new ( getPixelFormatArrayType ( this . _format ) ) ( data ) ;
881
892
}
882
893
894
+ if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
895
+ if ( this . cubemap || this . array ) {
896
+ this . _levelsUpdated [ 0 ] [ options . face ?? options . slice ] = true ;
897
+ } else {
898
+ this . _levelsUpdated [ 0 ] = true ;
899
+ }
900
+ }
901
+
883
902
return levels [ options . level ] ;
884
903
}
885
904
@@ -889,22 +908,21 @@ class Texture {
889
908
*
890
909
* @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement|HTMLCanvasElement[]|HTMLImageElement[]|HTMLVideoElement[] } source - A
891
910
* canvas, image or video element, or an array of 6 canvas, image or video elements.
892
- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
893
911
* Defaults to 0, which represents the base image source. A level value of N, that is greater
894
912
* than 0, represents the image source for the Nth mipmap reduction level.
895
913
* @param {boolean } [immediate] - When set to true it forces an immediate upload upon assignment. Defaults to false.
896
914
*/
897
- setSource ( source , mipLevel = 0 , immediate = false ) {
915
+ setSource ( source , immediate = false ) {
898
916
let invalid = false ;
899
917
let width , height ;
900
918
901
- if ( this . cubemap ) {
919
+ if ( this . cubemap || this . array ) {
902
920
if ( source [ 0 ] ) {
903
921
// rely on first face sizes
904
922
width = source [ 0 ] . width || 0 ;
905
923
height = source [ 0 ] . height || 0 ;
906
924
907
- for ( let i = 0 ; i < 6 ; i ++ ) {
925
+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
908
926
const face = source [ i ] ;
909
927
// cubemap becomes invalid if any condition is not satisfied
910
928
if ( ! face || // face is missing
@@ -922,10 +940,9 @@ class Texture {
922
940
923
941
if ( ! invalid ) {
924
942
// mark levels as updated
925
- for ( let i = 0 ; i < 6 ; i ++ ) {
926
- if ( this . _levels [ mipLevel ] [ i ] !== source [ i ] ) {
927
- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
928
- }
943
+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
944
+ if ( this . _levels [ 0 ] [ i ] !== source [ i ] )
945
+ this . _levelsUpdated [ 0 ] [ i ] = true ;
929
946
}
930
947
}
931
948
} else {
@@ -936,9 +953,8 @@ class Texture {
936
953
937
954
if ( ! invalid ) {
938
955
// mark level as updated
939
- if ( source !== this . _levels [ mipLevel ] ) {
940
- this . _levelsUpdated [ mipLevel ] = true ;
941
- }
956
+ if ( source !== this . _levels [ 0 ] )
957
+ this . _levelsUpdated [ 0 ] = true ;
942
958
943
959
width = source . width ;
944
960
height = source . height ;
@@ -953,23 +969,22 @@ class Texture {
953
969
this . _height = 4 ;
954
970
955
971
// remove levels
956
- if ( this . cubemap ) {
957
- for ( let i = 0 ; i < 6 ; i ++ ) {
958
- this . _levels [ mipLevel ] [ i ] = null ;
959
- this . _levelsUpdated [ mipLevel ] [ i ] = true ;
972
+ if ( this . cubemap || this . array ) {
973
+ for ( let i = 0 ; i < this . _slices ; i ++ ) {
974
+ this . _levels [ 0 ] [ i ] = null ;
975
+ this . _levelsUpdated [ 0 ] [ i ] = true ;
960
976
}
961
977
} else {
962
- this . _levels [ mipLevel ] = null ;
963
- this . _levelsUpdated [ mipLevel ] = true ;
978
+ this . _levels [ 0 ] = null ;
979
+ this . _levelsUpdated [ 0 ] = true ;
964
980
}
965
981
} else {
966
982
// valid texture
967
- if ( mipLevel === 0 ) {
968
- this . _width = width ;
969
- this . _height = height ;
970
- }
971
983
972
- this . _levels [ mipLevel ] = source ;
984
+ this . _width = width ;
985
+ this . _height = height ;
986
+
987
+ this . _levels [ 0 ] = source ;
973
988
}
974
989
975
990
// valid or changed state of validity
@@ -985,14 +1000,11 @@ class Texture {
985
1000
* Get the pixel data of the texture. If this is a cubemap then an array of 6 images will be
986
1001
* returned otherwise a single image.
987
1002
*
988
- * @param {number } [mipLevel] - A non-negative integer specifying the image level of detail.
989
- * Defaults to 0, which represents the base image source. A level value of N, that is greater
990
- * than 0, represents the image source for the Nth mipmap reduction level.
991
1003
* @returns {HTMLImageElement } The source image of this texture. Can be null if source not
992
1004
* assigned for specific image level.
993
1005
*/
994
- getSource ( mipLevel = 0 ) {
995
- return this . _levels [ mipLevel ] ;
1006
+ getSource ( ) {
1007
+ return this . _levels [ 0 ] ;
996
1008
}
997
1009
998
1010
/**
@@ -1008,7 +1020,6 @@ class Texture {
1008
1020
if ( this . _lockedMode === TEXTURELOCK_WRITE ) {
1009
1021
this . upload ( immediate ) ;
1010
1022
}
1011
- this . _lockedLevel = - 1 ;
1012
1023
this . _lockedMode = TEXTURELOCK_NONE ;
1013
1024
}
1014
1025
0 commit comments