@@ -15,7 +15,11 @@ import {
15
15
TEXTURELOCK_WRITE ,
16
16
TEXTUREPROJECTION_NONE , TEXTUREPROJECTION_CUBE ,
17
17
TEXTURETYPE_DEFAULT , TEXTURETYPE_RGBM , TEXTURETYPE_RGBE , TEXTURETYPE_RGBP ,
18
- isIntegerPixelFormat , FILTER_NEAREST , TEXTURELOCK_NONE , TEXTURELOCK_READ
18
+ isIntegerPixelFormat , FILTER_NEAREST , TEXTURELOCK_NONE , TEXTURELOCK_READ ,
19
+ TEXTUREDIMENSION_2D ,
20
+ TEXTUREDIMENSION_3D ,
21
+ TEXTUREDIMENSION_2D_ARRAY ,
22
+ TEXTUREDIMENSION_CUBE
19
23
} from './constants.js' ;
20
24
21
25
let id = 0 ;
@@ -101,7 +105,15 @@ class Texture {
101
105
* @param {string } [options.name] - The name of the texture. Defaults to null.
102
106
* @param {number } [options.width] - The width of the texture in pixels. Defaults to 4.
103
107
* @param {number } [options.height] - The height of the texture in pixels. Defaults to 4.
104
- * @param {number } [options.depth] - The number of depth slices in a 3D texture.
108
+ * @param {number } [options.slices] - The number of depth slices in a 3D texture, the number of textures
109
+ * in a texture array or the number of faces for a cubemap.
110
+ * @param {string } [options.dimension] - The texture dimension type. Can be:
111
+ * - {@link TEXTUREDIMENSION_2D}
112
+ * - {@link TEXTUREDIMENSION_2D_ARRAY}
113
+ * - {@link TEXTUREDIMENSION_3D}
114
+ * - {@link TEXTUREDIMENSION_CUBE}
115
+ * Defaults to {@link TEXTUREDIMENSION_2D}. Alternatively, you can specify the dimension using
116
+ * the options.cubemap, options.volume or options.array properties.
105
117
* @param {number } [options.format] - The pixel format of the texture. Can be:
106
118
*
107
119
* - {@link PIXELFORMAT_R8}
@@ -155,9 +167,8 @@ class Texture {
155
167
* texture. Default is true.
156
168
* @param {boolean } [options.cubemap] - Specifies whether the texture is to be a cubemap.
157
169
* Defaults to false.
158
- * @param {number } [options.arrayLength] - Specifies whether the texture is to be a 2D texture array.
159
- * When passed in as undefined or < 1, this is not an array texture. If >= 1, this is an array texture.
160
- * Defaults to undefined.
170
+ * @param {boolean } [options.array] - Specifies whether the texture is to be a 2D texture array.
171
+ * Defaults to false.
161
172
* @param {boolean } [options.volume] - Specifies whether the texture is to be a 3D volume.
162
173
* Defaults to false.
163
174
* @param {string } [options.type] - Specifies the texture type. Can be:
@@ -192,7 +203,7 @@ class Texture {
192
203
* Defaults to {@link FUNC_LESS}.
193
204
* @param {Uint8Array[]|HTMLCanvasElement[]|HTMLImageElement[]|HTMLVideoElement[]|Uint8Array[][] } [options.levels]
194
205
* - Array of Uint8Array or other supported browser interface; or a two-dimensional array
195
- * of Uint8Array if options.arrayLength is defined and greater than zero .
206
+ * of Uint8Array if options.dimension is { @link TEXTUREDIMENSION_2D_ARRAY} .
196
207
* @param {boolean } [options.storage] - Defines if texture can be used as a storage texture by
197
208
* a compute shader. Defaults to false.
198
209
* @param {boolean } [options.immediate] - If set and true, the texture will be uploaded to the GPU immediately.
@@ -221,13 +232,22 @@ class Texture {
221
232
Debug . assert ( this . device , "Texture constructor requires a graphicsDevice to be valid" ) ;
222
233
Debug . assert ( ! options . width || Number . isInteger ( options . width ) , "Texture width must be an integer number, got" , options ) ;
223
234
Debug . assert ( ! options . height || Number . isInteger ( options . height ) , "Texture height must be an integer number, got" , options ) ;
224
- Debug . assert ( ! options . depth || Number . isInteger ( options . depth ) , "Texture depth must be an integer number, got" , options ) ;
235
+ Debug . assert ( ! options . slices || Number . isInteger ( options . slices ) , "Texture slices must be an integer number, got" , options ) ;
225
236
226
237
this . name = options . name ?? '' ;
227
238
239
+ this . _dimension = options . dimension ?? TEXTUREDIMENSION_2D ;
240
+ this . _dimension = options . array ? TEXTUREDIMENSION_2D_ARRAY : this . _dimension ;
241
+ this . _dimension = options . cubemap ? TEXTUREDIMENSION_CUBE : this . _dimension ;
242
+ this . _dimension = options . volume ? TEXTUREDIMENSION_3D : this . _dimension ;
243
+
228
244
this . _width = Math . floor ( options . width ?? 4 ) ;
229
245
this . _height = Math . floor ( options . height ?? 4 ) ;
230
246
247
+ this . _slices = Math . floor ( options . slices ?? ( this . _dimension === TEXTUREDIMENSION_CUBE ? 6 : 1 ) ) ;
248
+
249
+ Debug . assert ( ( this . _dimension === TEXTUREDIMENSION_CUBE ? this . _slices === 6 : true ) , "Texture cube map must have 6 slices" ) ;
250
+
231
251
this . _format = options . format ?? PIXELFORMAT_RGBA8 ;
232
252
this . _compressed = isCompressedPixelFormat ( this . _format ) ;
233
253
this . _integerFormat = isIntegerPixelFormat ( this . _format ) ;
@@ -237,12 +257,7 @@ class Texture {
237
257
options . magFilter = FILTER_NEAREST ;
238
258
}
239
259
240
- this . _volume = options . volume ?? false ;
241
- this . _depth = Math . floor ( options . depth ?? 1 ) ;
242
- this . _arrayLength = Math . floor ( options . arrayLength ?? 0 ) ;
243
-
244
260
this . _storage = options . storage ?? false ;
245
- this . _cubemap = options . cubemap ?? false ;
246
261
this . _flipY = options . flipY ?? false ;
247
262
this . _premultiplyAlpha = options . premultiplyAlpha ?? false ;
248
263
@@ -262,7 +277,7 @@ class Texture {
262
277
Debug . assert ( ! options . hasOwnProperty ( 'swizzleGGGR' ) , 'Use options.type.' ) ;
263
278
264
279
this . projection = TEXTUREPROJECTION_NONE ;
265
- if ( this . _cubemap ) {
280
+ if ( this . cubemap ) {
266
281
this . projection = TEXTUREPROJECTION_CUBE ;
267
282
} else if ( options . projection && options . projection !== TEXTUREPROJECTION_CUBE ) {
268
283
this . projection = options . projection ;
@@ -280,7 +295,7 @@ class Texture {
280
295
if ( this . _levels ) {
281
296
this . upload ( options . immediate ?? false ) ;
282
297
} else {
283
- this . _levels = this . _cubemap ? [ [ null , null , null , null , null , null ] ] : [ null ] ;
298
+ this . _levels = this . cubemap ? [ [ null , null , null , null , null , null ] ] : [ null ] ;
284
299
}
285
300
286
301
// track the texture
@@ -328,10 +343,10 @@ class Texture {
328
343
*
329
344
* @param {number } width - The new width of the texture.
330
345
* @param {number } height - The new height of the texture.
331
- * @param {number } [depth ] - The new depth of the texture. Defaults to 1.
346
+ * @param {number } [slices ] - The new number of slices for the texture. Defaults to 1.
332
347
* @ignore
333
348
*/
334
- resize ( width , height , depth = 1 ) {
349
+ resize ( width , height , slices = 1 ) {
335
350
336
351
// destroy texture impl
337
352
const device = this . device ;
@@ -340,7 +355,7 @@ class Texture {
340
355
341
356
this . _width = Math . floor ( width ) ;
342
357
this . _height = Math . floor ( height ) ;
343
- this . _depth = Math . floor ( depth ) ;
358
+ this . _slices = Math . floor ( slices ) ;
344
359
345
360
// re-create the implementation
346
361
this . impl = device . createTextureImpl ( this ) ;
@@ -508,7 +523,7 @@ class Texture {
508
523
* @type {number }
509
524
*/
510
525
set addressW ( addressW ) {
511
- if ( ! this . _volume ) {
526
+ if ( ! this . volume ) {
512
527
Debug . warn ( "pc.Texture#addressW: Can't set W addressing mode for a non-3D texture." ) ;
513
528
return ;
514
529
}
@@ -637,7 +652,16 @@ class Texture {
637
652
* @type {number }
638
653
*/
639
654
get depth ( ) {
640
- return this . _depth ;
655
+ return this . _dimension === TEXTUREDIMENSION_3D ? this . _slices : 1 ;
656
+ }
657
+
658
+ /**
659
+ * The number of textures in a texture array or the number of faces for a cubemap.
660
+ *
661
+ * @type {number }
662
+ */
663
+ get slices ( ) {
664
+ return this . _slices ;
641
665
}
642
666
643
667
/**
@@ -679,12 +703,12 @@ class Texture {
679
703
* @type {boolean }
680
704
*/
681
705
get cubemap ( ) {
682
- return this . _cubemap ;
706
+ return this . _dimension === TEXTUREDIMENSION_CUBE ;
683
707
}
684
708
685
709
get gpuSize ( ) {
686
710
const mips = this . pot && this . _mipmaps && ! ( this . _compressed && this . _levels . length === 1 ) ;
687
- return TextureUtils . calcGpuSize ( this . _width , this . _height , this . _depth , this . _format , mips , this . _cubemap ) ;
711
+ return TextureUtils . calcGpuSize ( this . _width , this . _height , this . _slices , this . _format , this . volume , mips ) ;
688
712
}
689
713
690
714
/**
@@ -693,16 +717,7 @@ class Texture {
693
717
* @type {boolean }
694
718
*/
695
719
get array ( ) {
696
- return this . _arrayLength > 0 ;
697
- }
698
-
699
- /**
700
- * Returns the number of textures inside this texture if this is a 2D array texture or 0 otherwise.
701
- *
702
- * @type {number }
703
- */
704
- get arrayLength ( ) {
705
- return this . _arrayLength ;
720
+ return this . _dimension === TEXTUREDIMENSION_2D_ARRAY ;
706
721
}
707
722
708
723
/**
@@ -711,7 +726,7 @@ class Texture {
711
726
* @type {boolean }
712
727
*/
713
728
get volume ( ) {
714
- return this . _volume ;
729
+ return this . _dimension === TEXTUREDIMENSION_3D ;
715
730
}
716
731
717
732
/**
@@ -772,7 +787,7 @@ class Texture {
772
787
773
788
// Force a full resubmission of the texture to the GPU (used on a context restore event)
774
789
dirtyAll ( ) {
775
- this . _levelsUpdated = this . _cubemap ? [ [ true , true , true , true , true , true ] ] : [ true ] ;
790
+ this . _levelsUpdated = this . cubemap ? [ [ true , true , true , true , true , true ] ] : [ true ] ;
776
791
777
792
this . _needsUpload = true ;
778
793
this . _needsMipmapsUpload = this . _mipmaps ;
@@ -822,7 +837,7 @@ class Texture {
822
837
// allocate storage for this mip level
823
838
const width = Math . max ( 1 , this . _width >> options . level ) ;
824
839
const height = Math . max ( 1 , this . _height >> options . level ) ;
825
- const depth = Math . max ( 1 , this . _depth >> options . level ) ;
840
+ const depth = Math . max ( 1 , ( this . _dimension === TEXTUREDIMENSION_3D ? this . _slices : 1 ) >> options . level ) ;
826
841
const data = new ArrayBuffer ( TextureUtils . calcLevelGpuSize ( width , height , depth , this . _format ) ) ;
827
842
levels [ options . level ] = new ( getPixelFormatArrayType ( this . _format ) ) ( data ) ;
828
843
}
@@ -845,7 +860,7 @@ class Texture {
845
860
let invalid = false ;
846
861
let width , height ;
847
862
848
- if ( this . _cubemap ) {
863
+ if ( this . cubemap ) {
849
864
if ( source [ 0 ] ) {
850
865
// rely on first face sizes
851
866
width = source [ 0 ] . width || 0 ;
@@ -897,7 +912,7 @@ class Texture {
897
912
this . _height = 4 ;
898
913
899
914
// remove levels
900
- if ( this . _cubemap ) {
915
+ if ( this . cubemap ) {
901
916
for ( let i = 0 ; i < 6 ; i ++ ) {
902
917
this . _levels [ mipLevel ] [ i ] = null ;
903
918
this . _levelsUpdated [ mipLevel ] [ i ] = true ;
0 commit comments