@@ -42,14 +42,18 @@ enum {
42
42
DDSD_PITCH = 0x00000008 ,
43
43
DDSD_LINEARSIZE = 0x00080000 ,
44
44
DDSD_MIPMAPCOUNT = 0x00020000 ,
45
- DDPF_FOURCC = 0x00000004 ,
46
45
DDPF_ALPHAPIXELS = 0x00000001 ,
47
- DDPF_RGB = 0x00000040
46
+ DDPF_ALPHAONLY = 0x00000002 ,
47
+ DDPF_FOURCC = 0x00000004 ,
48
+ DDPF_RGB = 0x00000040 ,
49
+ DDPF_RG_SNORM = 0x00080000
48
50
};
49
51
50
52
enum DDSFourCC {
51
53
DDFCC_DXT1 = PF_FOURCC (" DXT1" ),
54
+ DDFCC_DXT2 = PF_FOURCC (" DXT2" ),
52
55
DDFCC_DXT3 = PF_FOURCC (" DXT3" ),
56
+ DDFCC_DXT4 = PF_FOURCC (" DXT4" ),
53
57
DDFCC_DXT5 = PF_FOURCC (" DXT5" ),
54
58
DDFCC_ATI1 = PF_FOURCC (" ATI1" ),
55
59
DDFCC_BC4U = PF_FOURCC (" BC4U" ),
@@ -68,17 +72,25 @@ enum DDSFourCC {
68
72
// Reference: https://learn.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format
69
73
enum DXGIFormat {
70
74
DXGI_R32G32B32A32_FLOAT = 2 ,
75
+ DXGI_R32G32B32_FLOAT = 6 ,
71
76
DXGI_R16G16B16A16_FLOAT = 10 ,
72
77
DXGI_R32G32_FLOAT = 16 ,
73
78
DXGI_R10G10B10A2_UNORM = 24 ,
74
79
DXGI_R8G8B8A8_UNORM = 28 ,
80
+ DXGI_R8G8B8A8_UNORM_SRGB = 29 ,
75
81
DXGI_R16G16_FLOAT = 34 ,
76
82
DXGI_R32_FLOAT = 41 ,
83
+ DXGI_R8G8_UNORM = 49 ,
77
84
DXGI_R16_FLOAT = 54 ,
85
+ DXGI_R8_UNORM = 61 ,
86
+ DXGI_A8_UNORM = 65 ,
78
87
DXGI_R9G9B9E5 = 67 ,
79
88
DXGI_BC1_UNORM = 71 ,
89
+ DXGI_BC1_UNORM_SRGB = 72 ,
80
90
DXGI_BC2_UNORM = 74 ,
91
+ DXGI_BC2_UNORM_SRGB = 75 ,
81
92
DXGI_BC3_UNORM = 77 ,
93
+ DXGI_BC3_UNORM_SRGB = 78 ,
82
94
DXGI_BC4_UNORM = 80 ,
83
95
DXGI_BC5_UNORM = 83 ,
84
96
DXGI_B5G6R5_UNORM = 85 ,
@@ -87,6 +99,7 @@ enum DXGIFormat {
87
99
DXGI_BC6H_UF16 = 95 ,
88
100
DXGI_BC6H_SF16 = 96 ,
89
101
DXGI_BC7_UNORM = 98 ,
102
+ DXGI_BC7_UNORM_SRGB = 99 ,
90
103
DXGI_B4G4R4A4_UNORM = 115
91
104
};
92
105
@@ -100,25 +113,29 @@ enum DDSFormat {
100
113
DDS_ATI2,
101
114
DDS_BC6U,
102
115
DDS_BC6S,
103
- DDS_BC7U ,
116
+ DDS_BC7 ,
104
117
DDS_R16F,
105
118
DDS_RG16F,
106
119
DDS_RGBA16F,
107
120
DDS_R32F,
108
121
DDS_RG32F,
122
+ DDS_RGB32F,
109
123
DDS_RGBA32F,
110
124
DDS_RGB9E5,
111
- DDS_BGRA8,
112
- DDS_BGR8,
113
- DDS_RGBA8,
114
125
DDS_RGB8,
126
+ DDS_RGBA8,
127
+ DDS_BGR8,
128
+ DDS_BGRA8,
115
129
DDS_BGR5A1,
116
130
DDS_BGR565,
131
+ DDS_B2GR3,
132
+ DDS_B2GR3A8,
117
133
DDS_BGR10A2,
118
134
DDS_RGB10A2,
119
135
DDS_BGRA4,
120
136
DDS_LUMINANCE,
121
137
DDS_LUMINANCE_ALPHA,
138
+ DDS_LUMINANCE_ALPHA_4,
122
139
DDS_MAX
123
140
};
124
141
@@ -132,38 +149,45 @@ struct DDSFormatInfo {
132
149
133
150
static const DDSFormatInfo dds_format_info[DDS_MAX] = {
134
151
{ " DXT1/BC1" , true , 4 , 8 , Image::FORMAT_DXT1 },
135
- { " DXT3/BC2" , true , 4 , 16 , Image::FORMAT_DXT3 },
136
- { " DXT5/BC3" , true , 4 , 16 , Image::FORMAT_DXT5 },
152
+ { " DXT2/ DXT3/BC2" , true , 4 , 16 , Image::FORMAT_DXT3 },
153
+ { " DXT4/ DXT5/BC3" , true , 4 , 16 , Image::FORMAT_DXT5 },
137
154
{ " ATI1/BC4" , true , 4 , 8 , Image::FORMAT_RGTC_R },
138
155
{ " ATI2/A2XY/BC5" , true , 4 , 16 , Image::FORMAT_RGTC_RG },
139
- { " BC6U " , true , 4 , 16 , Image::FORMAT_BPTC_RGBFU },
140
- { " BC6S " , true , 4 , 16 , Image::FORMAT_BPTC_RGBF },
141
- { " BC7U " , true , 4 , 16 , Image::FORMAT_BPTC_RGBA },
156
+ { " BC6UF " , true , 4 , 16 , Image::FORMAT_BPTC_RGBFU },
157
+ { " BC6SF " , true , 4 , 16 , Image::FORMAT_BPTC_RGBF },
158
+ { " BC7 " , true , 4 , 16 , Image::FORMAT_BPTC_RGBA },
142
159
{ " R16F" , false , 1 , 2 , Image::FORMAT_RH },
143
160
{ " RG16F" , false , 1 , 4 , Image::FORMAT_RGH },
144
161
{ " RGBA16F" , false , 1 , 8 , Image::FORMAT_RGBAH },
145
162
{ " R32F" , false , 1 , 4 , Image::FORMAT_RF },
146
163
{ " RG32F" , false , 1 , 8 , Image::FORMAT_RGF },
164
+ { " RGB32F" , false , 1 , 12 , Image::FORMAT_RGBF },
147
165
{ " RGBA32F" , false , 1 , 16 , Image::FORMAT_RGBAF },
148
166
{ " RGB9E5" , false , 1 , 4 , Image::FORMAT_RGBE9995 },
149
- { " BGRA8" , false , 1 , 4 , Image::FORMAT_RGBA8 },
150
- { " BGR8" , false , 1 , 3 , Image::FORMAT_RGB8 },
151
- { " RGBA8" , false , 1 , 4 , Image::FORMAT_RGBA8 },
152
167
{ " RGB8" , false , 1 , 3 , Image::FORMAT_RGB8 },
168
+ { " RGBA8" , false , 1 , 4 , Image::FORMAT_RGBA8 },
169
+ { " BGR8" , false , 1 , 3 , Image::FORMAT_RGB8 },
170
+ { " BGRA8" , false , 1 , 4 , Image::FORMAT_RGBA8 },
153
171
{ " BGR5A1" , false , 1 , 2 , Image::FORMAT_RGBA8 },
154
172
{ " BGR565" , false , 1 , 2 , Image::FORMAT_RGB8 },
173
+ { " B2GR3" , false , 1 , 1 , Image::FORMAT_RGB8 },
174
+ { " B2GR3A8" , false , 1 , 2 , Image::FORMAT_RGBA8 },
155
175
{ " BGR10A2" , false , 1 , 4 , Image::FORMAT_RGBA8 },
156
176
{ " RGB10A2" , false , 1 , 4 , Image::FORMAT_RGBA8 },
157
177
{ " BGRA4" , false , 1 , 2 , Image::FORMAT_RGBA8 },
158
178
{ " GRAYSCALE" , false , 1 , 1 , Image::FORMAT_L8 },
159
- { " GRAYSCALE_ALPHA" , false , 1 , 2 , Image::FORMAT_LA8 }
179
+ { " GRAYSCALE_ALPHA" , false , 1 , 2 , Image::FORMAT_LA8 },
180
+ { " GRAYSCALE_ALPHA_4" , false , 1 , 1 , Image::FORMAT_LA8 }
160
181
};
161
182
162
183
static DDSFormat dxgi_to_dds_format (uint32_t p_dxgi_format) {
163
184
switch (p_dxgi_format) {
164
185
case DXGI_R32G32B32A32_FLOAT: {
165
186
return DDS_RGBA32F;
166
187
}
188
+ case DXGI_R32G32B32_FLOAT: {
189
+ return DDS_RGB32F;
190
+ }
167
191
case DXGI_R16G16B16A16_FLOAT: {
168
192
return DDS_RGBA16F;
169
193
}
@@ -173,7 +197,8 @@ static DDSFormat dxgi_to_dds_format(uint32_t p_dxgi_format) {
173
197
case DXGI_R10G10B10A2_UNORM: {
174
198
return DDS_RGB10A2;
175
199
}
176
- case DXGI_R8G8B8A8_UNORM: {
200
+ case DXGI_R8G8B8A8_UNORM:
201
+ case DXGI_R8G8B8A8_UNORM_SRGB: {
177
202
return DDS_RGBA8;
178
203
}
179
204
case DXGI_R16G16_FLOAT: {
@@ -182,19 +207,29 @@ static DDSFormat dxgi_to_dds_format(uint32_t p_dxgi_format) {
182
207
case DXGI_R32_FLOAT: {
183
208
return DDS_R32F;
184
209
}
210
+ case DXGI_R8_UNORM:
211
+ case DXGI_A8_UNORM: {
212
+ return DDS_LUMINANCE;
213
+ }
185
214
case DXGI_R16_FLOAT: {
186
215
return DDS_R16F;
187
216
}
217
+ case DXGI_R8G8_UNORM: {
218
+ return DDS_LUMINANCE_ALPHA;
219
+ }
188
220
case DXGI_R9G9B9E5: {
189
221
return DDS_RGB9E5;
190
222
}
191
- case DXGI_BC1_UNORM: {
223
+ case DXGI_BC1_UNORM:
224
+ case DXGI_BC1_UNORM_SRGB: {
192
225
return DDS_DXT1;
193
226
}
194
- case DXGI_BC2_UNORM: {
227
+ case DXGI_BC2_UNORM:
228
+ case DXGI_BC2_UNORM_SRGB: {
195
229
return DDS_DXT3;
196
230
}
197
- case DXGI_BC3_UNORM: {
231
+ case DXGI_BC3_UNORM:
232
+ case DXGI_BC3_UNORM_SRGB: {
198
233
return DDS_DXT5;
199
234
}
200
235
case DXGI_BC4_UNORM: {
@@ -218,8 +253,9 @@ static DDSFormat dxgi_to_dds_format(uint32_t p_dxgi_format) {
218
253
case DXGI_BC6H_SF16: {
219
254
return DDS_BC6S;
220
255
}
221
- case DXGI_BC7_UNORM: {
222
- return DDS_BC7U;
256
+ case DXGI_BC7_UNORM:
257
+ case DXGI_BC7_UNORM_SRGB: {
258
+ return DDS_BC7;
223
259
}
224
260
case DXGI_B4G4R4A4_UNORM: {
225
261
return DDS_BGRA4;
@@ -299,9 +335,11 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig
299
335
case DDFCC_DXT1: {
300
336
dds_format = DDS_DXT1;
301
337
} break ;
338
+ case DDFCC_DXT2:
302
339
case DDFCC_DXT3: {
303
340
dds_format = DDS_DXT3;
304
341
} break ;
342
+ case DDFCC_DXT4:
305
343
case DDFCC_DXT5: {
306
344
dds_format = DDS_DXT5;
307
345
} break ;
@@ -363,6 +401,8 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig
363
401
dds_format = DDS_RGB10A2;
364
402
} else if (format_rgb_bits == 16 && format_red_mask == 0xf00 && format_green_mask == 0xf0 && format_blue_mask == 0xf && format_alpha_mask == 0xf000 ) {
365
403
dds_format = DDS_BGRA4;
404
+ } else if (format_rgb_bits == 16 && format_red_mask == 0xe0 && format_green_mask == 0x1c && format_blue_mask == 0x3 && format_alpha_mask == 0xff00 ) {
405
+ dds_format = DDS_B2GR3A8;
366
406
}
367
407
368
408
} else {
@@ -373,18 +413,38 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig
373
413
dds_format = DDS_RGB8;
374
414
} else if (format_rgb_bits == 16 && format_red_mask == 0x0000f800 && format_green_mask == 0x000007e0 && format_blue_mask == 0x0000001f ) {
375
415
dds_format = DDS_BGR565;
416
+ } else if (format_rgb_bits == 8 && format_red_mask == 0xe0 && format_green_mask == 0x1c && format_blue_mask == 0x3 ) {
417
+ dds_format = DDS_B2GR3;
376
418
}
377
419
}
378
420
379
421
} else {
380
422
// Other formats.
381
- if (format_flags & DDPF_ALPHAPIXELS && format_rgb_bits == 16 && format_red_mask == 0xff && format_alpha_mask == 0xff00 ) {
382
- dds_format = DDS_LUMINANCE_ALPHA;
383
- } else if (!(format_flags & DDPF_ALPHAPIXELS) && format_rgb_bits == 8 && format_red_mask == 0xff ) {
423
+ if (format_flags & DDPF_ALPHAONLY && format_rgb_bits == 8 && format_alpha_mask == 0xff ) {
424
+ // Alpha only.
384
425
dds_format = DDS_LUMINANCE;
385
426
}
386
427
}
387
428
429
+ // Depending on the writer, luminance formats may or may not have the DDPF_RGB or DDPF_LUMINANCE flags defined,
430
+ // so we check for these formats after everything else failed.
431
+ if (dds_format == DDS_MAX) {
432
+ if (format_flags & DDPF_ALPHAPIXELS) {
433
+ // With alpha.
434
+ if (format_rgb_bits == 16 && format_red_mask == 0xff && format_alpha_mask == 0xff00 ) {
435
+ dds_format = DDS_LUMINANCE_ALPHA;
436
+ } else if (format_rgb_bits == 8 && format_red_mask == 0xf && format_alpha_mask == 0xf0 ) {
437
+ dds_format = DDS_LUMINANCE_ALPHA_4;
438
+ }
439
+
440
+ } else {
441
+ // Without alpha.
442
+ if (format_rgb_bits == 8 && format_red_mask == 0xff ) {
443
+ dds_format = DDS_LUMINANCE;
444
+ }
445
+ }
446
+ }
447
+
388
448
// No format detected, error.
389
449
if (dds_format == DDS_MAX) {
390
450
ERR_FAIL_V_MSG (Ref<Resource>(), " Unrecognized or unsupported color layout in DDS '" + p_path + " '." );
@@ -433,10 +493,24 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig
433
493
}
434
494
435
495
// Calculate the space these formats will take up after decoding.
436
- if (dds_format == DDS_BGR565) {
437
- size = size * 3 / 2 ;
438
- } else if (dds_format == DDS_BGR5A1 || dds_format == DDS_BGRA4) {
439
- size = size * 2 ;
496
+ switch (dds_format) {
497
+ case DDS_BGR565:
498
+ size = size * 3 / 2 ;
499
+ break ;
500
+
501
+ case DDS_BGR5A1:
502
+ case DDS_BGRA4:
503
+ case DDS_B2GR3A8:
504
+ case DDS_LUMINANCE_ALPHA_4:
505
+ size = size * 2 ;
506
+ break ;
507
+
508
+ case DDS_B2GR3:
509
+ size = size * 3 ;
510
+ break ;
511
+
512
+ default :
513
+ break ;
440
514
}
441
515
442
516
src_data.resize (size);
@@ -502,6 +576,44 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig
502
576
wb[dst_ofs + 3 ] = a | (a >> 4 );
503
577
}
504
578
579
+ } break ;
580
+ case DDS_B2GR3: {
581
+ // To RGB8.
582
+ int colcount = size / 3 ;
583
+
584
+ for (int i = colcount - 1 ; i >= 0 ; i--) {
585
+ int src_ofs = i;
586
+ int dst_ofs = i * 3 ;
587
+
588
+ uint8_t b = (wb[src_ofs] & 0x3 ) << 6 ;
589
+ uint8_t g = (wb[src_ofs] & 0x1C ) << 3 ;
590
+ uint8_t r = (wb[src_ofs] & 0xE0 );
591
+
592
+ wb[dst_ofs] = r;
593
+ wb[dst_ofs + 1 ] = g;
594
+ wb[dst_ofs + 2 ] = b;
595
+ }
596
+
597
+ } break ;
598
+ case DDS_B2GR3A8: {
599
+ // To RGBA8.
600
+ int colcount = size / 4 ;
601
+
602
+ for (int i = colcount - 1 ; i >= 0 ; i--) {
603
+ int src_ofs = i * 2 ;
604
+ int dst_ofs = i * 4 ;
605
+
606
+ uint8_t b = (wb[src_ofs] & 0x3 ) << 6 ;
607
+ uint8_t g = (wb[src_ofs] & 0x1C ) << 3 ;
608
+ uint8_t r = (wb[src_ofs] & 0xE0 );
609
+ uint8_t a = wb[src_ofs + 1 ];
610
+
611
+ wb[dst_ofs] = r;
612
+ wb[dst_ofs + 1 ] = g;
613
+ wb[dst_ofs + 2 ] = b;
614
+ wb[dst_ofs + 3 ] = a;
615
+ }
616
+
505
617
} break ;
506
618
case DDS_RGB10A2: {
507
619
// To RGBA8.
@@ -549,6 +661,8 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig
549
661
}
550
662
551
663
} break ;
664
+
665
+ // Channel-swapped.
552
666
case DDS_BGRA8: {
553
667
// To RGBA8.
554
668
int colcount = size / 4 ;
@@ -568,6 +682,24 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig
568
682
569
683
} break ;
570
684
685
+ // Grayscale.
686
+ case DDS_LUMINANCE_ALPHA_4: {
687
+ // To LA8.
688
+ int colcount = size / 2 ;
689
+
690
+ for (int i = colcount - 1 ; i >= 0 ; i--) {
691
+ int src_ofs = i;
692
+ int dst_ofs = i * 2 ;
693
+
694
+ uint8_t l = wb[src_ofs] & 0x0F ;
695
+ uint8_t a = wb[src_ofs] & 0xF0 ;
696
+
697
+ wb[dst_ofs] = (l << 4 ) | l;
698
+ wb[dst_ofs + 1 ] = a | (a >> 4 );
699
+ }
700
+
701
+ } break ;
702
+
571
703
default : {
572
704
}
573
705
}
0 commit comments