2
// This unit is part of the GLScene Engine https://github.com/glscene
5
DXTC (also S3TC) decoding.
6
Adapted from DevIL image library (http://openil.sourceforge.net)
9
04/11/10 - DaStr - Restored Delphi5 and Delphi6 compatibility
10
23/08/10 - Yar - Replaced OpenGL1x to OpenGLTokens
11
05/03/10 - Yar - Added float types in GLEnumToDDSHeader
12
23/01/10 - Yar - Added more support DX9 DDS color formats
13
and DX11 DXGI constants to future
14
31/03/07 - DaStr - Added $I GLScene.inc
15
03/09/04 - SG - Delphi 5 compatibilty fixes (Ivan Lee Herring)
16
01/09/04 - SG - Creation
24
{$Z4} // Minimum enum size = dword
27
SysUtils, GLCrossPlatform, OpenGLTokens, GLTextureFormat;
30
DDSD_CAPS = $00000001;
31
DDSD_HEIGHT = $00000002;
32
DDSD_WIDTH = $00000004;
33
DDSD_PITCH = $00000008;
34
DDSD_PIXELFORMAT = $00001000;
35
DDSD_MIPMAPCOUNT = $00020000;
36
DDSD_LINEARSIZE = $00080000;
37
DDSD_DEPTH = $00800000;
39
DDPF_ALPHAPIXELS = $00000001;
41
DDPF_FOURCC = $00000004;
43
DDPF_RGBA = $00000041;
47
DDSCAPS_COMPLEX = $00000008;
48
DDSCAPS_TEXTURE = $00001000;
49
DDSCAPS_MIPMAP = $00400000;
51
DDSCAPS2_CUBEMAP = $00000200;
52
DDSCAPS2_CUBEMAP_POSITIVEX = $00000400;
53
DDSCAPS2_CUBEMAP_NEGATIVEX = $00000800;
54
DDSCAPS2_CUBEMAP_POSITIVEY = $00001000;
55
DDSCAPS2_CUBEMAP_NEGATIVEY = $00002000;
56
DDSCAPS2_CUBEMAP_POSITIVEZ = $00004000;
57
DDSCAPS2_CUBEMAP_NEGATIVEZ = $00008000;
58
DDSCAPS2_VOLUME = $00200000;
62
TDDPIXELFORMAT = record
70
dwRGBAlphaBitMask : Cardinal;
73
TDDSURFACEDESC2 = record
78
dwPitchOrLinearSize, { The number of bytes per scan line in an
79
uncompressed texture; the total number of bytes
80
in the top level texture for a compressed texture.}
82
dwMipMapCount : Cardinal;
83
dwReserved1 : array[0..10] of Cardinal;
84
ddpf : TDDPIXELFORMAT;
89
dwReserved2 : Cardinal;
94
SurfaceFormat : TDDSURFACEDESC2;
100
row: array[0..3] of GLubyte;
102
PDXTColBlock = ^DXTColBlock;
104
DXT3AlphaBlock = record
105
row: array[0..3] of GLushort;
107
PDXT3AlphaBlock = ^DXT3AlphaBlock;
109
DXT5AlphaBlock = record
112
row : array[0..5] of GLubyte;
114
PDXT5AlphaBlock = ^DXT5AlphaBlock;
119
DXGI_FORMAT_FORCE_UINT = -1;
120
DXGI_FORMAT_UNKNOWN = 0;
121
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1;
122
DXGI_FORMAT_R32G32B32A32_FLOAT = 2;
123
DXGI_FORMAT_R32G32B32A32_UINT = 3;
124
DXGI_FORMAT_R32G32B32A32_SINT = 4;
125
DXGI_FORMAT_R32G32B32_TYPELESS = 5;
126
DXGI_FORMAT_R32G32B32_FLOAT = 6;
127
DXGI_FORMAT_R32G32B32_UINT = 7;
128
DXGI_FORMAT_R32G32B32_SINT = 8;
129
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9;
130
DXGI_FORMAT_R16G16B16A16_FLOAT = 10;
131
DXGI_FORMAT_R16G16B16A16_UNORM = 11;
132
DXGI_FORMAT_R16G16B16A16_UINT = 12;
133
DXGI_FORMAT_R16G16B16A16_SNORM = 13;
134
DXGI_FORMAT_R16G16B16A16_SINT = 14;
135
DXGI_FORMAT_R32G32_TYPELESS = 15;
136
DXGI_FORMAT_R32G32_FLOAT = 16;
137
DXGI_FORMAT_R32G32_UINT = 17;
138
DXGI_FORMAT_R32G32_SINT = 18;
139
DXGI_FORMAT_R32G8X24_TYPELESS = 19;
140
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20;
141
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21;
142
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22;
143
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23;
144
DXGI_FORMAT_R10G10B10A2_UNORM = 24;
145
DXGI_FORMAT_R10G10B10A2_UINT = 25;
146
DXGI_FORMAT_R11G11B10_FLOAT = 26;
147
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27;
148
DXGI_FORMAT_R8G8B8A8_UNORM = 28;
149
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29;
150
DXGI_FORMAT_R8G8B8A8_UINT = 30;
151
DXGI_FORMAT_R8G8B8A8_SNORM = 31;
152
DXGI_FORMAT_R8G8B8A8_SINT = 32;
153
DXGI_FORMAT_R16G16_TYPELESS = 33;
154
DXGI_FORMAT_R16G16_FLOAT = 34;
155
DXGI_FORMAT_R16G16_UNORM = 35;
156
DXGI_FORMAT_R16G16_UINT = 36;
157
DXGI_FORMAT_R16G16_SNORM = 37;
158
DXGI_FORMAT_R16G16_SINT = 38;
159
DXGI_FORMAT_R32_TYPELESS = 39;
160
DXGI_FORMAT_D32_FLOAT = 40;
161
DXGI_FORMAT_R32_FLOAT = 41;
162
DXGI_FORMAT_R32_UINT = 42;
163
DXGI_FORMAT_R32_SINT = 43;
164
DXGI_FORMAT_R24G8_TYPELESS = 44;
165
DXGI_FORMAT_D24_UNORM_S8_UINT = 45;
166
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46;
167
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47;
168
DXGI_FORMAT_R8G8_TYPELESS = 48;
169
DXGI_FORMAT_R8G8_UNORM = 49;
170
DXGI_FORMAT_R8G8_UINT = 50;
171
DXGI_FORMAT_R8G8_SNORM = 51;
172
DXGI_FORMAT_R8G8_SINT = 52;
173
DXGI_FORMAT_R16_TYPELESS = 53;
174
DXGI_FORMAT_R16_FLOAT = 54;
175
DXGI_FORMAT_D16_UNORM = 55;
176
DXGI_FORMAT_R16_UNORM = 56;
177
DXGI_FORMAT_R16_UINT = 57;
178
DXGI_FORMAT_R16_SNORM = 58;
179
DXGI_FORMAT_R16_SINT = 59;
180
DXGI_FORMAT_R8_TYPELESS = 60;
181
DXGI_FORMAT_R8_UNORM = 61;
182
DXGI_FORMAT_R8_UINT = 62;
183
DXGI_FORMAT_R8_SNORM = 63;
184
DXGI_FORMAT_R8_SINT = 64;
185
DXGI_FORMAT_A8_UNORM = 65;
186
DXGI_FORMAT_R1_UNORM = 66;
187
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67;
188
DXGI_FORMAT_R8G8_B8G8_UNORM = 68;
189
DXGI_FORMAT_G8R8_G8B8_UNORM = 69;
190
DXGI_FORMAT_BC1_TYPELESS = 70;
191
DXGI_FORMAT_BC1_UNORM = 71;
192
DXGI_FORMAT_BC1_UNORM_SRGB = 72;
193
DXGI_FORMAT_BC2_TYPELESS = 73;
194
DXGI_FORMAT_BC2_UNORM = 74;
195
DXGI_FORMAT_BC2_UNORM_SRGB = 75;
196
DXGI_FORMAT_BC3_TYPELESS = 76;
197
DXGI_FORMAT_BC3_UNORM = 77;
198
DXGI_FORMAT_BC3_UNORM_SRGB = 78;
199
DXGI_FORMAT_BC4_TYPELESS = 79;
200
DXGI_FORMAT_BC4_UNORM = 80;
201
DXGI_FORMAT_BC4_SNORM = 81;
202
DXGI_FORMAT_BC5_TYPELESS = 82;
203
DXGI_FORMAT_BC5_UNORM = 83;
204
DXGI_FORMAT_BC5_SNORM = 84;
205
DXGI_FORMAT_B5G6R5_UNORM = 85;
206
DXGI_FORMAT_B5G5R5A1_UNORM = 86;
207
DXGI_FORMAT_B8G8R8A8_UNORM = 87;
208
DXGI_FORMAT_B8G8R8X8_UNORM = 88;
209
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89;
210
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90;
211
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91;
212
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92;
213
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93;
214
DXGI_FORMAT_BC6H_TYPELESS = 94;
215
DXGI_FORMAT_BC6H_UF16 = 95;
216
DXGI_FORMAT_BC6H_SF16 = 96;
217
DXGI_FORMAT_BC7_TYPELESS = 97;
218
DXGI_FORMAT_BC7_UNORM = 98;
219
DXGI_FORMAT_BC7_UNORM_SRGB = 99;
222
// TD3D11_RESOURCE_DIMENSION =
224
D3D11_RESOURCE_DIMENSION_UNKNOWN = 0;
225
D3D11_RESOURCE_DIMENSION_BUFFER = 1;
226
D3D11_RESOURCE_DIMENSION_TEXTURE1D = 2;
227
D3D11_RESOURCE_DIMENSION_TEXTURE2D = 3;
228
D3D11_RESOURCE_DIMENSION_TEXTURE3D = 4;
232
TDDS_HEADER_DXT10 = record
233
dxgiFormat : Integer; //TDXGI_FORMAT;
234
resourceDimension : Integer; //TD3D11_RESOURCE_DIMENSION;
236
arraySize : Cardinal;
240
TFOURCC = array[0..3] of AnsiChar;
245
FOURCC_A8R8G8B8 = 21;
246
FOURCC_X8R8G8B8 = 22;
248
FOURCC_X1R5G5B5 = 24;
249
FOURCC_A1R5G5B5 = 25;
250
FOURCC_A4R4G4B4 = 26;
253
FOURCC_A8R3G3B2 = 29;
254
FOURCC_X4R4G4B4 = 30;
255
FOURCC_A2B10G10R10 = 31;
256
FOURCC_A8B8G8R8 = 32;
257
FOURCC_X8B8G8R8 = 33;
259
FOURCC_A2R10G10B10 = 35;
260
FOURCC_A16B16G16R16 = 36;
265
FOURCC_DXT1 = $31545844;
266
FOURCC_DXT2 = $32545844;
267
FOURCC_DXT3 = $33545844;
268
FOURCC_DXT4 = $34545844;
269
FOURCC_DXT5 = $35545844;
270
FOURCC_ATI1 = $31495441;
271
FOURCC_ATI2 = $32495441;
273
FOURCC_D16_LOCKABLE = 70;
278
FOURCC_D32F_LOCKABLE = 82;
282
// Floating point surface formats
284
// s10e5 formats (16-bits per channel)
286
FOURCC_G16R16F = 112;
287
FOURCC_A16B16G16R16F = 113;
289
// IEEE s23e8 formats (32-bits per channel)
291
FOURCC_G32R32F = 115;
292
FOURCC_A32B32G32R32F = 116;
294
// DX10 header indicator
295
FOURCC_DX10 = $47495844;
298
TGLImageDataFormat = record
300
RBits, GBits, BBits, ABits: Cardinal;
302
TexFormat: TGLInternalFormat;
307
cImageDataFormat8bits: array[0..3] of TGLImageDataFormat = (
308
(ColorFlag: DDPF_RGB;
314
TexFormat: tfR3_G3_B2;
315
dType: GL_UNSIGNED_BYTE_3_3_2),
322
colorFormat: GL_LUMINANCE_ALPHA;
323
TexFormat: tfLUMINANCE4_ALPHA4;
324
dType: GL_UNSIGNED_BYTE),
331
colorFormat: GL_ALPHA;
333
dType: GL_UNSIGNED_BYTE),
340
colorFormat: GL_LUMINANCE;
341
TexFormat: tfLUMINANCE8;
342
dType: GL_UNSIGNED_BYTE)
345
cImageDataFormat16bits: array[0..4] of TGLImageDataFormat = (
346
(ColorFlag: DDPF_RGBA;
351
colorFormat: GL_BGRA;
353
dType: GL_UNSIGNED_SHORT_4_4_4_4_REV),
355
(ColorFlag: DDPF_RGB;
362
dType: GL_UNSIGNED_SHORT_5_6_5),
369
colorFormat: GL_LUMINANCE;
370
TexFormat: tfLUMINANCE16;
371
dType: GL_UNSIGNED_SHORT),
378
colorFormat: GL_LUMINANCE_ALPHA;
379
TexFormat: tfLUMINANCE8_ALPHA8;
380
dType: GL_UNSIGNED_BYTE),
382
(ColorFlag: DDPF_RGBA;
387
colorFormat: GL_BGRA;
388
TexFormat: tfRGB5_A1;
389
dType: GL_UNSIGNED_SHORT_1_5_5_5_REV)
392
cImageDataFormat24bits: array[0..0] of TGLImageDataFormat = (
393
(ColorFlag: DDPF_RGB;
400
dType: GL_UNSIGNED_BYTE)
403
cImageDataFormat32bits: array[0..6] of TGLImageDataFormat = (
404
(ColorFlag: DDPF_RGBA;
409
colorFormat: GL_RGBA;
411
dType: GL_UNSIGNED_BYTE),
413
(ColorFlag: DDPF_RGBA;
418
colorFormat: GL_BGRA;
420
dType: GL_UNSIGNED_BYTE),
422
(ColorFlag: DDPF_RGBA;
427
colorFormat: GL_RGBA;
428
TexFormat: tfRGB10_A2;
429
dType: GL_UNSIGNED_INT_2_10_10_10_REV),
431
(ColorFlag: DDPF_RGBA;
436
colorFormat: GL_BGRA;
437
TexFormat: tfRGB10_A2;
438
dType: GL_UNSIGNED_INT_2_10_10_10_REV),
440
(ColorFlag: DDPF_RGBA;
445
colorFormat: GL_BGRA;
447
dType: GL_UNSIGNED_INT_8_8_8_8),
449
(ColorFlag: DDPF_RGBA;
454
colorFormat: GL_RGBA;
456
dType: GL_UNSIGNED_INT_8_8_8_8),
458
(ColorFlag: DDPF_RGB;
465
dType: GL_UNSIGNED_SHORT)
468
procedure DecodeDXT1toBitmap32(
469
encData, decData : PByteArray;
470
w,h : Integer; var trans : Boolean);
471
procedure DecodeDXT3toBitmap32(encData, decData : PByteArray; w,h : Integer);
472
procedure DecodeDXT5toBitmap32(encData, decData : PByteArray; w,h : Integer);
473
procedure flip_blocks_dxtc1( data : PGLubyte; numBlocks: integer);
474
procedure flip_blocks_dxtc3( data : PGLubyte; numBlocks: integer);
475
procedure flip_blocks_dxtc5( data : PGLubyte; numBlocks: integer);
476
procedure flip_dxt5_alpha ( block : PDXT5AlphaBlock);
478
function DDSHeaderToGLEnum(const DX9header: TDDSHeader;
479
const DX11header: TDDS_HEADER_DXT10;
480
const useDX11: Boolean;
481
out iFormat: TGLInternalFormat;
482
out colorFormat: GLEnum;
483
out dataType: GLenum;
484
out bpe: Integer): Boolean;
486
function GLEnumToDDSHeader(var DX9header: TDDSHeader;
487
var DX11header: TDDS_HEADER_DXT10;
488
const useDX11: Boolean;
489
const iFormat: TGLInternalFormat;
490
const colorFormat: GLEnum;
491
const dataType: GLenum;
492
const bpe: Integer): Boolean;
494
function FindDDSCompatibleDataFormat(const iFormat: TGLInternalFormat;
495
out colorFormat: TGLEnum;
496
out dataType: TGLEnum): Boolean;
500
procedure DecodeColor565(col : Word; var r,g,b : Byte);
503
g:=(col shr 5) and $3F;
504
b:=(col shr 11) and $1F;
507
// DecodeDXT1toBitmap32
509
procedure DecodeDXT1toBitmap32(
510
encData, decData : PByteArray;
511
w,h : Integer; var trans : Boolean);
513
x,y,i,j,k,select : Integer;
515
colors : array[0..3] of array[0..3] of Byte;
518
r0,g0,b0,r1,g1,b1 : Byte;
522
if not (Assigned(encData) and Assigned(decData)) then exit;
524
temp:=PGLubyte(encData);
525
for y:=0 to (h div 4)-1 do begin
526
for x:=0 to (w div 4)-1 do begin
527
col0:=PWord(temp)^; Inc(temp, 2);
528
col1:=PWord(temp)^; Inc(temp, 2);
529
bitmask:=PCardinal(temp)^; Inc(temp, 4);
531
DecodeColor565(col0,r0,g0,b0);
532
DecodeColor565(col1,r1,g1,b1);
534
colors[0][0]:=r0 shl 3;
535
colors[0][1]:=g0 shl 2;
536
colors[0][2]:=b0 shl 3;
538
colors[1][0]:=r1 shl 3;
539
colors[1][1]:=g1 shl 2;
540
colors[1][2]:=b1 shl 3;
543
if col0>col1 then begin
544
colors[2][0]:=(2*colors[0][0]+colors[1][0]+1) div 3;
545
colors[2][1]:=(2*colors[0][1]+colors[1][1]+1) div 3;
546
colors[2][2]:=(2*colors[0][2]+colors[1][2]+1) div 3;
548
colors[3][0]:=(colors[0][0]+2*colors[1][0]+1) div 3;
549
colors[3][1]:=(colors[0][1]+2*colors[1][1]+1) div 3;
550
colors[3][2]:=(colors[0][2]+2*colors[1][2]+1) div 3;
554
colors[2][0]:=(colors[0][0]+colors[1][0]) div 2;
555
colors[2][1]:=(colors[0][1]+colors[1][1]) div 2;
556
colors[2][2]:=(colors[0][2]+colors[1][2]) div 2;
558
colors[3][0]:=(colors[0][0]+2*colors[1][0]+1) div 3;
559
colors[3][1]:=(colors[0][1]+2*colors[1][1]+1) div 3;
560
colors[3][2]:=(colors[0][2]+2*colors[1][2]+1) div 3;
565
for j:=0 to 3 do begin
566
for i:=0 to 3 do begin
567
select:=(bitmask and (3 shl (k*2))) shr (k*2);
568
if ((4*x+i)<w) and ((4*y+j)<h) then
569
PCardinal(@decData[((4*y+j)*w+(4*x+i))*4])^:=Cardinal(colors[select]);
578
// DecodeDXT3toBitmap32
580
procedure DecodeDXT3toBitmap32(encData, decData : PByteArray; w,h : Integer);
582
x,y,i,j,k,select : Integer;
583
col0, col1, wrd : Word;
584
colors : array[0..3] of array[0..3] of Byte;
585
bitmask, offset : Cardinal;
587
r0,g0,b0,r1,g1,b1 : Byte;
588
alpha : array[0..3] of Word;
590
if not (Assigned(encData) and Assigned(decData)) then exit;
592
temp:=PGLubyte(encData);
593
for y:=0 to (h div 4)-1 do begin
594
for x:=0 to (w div 4)-1 do begin
595
alpha[0]:=PWord(temp)^; Inc(temp, 2);
596
alpha[1]:=PWord(temp)^; Inc(temp, 2);
597
alpha[2]:=PWord(temp)^; Inc(temp, 2);
598
alpha[3]:=PWord(temp)^; Inc(temp, 2);
599
col0:=PWord(temp)^; Inc(temp, 2);
600
col1:=PWord(temp)^; Inc(temp, 2);
601
bitmask:=PCardinal(temp)^; Inc(temp, 4);
603
DecodeColor565(col0,r0,g0,b0);
604
DecodeColor565(col1,r1,g1,b1);
606
colors[0][0]:=r0 shl 3;
607
colors[0][1]:=g0 shl 2;
608
colors[0][2]:=b0 shl 3;
610
colors[1][0]:=r1 shl 3;
611
colors[1][1]:=g1 shl 2;
612
colors[1][2]:=b1 shl 3;
614
colors[2][0]:=(2*colors[0][0]+colors[1][0]+1) div 3;
615
colors[2][1]:=(2*colors[0][1]+colors[1][1]+1) div 3;
616
colors[2][2]:=(2*colors[0][2]+colors[1][2]+1) div 3;
618
colors[3][0]:=(colors[0][0]+2*colors[1][0]+1) div 3;
619
colors[3][1]:=(colors[0][1]+2*colors[1][1]+1) div 3;
620
colors[3][2]:=(colors[0][2]+2*colors[1][2]+1) div 3;
624
for j:=0 to 3 do begin
625
for i:=0 to 3 do begin
626
select:=(bitmask and (3 shl (k*2))) shr (k*2);
627
if ((4*x+i)<w) and ((4*y+j)<h) then
628
PCardinal(@decData[((4*y+j)*w+(4*x+i))*4])^:=Cardinal(colors[select]);
633
for j:=0 to 3 do begin
635
for i:=0 to 3 do begin
636
if (((4*x+i)<w) and ((4*y+j)<h)) then begin
637
offset:=((4*y+j)*w+(4*x+i))*4+3;
638
decData[offset]:=wrd and $0F;
639
decData[offset]:=decData[offset] or (decData[offset] shl 4);
649
// DecodeDXT5toBitmap32
651
procedure DecodeDXT5toBitmap32(encData, decData : PByteArray; w,h : Integer);
653
x,y,i,j,k,select : Integer;
655
colors : array[0..3] of array[0..3] of Byte;
656
bits, bitmask, offset : Cardinal;
657
temp, alphamask : PGLubyte;
658
r0,g0,b0,r1,g1,b1 : Byte;
659
alphas : array[0..7] of Byte;
661
if not (Assigned(encData) and Assigned(decData)) then exit;
663
temp:=PGLubyte(encData);
664
for y:=0 to (h div 4)-1 do begin
665
for x:=0 to (w div 4)-1 do begin
666
alphas[0]:=temp^; Inc(temp);
667
alphas[1]:=temp^; Inc(temp);
668
alphamask:=temp; Inc(temp, 6);
669
col0:=PWord(temp)^; Inc(temp, 2);
670
col1:=PWord(temp)^; Inc(temp, 2);
671
bitmask:=PCardinal(temp)^; Inc(temp, 4);
673
DecodeColor565(col0,r0,g0,b0);
674
DecodeColor565(col1,r1,g1,b1);
676
colors[0][0]:=r0 shl 3;
677
colors[0][1]:=g0 shl 2;
678
colors[0][2]:=b0 shl 3;
680
colors[1][0]:=r1 shl 3;
681
colors[1][1]:=g1 shl 2;
682
colors[1][2]:=b1 shl 3;
684
colors[2][0]:=(2*colors[0][0]+colors[1][0]+1) div 3;
685
colors[2][1]:=(2*colors[0][1]+colors[1][1]+1) div 3;
686
colors[2][2]:=(2*colors[0][2]+colors[1][2]+1) div 3;
688
colors[3][0]:=(colors[0][0]+2*colors[1][0]+1) div 3;
689
colors[3][1]:=(colors[0][1]+2*colors[1][1]+1) div 3;
690
colors[3][2]:=(colors[0][2]+2*colors[1][2]+1) div 3;
694
for j:=0 to 3 do begin
695
for i:=0 to 3 do begin
696
select:=(bitmask and (3 shl (k*2))) shr (k*2);
697
if ((4*x+i)<w) and ((4*y+j)<h) then
698
PCardinal(@decData[((4*y+j)*w+(4*x+i))*4])^:=Cardinal(colors[select]);
703
if (alphas[0] > alphas[1]) then begin
704
alphas[2]:=(6*alphas[0]+1*alphas[1]+3) div 7;
705
alphas[3]:=(5*alphas[0]+2*alphas[1]+3) div 7;
706
alphas[4]:=(4*alphas[0]+3*alphas[1]+3) div 7;
707
alphas[5]:=(3*alphas[0]+4*alphas[1]+3) div 7;
708
alphas[6]:=(2*alphas[0]+5*alphas[1]+3) div 7;
709
alphas[7]:=(1*alphas[0]+6*alphas[1]+3) div 7;
711
alphas[2]:=(4*alphas[0]+1*alphas[1]+2) div 5;
712
alphas[3]:=(3*alphas[0]+2*alphas[1]+2) div 5;
713
alphas[4]:=(2*alphas[0]+3*alphas[1]+2) div 5;
714
alphas[5]:=(1*alphas[0]+4*alphas[1]+2) div 5;
719
bits:=PCardinal(alphamask)^;
720
for j:=0 to 1 do begin
721
for i:=0 to 3 do begin
722
if (((4*x+i)<w) and ((4*y+j)<h)) then begin
723
offset:=((4*y+j)*w+(4*x+i))*4+3;
724
decData[Offset]:=alphas[bits and 7];
731
bits:=PCardinal(alphamask)^;
732
for j:=2 to 3 do begin
733
for i:=0 to 3 do begin
734
if (((4*x+i)<w) and ((4*y+j)<h)) then begin
735
offset:=((4*y+j)*w+(4*x+i))*4+3;
736
decData[offset]:=alphas[bits and 7];
746
// flip a DXT1 color block
747
////////////////////////////////////////////////////////////
748
procedure flip_blocks_dxtc1( data : PGLubyte; numBlocks: integer);
750
curblock : PDXTColBlock;
754
curblock := PDXTColBlock( data );
755
for i := 0 to numBlocks-1 do begin
756
temp := curblock.row[0];
757
curblock.row[0] := curblock.row[3];
758
curblock.row[3] := temp;
759
temp := curblock.row[1];
760
curblock.row[1] := curblock.row[2];
761
curblock.row[2] := temp;
767
// flip a DXT3 color block
768
////////////////////////////////////////////////////////////
769
procedure flip_blocks_dxtc3( data: PGLubyte; numBlocks: integer );
771
curblock : PDXTColBlock;
772
alphablock : PDXT3AlphaBlock;
777
curblock := PDXTColBlock( data );
778
for i := 0 to numBlocks-1 do
780
alphablock := PDXT3AlphaBlock( curblock );
782
tempS := alphablock.row[0];
783
alphablock.row[0] := alphablock.row[3];
784
alphablock.row[3] := tempS;
785
tempS := alphablock.row[1];
786
alphablock.row[1] := alphablock.row[2];
787
alphablock.row[2] := tempS;
791
tempB := curblock.row[0];
792
curblock.row[0] := curblock.row[3];
793
curblock.row[3] := tempB;
794
tempB := curblock.row[1];
795
curblock.row[1] := curblock.row[2];
796
curblock.row[2] := tempB;
803
// flip a DXT5 alpha block
804
////////////////////////////////////////////////////////////
805
procedure flip_dxt5_alpha( block : PDXT5AlphaBlock);
807
mask = $00000007; // bits = 00 00 01 11
809
gBits : array[0..3, 0..3] of GLubyte;
813
Move(block.row[0], bits, sizeof(GLubyte) * 3);
815
gBits[0][0] := GLubyte(bits and mask);
817
gBits[0][1] := GLubyte(bits and mask);
819
gBits[0][2] := GLubyte(bits and mask);
821
gBits[0][3] := GLubyte(bits and mask);
823
gBits[1][0] := GLubyte(bits and mask);
825
gBits[1][1] := GLubyte(bits and mask);
827
gBits[1][2] := GLubyte(bits and mask);
829
gBits[1][3] := GLubyte(bits and mask);
832
Move(block.row[3], bits, sizeof(GLubyte) * 3);
834
gBits[2][0] := GLubyte(bits and mask);
836
gBits[2][1] := GLubyte(bits and mask);
838
gBits[2][2] := GLubyte(bits and mask);
840
gBits[2][3] := GLubyte(bits and mask);
842
gBits[3][0] := GLubyte(bits and mask);
844
gBits[3][1] := GLubyte(bits and mask);
846
gBits[3][2] := GLubyte(bits and mask);
848
gBits[3][3] := GLubyte(bits and mask);
850
// clear existing alpha bits
851
FillChar( block.row, sizeof(GLubyte) * 6, 0);
853
bits := block.row[0]+block.row[1]*$100+block.row[2]*$10000;
855
bits := bits or (gBits[3][0] shl 0);
856
bits := bits or (gBits[3][1] shl 3);
857
bits := bits or (gBits[3][2] shl 6);
858
bits := bits or (gBits[3][3] shl 9);
860
bits := bits or (gBits[2][0] shl 12);
861
bits := bits or (gBits[2][1] shl 15);
862
bits := bits or (gBits[2][2] shl 18);
863
bits := bits or (gBits[2][3] shl 21);
865
block.row[0] := bits and $FF;
866
block.row[1] := (bits shr 8) and $FF;
867
block.row[2] := (bits shr 16) and $FF;
869
bits := block.row[3]+block.row[4]*$100+block.row[5]*$10000;
871
bits := bits or (gBits[1][0] shl 0);
872
bits := bits or (gBits[1][1] shl 3);
873
bits := bits or (gBits[1][2] shl 6);
874
bits := bits or (gBits[1][3] shl 9);
876
bits := bits or (gBits[0][0] shl 12);
877
bits := bits or (gBits[0][1] shl 15);
878
bits := bits or (gBits[0][2] shl 18);
879
bits := bits or (gBits[0][3] shl 21);
881
block.row[3] := bits and $FF;
882
block.row[4] := (bits shr 8) and $FF;
883
block.row[5] := (bits shr 16) and $FF;
887
// flip a DXT5 color block
888
////////////////////////////////////////////////////////////
889
procedure flip_blocks_dxtc5( data: PGLubyte; numBlocks: integer );
891
curblock : PDXTColBlock;
895
curblock := PDXTColBlock( data );
896
for i := 0 to numBlocks-1 do
898
flip_dxt5_alpha( PDXT5AlphaBlock( curblock ) );
900
temp := curblock.row[0];
901
curblock.row[0] := curblock.row[3];
902
curblock.row[3] := temp;
903
temp := curblock.row[1];
904
curblock.row[1] := curblock.row[2];
905
curblock.row[2] := temp;
910
function DDSHeaderToGLEnum(const DX9header: TDDSHeader;
911
const DX11header: TDDS_HEADER_DXT10;
912
const useDX11: Boolean;
913
out iFormat: TGLInternalFormat;
914
out colorFormat: GLEnum;
915
out dataType: GLenum;
916
out bpe: Integer): Boolean;
923
Assert(false, 'DXGI images not supported.');
927
// figure out what the image format is
928
if (DX9header.SurfaceFormat.ddpf.dwFlags and DDPF_FOURCC)<>0 then
930
case DX9header.SurfaceFormat.ddpf.dwFourCC of
933
colorFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
934
iFormat := tfCOMPRESSED_RGBA_S3TC_DXT1;
935
dataType := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
938
FOURCC_DXT2, FOURCC_DXT3:
940
colorFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
941
iFormat := tfCOMPRESSED_RGBA_S3TC_DXT3;
942
dataType := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
945
FOURCC_DXT4, FOURCC_DXT5:
947
colorFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
948
iFormat := tfCOMPRESSED_RGBA_S3TC_DXT5;
949
dataType := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
954
colorFormat := GL_COMPRESSED_RED_RGTC1;
955
iFormat := tfCOMPRESSED_RED_RGTC1;
956
dataType := GL_COMPRESSED_RED_RGTC1;
961
colorFormat := GL_COMPRESSED_RG_RGTC2;
962
iFormat := tfCOMPRESSED_RG_RGTC2;
963
dataType := GL_COMPRESSED_RG_RGTC2;
968
colorFormat := GL_BGR;
970
dataType := GL_UNSIGNED_BYTE;
975
colorFormat := GL_BGRA;
977
dataType := GL_UNSIGNED_BYTE;
982
colorFormat := GL_BGRA;
984
dataType := GL_UNSIGNED_INT_8_8_8_8;
989
colorFormat := GL_RGB;
991
dataType := GL_UNSIGNED_SHORT_5_6_5;
996
colorFormat := GL_ALPHA;
998
dataType := GL_UNSIGNED_BYTE;
1003
colorFormat := GL_RGBA;
1004
iFormat := tfRGB10_A2;
1005
dataType := GL_UNSIGNED_INT_10_10_10_2;
1010
colorFormat := GL_RGBA;
1012
dataType := GL_UNSIGNED_BYTE;
1017
colorFormat := GL_RGBA;
1019
dataType := GL_UNSIGNED_INT_8_8_8_8;
1024
colorFormat := GL_BGRA;
1025
iFormat := tfRGB10_A2;
1026
dataType := GL_UNSIGNED_INT_10_10_10_2;
1029
FOURCC_A16B16G16R16:
1031
colorFormat := GL_RGBA;
1032
iFormat := tfR16G16B16A16;
1033
dataType := GL_UNSIGNED_SHORT;
1038
colorFormat := GL_LUMINANCE;
1039
iFormat := tfLUMINANCE8;
1040
dataType := GL_UNSIGNED_BYTE;
1045
colorFormat := GL_LUMINANCE_ALPHA;
1046
iFormat := tfLUMINANCE8_ALPHA8;
1047
dataType := GL_UNSIGNED_BYTE;
1052
colorFormat := GL_LUMINANCE;
1053
iFormat := tfLUMINANCE16;
1054
dataType := GL_UNSIGNED_SHORT;
1059
colorFormat := GL_RED;
1060
iFormat := tfLUMINANCE_FLOAT16;
1061
dataType := GL_HALF_FLOAT_ARB;
1064
FOURCC_A16B16G16R16F:
1066
colorFormat := GL_RGBA;
1067
iFormat := tfRGBA_FLOAT16;
1068
dataType := GL_HALF_FLOAT_ARB;
1073
colorFormat := GL_RED;
1074
iFormat := tfLUMINANCE_FLOAT32;
1075
dataType := GL_FLOAT;
1080
colorFormat := GL_RG;
1082
dataType := GL_UNSIGNED_SHORT;
1087
colorFormat := GL_RG;
1089
dataType := GL_HALF_FLOAT;
1094
colorFormat := GL_RG;
1096
dataType := GL_FLOAT;
1107
FOURCC_D16_LOCKABLE,
1111
FOURCC_D32F_LOCKABLE: Result := false; //these are unsupported for now
1116
with DX9header.SurfaceFormat.ddpf do
1117
case dwRGBBitCount of
1119
for i := 0 to High(cImageDataFormat8bits) do
1120
if (cImageDataFormat8bits[i].ColorFlag = dwFlags)
1121
and (cImageDataFormat8bits[i].RBits = dwRBitMask)
1122
and (cImageDataFormat8bits[i].GBits = dwGBitMask)
1123
and (cImageDataFormat8bits[i].BBits = dwBBitMask)
1124
and (cImageDataFormat8bits[i].ABits = dwRGBAlphaBitMask) then
1126
colorFormat := cImageDataFormat8bits[i].colorFormat;
1127
iFormat := cImageDataFormat8bits[i].TexFormat;
1128
dataType := cImageDataFormat8bits[i].dType;
1135
for i := 0 to High(cImageDataFormat16bits) do
1136
if (cImageDataFormat16bits[i].ColorFlag = dwFlags)
1137
and (cImageDataFormat16bits[i].RBits = dwRBitMask)
1138
and (cImageDataFormat16bits[i].GBits = dwGBitMask)
1139
and (cImageDataFormat16bits[i].BBits = dwBBitMask)
1140
and (cImageDataFormat16bits[i].ABits = dwRGBAlphaBitMask) then
1142
colorFormat := cImageDataFormat16bits[i].colorFormat;
1143
iFormat := cImageDataFormat16bits[i].TexFormat;
1144
dataType := cImageDataFormat16bits[i].dType;
1151
for i := 0 to High(cImageDataFormat24bits) do
1152
if (cImageDataFormat24bits[i].ColorFlag = dwFlags)
1153
and (cImageDataFormat24bits[i].RBits = dwRBitMask)
1154
and (cImageDataFormat24bits[i].GBits = dwGBitMask)
1155
and (cImageDataFormat24bits[i].BBits = dwBBitMask)
1156
and (cImageDataFormat24bits[i].ABits = dwRGBAlphaBitMask) then
1158
colorFormat := cImageDataFormat24bits[i].colorFormat;
1159
iFormat := cImageDataFormat24bits[i].TexFormat;
1160
dataType := cImageDataFormat24bits[i].dType;
1167
for i := 0 to High(cImageDataFormat32bits) do
1168
if (cImageDataFormat32bits[i].ColorFlag = dwFlags)
1169
and (cImageDataFormat32bits[i].RBits = dwRBitMask)
1170
and (cImageDataFormat32bits[i].GBits = dwGBitMask)
1171
and (cImageDataFormat32bits[i].BBits = dwBBitMask)
1172
and (cImageDataFormat32bits[i].ABits = dwRGBAlphaBitMask) then
1174
colorFormat := cImageDataFormat32bits[i].colorFormat;
1175
iFormat := cImageDataFormat32bits[i].TexFormat;
1176
dataType := cImageDataFormat32bits[i].dType;
1182
else Result := false;
1187
function GLEnumToDDSHeader(var DX9header: TDDSHeader;
1188
var DX11header: TDDS_HEADER_DXT10;
1189
const useDX11: Boolean;
1190
const iFormat: TGLInternalFormat;
1191
const colorFormat: GLEnum;
1192
const dataType: GLenum;
1193
const bpe: Integer): Boolean;
1200
Assert(false, 'DXGI images not supported.');
1203
if IsCompressedFormat(iFormat) then
1205
with DX9header.SurfaceFormat.ddpf do
1207
dwFlags := DDPF_FOURCC;
1209
tfCOMPRESSED_RGB_S3TC_DXT1: dwFourCC := FOURCC_DXT1;
1210
tfCOMPRESSED_RGBA_S3TC_DXT1: dwFourCC := FOURCC_DXT1;
1211
tfCOMPRESSED_RGBA_S3TC_DXT3: dwFourCC := FOURCC_DXT3;
1212
tfCOMPRESSED_RGBA_S3TC_DXT5: dwFourCC := FOURCC_DXT5;
1213
tfCOMPRESSED_LUMINANCE_LATC1: dwFourCC := FOURCC_ATI1;
1214
tfCOMPRESSED_LUMINANCE_ALPHA_LATC2: dwFourCC := FOURCC_ATI2;
1215
else Result := false;
1219
else if IsFloatFormat(iFormat) then
1221
with DX9header.SurfaceFormat.ddpf do
1223
dwFlags := DDPF_FOURCC;
1225
tfINTENSITY_FLOAT16,
1226
tfLUMINANCE_FLOAT16,
1227
tfR16F: dwFourCC := FOURCC_R16F;
1228
tfRGBA_FLOAT16: dwFourCC := FOURCC_A16B16G16R16F;
1229
tfINTENSITY_FLOAT32,
1230
tfLUMINANCE_FLOAT32,
1231
tfR32F: dwFourCC := FOURCC_R32F;
1232
tfLUMINANCE_ALPHA_FLOAT16,
1233
tfRG16F: dwFourCC := FOURCC_G16R16F;
1234
tfLUMINANCE_ALPHA_FLOAT32,
1235
tfRG32F: dwFourCC := FOURCC_G32R32F;
1236
tfRGBA_FLOAT32: dwFourCC := FOURCC_A32B32G32R32F
1237
else Result := false;
1241
else with DX9header.SurfaceFormat.ddpf do
1244
dwRGBBitCount := bpe * 8;
1247
for i := 0 to High(cImageDataFormat8bits) do
1248
if (cImageDataFormat8bits[i].colorFormat = colorFormat)
1249
and (cImageDataFormat8bits[i].TexFormat = iFormat)
1250
and (cImageDataFormat8bits[i].dType = dataType) then
1252
dwFlags := cImageDataFormat8bits[i].ColorFlag;
1253
dwRBitMask := cImageDataFormat8bits[i].RBits;
1254
dwGBitMask := cImageDataFormat8bits[i].GBits;
1255
dwBBitMask := cImageDataFormat8bits[i].BBits;
1256
dwRGBAlphaBitMask := cImageDataFormat8bits[i].ABits;
1262
for i := 0 to High(cImageDataFormat16bits) do
1263
if (cImageDataFormat16bits[i].colorFormat = colorFormat)
1264
and (cImageDataFormat16bits[i].TexFormat = iFormat)
1265
and (cImageDataFormat16bits[i].dType = dataType) then
1267
dwFlags := cImageDataFormat16bits[i].ColorFlag;
1268
dwRBitMask := cImageDataFormat16bits[i].RBits;
1269
dwGBitMask := cImageDataFormat16bits[i].GBits;
1270
dwBBitMask := cImageDataFormat16bits[i].BBits;
1271
dwRGBAlphaBitMask := cImageDataFormat16bits[i].ABits;
1277
for i := 0 to High(cImageDataFormat24bits) do
1278
if (cImageDataFormat24bits[i].colorFormat = colorFormat)
1279
and (cImageDataFormat24bits[i].TexFormat = iFormat)
1280
and (cImageDataFormat24bits[i].dType = dataType) then
1282
dwFlags := cImageDataFormat24bits[i].ColorFlag;
1283
dwRBitMask := cImageDataFormat24bits[i].RBits;
1284
dwGBitMask := cImageDataFormat24bits[i].GBits;
1285
dwBBitMask := cImageDataFormat24bits[i].BBits;
1286
dwRGBAlphaBitMask := cImageDataFormat24bits[i].ABits;
1292
for i := 0 to High(cImageDataFormat32bits) do
1293
if (cImageDataFormat32bits[i].colorFormat = colorFormat)
1294
and (cImageDataFormat32bits[i].TexFormat = iFormat)
1295
and (cImageDataFormat32bits[i].dType = dataType) then
1297
dwFlags := cImageDataFormat32bits[i].ColorFlag;
1298
dwRBitMask := cImageDataFormat32bits[i].RBits;
1299
dwGBitMask := cImageDataFormat32bits[i].GBits;
1300
dwBBitMask := cImageDataFormat32bits[i].BBits;
1301
dwRGBAlphaBitMask := cImageDataFormat32bits[i].ABits;
1306
else Result := false;
1312
function FindDDSCompatibleDataFormat(const iFormat: TGLInternalFormat;
1313
out colorFormat: TGLEnum;
1314
out dataType: TGLEnum): Boolean;
1319
// 32 bits data format
1320
for i := 0 to High(cImageDataFormat32bits) do
1321
if cImageDataFormat32bits[i].TexFormat = iFormat then
1323
colorFormat := cImageDataFormat32bits[i].colorFormat;
1324
dataType := cImageDataFormat32bits[i].dType;
1328
// 24 bits data format
1329
for i := 0 to High(cImageDataFormat24bits) do
1330
if cImageDataFormat24bits[i].TexFormat = iFormat then
1332
colorFormat := cImageDataFormat24bits[i].colorFormat;
1333
dataType := cImageDataFormat24bits[i].dType;
1337
// 16 bits data format
1338
for i := 0 to High(cImageDataFormat16bits) do
1339
if cImageDataFormat16bits[i].TexFormat = iFormat then
1341
colorFormat := cImageDataFormat16bits[i].colorFormat;
1342
dataType := cImageDataFormat16bits[i].dType;
1346
// 8 bits data format
1347
for i := 0 to High(cImageDataFormat8bits) do
1348
if cImageDataFormat8bits[i].TexFormat = iFormat then
1350
colorFormat := cImageDataFormat8bits[i].colorFormat;
1351
dataType := cImageDataFormat8bits[i].dType;