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