2
0

Formatx.DXTC.pas 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265
  1. //
  2. // The graphics engine GXScene
  3. //
  4. unit Formatx.DXTC;
  5. (*
  6. DXTC (also S3TC) decoding.
  7. Adapted from DevIL image library (http://openil.sourceforge.net)
  8. *)
  9. interface
  10. {.$I Stage.Defines.inc}
  11. {$Z4} // Minimum enum size = dword
  12. uses
  13. Winapi.OpenGL,
  14. Winapi.OpenGLext,
  15. System.SysUtils,
  16. Stage.TextureFormat;
  17. const
  18. DDSD_CAPS = $00000001;
  19. DDSD_HEIGHT = $00000002;
  20. DDSD_WIDTH = $00000004;
  21. DDSD_PITCH = $00000008;
  22. DDSD_PIXELFORMAT = $00001000;
  23. DDSD_MIPMAPCOUNT = $00020000;
  24. DDSD_LINEARSIZE = $00080000;
  25. DDSD_DEPTH = $00800000;
  26. DDPF_ALPHAPIXELS = $00000001;
  27. DDPF_A = $00000002;
  28. DDPF_FOURCC = $00000004;
  29. DDPF_RGB = $00000040;
  30. DDPF_RGBA = $00000041;
  31. DDPF_L = $00020000;
  32. DDPF_LA = $00020001;
  33. DDSCAPS_COMPLEX = $00000008;
  34. DDSCAPS_TEXTURE = $00001000;
  35. DDSCAPS_MIPMAP = $00400000;
  36. DDSCAPS2_CUBEMAP = $00000200;
  37. DDSCAPS2_CUBEMAP_POSITIVEX = $00000400;
  38. DDSCAPS2_CUBEMAP_NEGATIVEX = $00000800;
  39. DDSCAPS2_CUBEMAP_POSITIVEY = $00001000;
  40. DDSCAPS2_CUBEMAP_NEGATIVEY = $00002000;
  41. DDSCAPS2_CUBEMAP_POSITIVEZ = $00004000;
  42. DDSCAPS2_CUBEMAP_NEGATIVEZ = $00008000;
  43. DDSCAPS2_VOLUME = $00200000;
  44. type
  45. TDDPIXELFORMAT = record
  46. dwSize, dwFlags, dwFourCC, dwRGBBitCount, dwRBitMask, dwGBitMask, dwBBitMask,
  47. dwRGBAlphaBitMask: Cardinal;
  48. end;
  49. TDDSURFACEDESC2 = record
  50. dwSize, dwFlags, dwHeight, dwWidth, dwPitchOrLinearSize,
  51. (* The number of bytes per scan line in an
  52. uncompressed texture; the total number of bytes
  53. in the top level texture for a compressed texture. *)
  54. dwDepth, dwMipMapCount: Cardinal;
  55. dwReserved1: array [0 .. 10] of Cardinal;
  56. ddpf: TDDPIXELFORMAT;
  57. dwCaps, dwCaps2, dwCaps3, dwCaps4: Cardinal;
  58. dwReserved2: Cardinal;
  59. end;
  60. TDDSHeader = record
  61. Magic: Cardinal;
  62. SurfaceFormat: TDDSURFACEDESC2;
  63. end;
  64. DXTColBlock = record
  65. col0: Word;
  66. col1: Word;
  67. row: array [0 .. 3] of Byte;
  68. end;
  69. PDXTColBlock = ^DXTColBlock;
  70. DXT3AlphaBlock = record
  71. row: array [0 .. 3] of Word;
  72. end;
  73. PDXT3AlphaBlock = ^DXT3AlphaBlock;
  74. DXT5AlphaBlock = record
  75. alpha0: Byte;
  76. alpha1: Byte;
  77. row: array [0 .. 5] of Byte;
  78. end;
  79. PDXT5AlphaBlock = ^DXT5AlphaBlock;
  80. const
  81. // TDXGI_FORMAT =
  82. // (
  83. DXGI_FORMAT_FORCE_UINT = -1;
  84. DXGI_FORMAT_UNKNOWN = 0;
  85. DXGI_FORMAT_R32G32B32A32_TYPELESS = 1;
  86. DXGI_FORMAT_R32G32B32A32_FLOAT = 2;
  87. DXGI_FORMAT_R32G32B32A32_UINT = 3;
  88. DXGI_FORMAT_R32G32B32A32_SINT = 4;
  89. DXGI_FORMAT_R32G32B32_TYPELESS = 5;
  90. DXGI_FORMAT_R32G32B32_FLOAT = 6;
  91. DXGI_FORMAT_R32G32B32_UINT = 7;
  92. DXGI_FORMAT_R32G32B32_SINT = 8;
  93. DXGI_FORMAT_R16G16B16A16_TYPELESS = 9;
  94. DXGI_FORMAT_R16G16B16A16_FLOAT = 10;
  95. DXGI_FORMAT_R16G16B16A16_UNORM = 11;
  96. DXGI_FORMAT_R16G16B16A16_UINT = 12;
  97. DXGI_FORMAT_R16G16B16A16_SNORM = 13;
  98. DXGI_FORMAT_R16G16B16A16_SINT = 14;
  99. DXGI_FORMAT_R32G32_TYPELESS = 15;
  100. DXGI_FORMAT_R32G32_FLOAT = 16;
  101. DXGI_FORMAT_R32G32_UINT = 17;
  102. DXGI_FORMAT_R32G32_SINT = 18;
  103. DXGI_FORMAT_R32G8X24_TYPELESS = 19;
  104. DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20;
  105. DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21;
  106. DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22;
  107. DXGI_FORMAT_R10G10B10A2_TYPELESS = 23;
  108. DXGI_FORMAT_R10G10B10A2_UNORM = 24;
  109. DXGI_FORMAT_R10G10B10A2_UINT = 25;
  110. DXGI_FORMAT_R11G11B10_FLOAT = 26;
  111. DXGI_FORMAT_R8G8B8A8_TYPELESS = 27;
  112. DXGI_FORMAT_R8G8B8A8_UNORM = 28;
  113. DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29;
  114. DXGI_FORMAT_R8G8B8A8_UINT = 30;
  115. DXGI_FORMAT_R8G8B8A8_SNORM = 31;
  116. DXGI_FORMAT_R8G8B8A8_SINT = 32;
  117. DXGI_FORMAT_R16G16_TYPELESS = 33;
  118. DXGI_FORMAT_R16G16_FLOAT = 34;
  119. DXGI_FORMAT_R16G16_UNORM = 35;
  120. DXGI_FORMAT_R16G16_UINT = 36;
  121. DXGI_FORMAT_R16G16_SNORM = 37;
  122. DXGI_FORMAT_R16G16_SINT = 38;
  123. DXGI_FORMAT_R32_TYPELESS = 39;
  124. DXGI_FORMAT_D32_FLOAT = 40;
  125. DXGI_FORMAT_R32_FLOAT = 41;
  126. DXGI_FORMAT_R32_UINT = 42;
  127. DXGI_FORMAT_R32_SINT = 43;
  128. DXGI_FORMAT_R24G8_TYPELESS = 44;
  129. DXGI_FORMAT_D24_UNORM_S8_UINT = 45;
  130. DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46;
  131. DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47;
  132. DXGI_FORMAT_R8G8_TYPELESS = 48;
  133. DXGI_FORMAT_R8G8_UNORM = 49;
  134. DXGI_FORMAT_R8G8_UINT = 50;
  135. DXGI_FORMAT_R8G8_SNORM = 51;
  136. DXGI_FORMAT_R8G8_SINT = 52;
  137. DXGI_FORMAT_R16_TYPELESS = 53;
  138. DXGI_FORMAT_R16_FLOAT = 54;
  139. DXGI_FORMAT_D16_UNORM = 55;
  140. DXGI_FORMAT_R16_UNORM = 56;
  141. DXGI_FORMAT_R16_UINT = 57;
  142. DXGI_FORMAT_R16_SNORM = 58;
  143. DXGI_FORMAT_R16_SINT = 59;
  144. DXGI_FORMAT_R8_TYPELESS = 60;
  145. DXGI_FORMAT_R8_UNORM = 61;
  146. DXGI_FORMAT_R8_UINT = 62;
  147. DXGI_FORMAT_R8_SNORM = 63;
  148. DXGI_FORMAT_R8_SINT = 64;
  149. DXGI_FORMAT_A8_UNORM = 65;
  150. DXGI_FORMAT_R1_UNORM = 66;
  151. DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67;
  152. DXGI_FORMAT_R8G8_B8G8_UNORM = 68;
  153. DXGI_FORMAT_G8R8_G8B8_UNORM = 69;
  154. DXGI_FORMAT_BC1_TYPELESS = 70;
  155. DXGI_FORMAT_BC1_UNORM = 71;
  156. DXGI_FORMAT_BC1_UNORM_SRGB = 72;
  157. DXGI_FORMAT_BC2_TYPELESS = 73;
  158. DXGI_FORMAT_BC2_UNORM = 74;
  159. DXGI_FORMAT_BC2_UNORM_SRGB = 75;
  160. DXGI_FORMAT_BC3_TYPELESS = 76;
  161. DXGI_FORMAT_BC3_UNORM = 77;
  162. DXGI_FORMAT_BC3_UNORM_SRGB = 78;
  163. DXGI_FORMAT_BC4_TYPELESS = 79;
  164. DXGI_FORMAT_BC4_UNORM = 80;
  165. DXGI_FORMAT_BC4_SNORM = 81;
  166. DXGI_FORMAT_BC5_TYPELESS = 82;
  167. DXGI_FORMAT_BC5_UNORM = 83;
  168. DXGI_FORMAT_BC5_SNORM = 84;
  169. DXGI_FORMAT_B5G6R5_UNORM = 85;
  170. DXGI_FORMAT_B5G5R5A1_UNORM = 86;
  171. DXGI_FORMAT_B8G8R8A8_UNORM = 87;
  172. DXGI_FORMAT_B8G8R8X8_UNORM = 88;
  173. DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89;
  174. DXGI_FORMAT_B8G8R8A8_TYPELESS = 90;
  175. DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91;
  176. DXGI_FORMAT_B8G8R8X8_TYPELESS = 92;
  177. DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93;
  178. DXGI_FORMAT_BC6H_TYPELESS = 94;
  179. DXGI_FORMAT_BC6H_UF16 = 95;
  180. DXGI_FORMAT_BC6H_SF16 = 96;
  181. DXGI_FORMAT_BC7_TYPELESS = 97;
  182. DXGI_FORMAT_BC7_UNORM = 98;
  183. DXGI_FORMAT_BC7_UNORM_SRGB = 99;
  184. // );
  185. // TD3D11_RESOURCE_DIMENSION =
  186. // (
  187. D3D11_RESOURCE_DIMENSION_UNKNOWN = 0;
  188. D3D11_RESOURCE_DIMENSION_BUFFER = 1;
  189. D3D11_RESOURCE_DIMENSION_TEXTURE1D = 2;
  190. D3D11_RESOURCE_DIMENSION_TEXTURE2D = 3;
  191. D3D11_RESOURCE_DIMENSION_TEXTURE3D = 4;
  192. // );
  193. type
  194. TDDS_HEADER_DXT10 = record
  195. dxgiFormat: Integer; // TDXGI_FORMAT;
  196. resourceDimension: Integer; // TD3D11_RESOURCE_DIMENSION;
  197. miscFlag: Cardinal;
  198. arraySize: Cardinal;
  199. reserved: Cardinal;
  200. end;
  201. TFOURCC = array [0 .. 3] of AnsiChar;
  202. const
  203. FOURCC_UNKNOWN = 0;
  204. FOURCC_R8G8B8 = 20;
  205. FOURCC_A8R8G8B8 = 21;
  206. FOURCC_X8R8G8B8 = 22;
  207. FOURCC_R5G6B5 = 23;
  208. FOURCC_X1R5G5B5 = 24;
  209. FOURCC_A1R5G5B5 = 25;
  210. FOURCC_A4R4G4B4 = 26;
  211. FOURCC_R3G3B2 = 27;
  212. FOURCC_A8 = 28;
  213. FOURCC_A8R3G3B2 = 29;
  214. FOURCC_X4R4G4B4 = 30;
  215. FOURCC_A2B10G10R10 = 31;
  216. FOURCC_A8B8G8R8 = 32;
  217. FOURCC_X8B8G8R8 = 33;
  218. FOURCC_G16R16 = 34;
  219. FOURCC_A2R10G10B10 = 35;
  220. FOURCC_A16B16G16R16 = 36;
  221. FOURCC_L8 = 50;
  222. FOURCC_A8L8 = 51;
  223. FOURCC_A4L4 = 52;
  224. FOURCC_DXT1 = $31545844;
  225. FOURCC_DXT2 = $32545844;
  226. FOURCC_DXT3 = $33545844;
  227. FOURCC_DXT4 = $34545844;
  228. FOURCC_DXT5 = $35545844;
  229. FOURCC_ATI1 = $31495441;
  230. FOURCC_ATI2 = $32495441;
  231. FOURCC_D16_LOCKABLE = 70;
  232. FOURCC_D32 = 71;
  233. FOURCC_D24X8 = 77;
  234. FOURCC_D16 = 80;
  235. FOURCC_D32F_LOCKABLE = 82;
  236. FOURCC_L16 = 81;
  237. // Floating point surface formats
  238. // s10e5 formats (16-bits per channel)
  239. FOURCC_R16F = 111;
  240. FOURCC_G16R16F = 112;
  241. FOURCC_A16B16G16R16F = 113;
  242. // IEEE s23e8 formats (32-bits per channel)
  243. FOURCC_R32F = 114;
  244. FOURCC_G32R32F = 115;
  245. FOURCC_A32B32G32R32F = 116;
  246. // DX10 header indicator
  247. FOURCC_DX10 = $47495844;
  248. type
  249. TGLImageDataFormat = record
  250. ColorFlag: Cardinal;
  251. RBits, GBits, BBits, ABits: Cardinal;
  252. colorFormat: Cardinal;
  253. TexFormat: TGLinternalFormat;
  254. dType: Cardinal;
  255. end;
  256. const
  257. cImageDataFormat8bits: array [0 .. 3] of TGLImageDataFormat = ((ColorFlag: DDPF_RGB; RBits: $E0;
  258. GBits: $1C; BBits: $03; ABits: $00; colorFormat: GL_RGB; TexFormat: tfR3_G3_B2;
  259. dType: GL_UNSIGNED_BYTE_3_3_2),
  260. (ColorFlag: DDPF_LA; RBits: $0F; GBits: $00; BBits: $00; ABits: $F0;
  261. colorFormat: GL_LUMINANCE_ALPHA; TexFormat: tfLUMINANCE4_ALPHA4; dType: GL_UNSIGNED_BYTE),
  262. (ColorFlag: DDPF_A; RBits: $00; GBits: $00; BBits: $00; ABits: $FF; colorFormat: GL_ALPHA;
  263. TexFormat: tfALPHA8; dType: GL_UNSIGNED_BYTE),
  264. (ColorFlag: DDPF_L; RBits: $FF; GBits: $00; BBits: $00; ABits: $00; colorFormat: GL_LUMINANCE;
  265. TexFormat: tfLUMINANCE8; dType: GL_UNSIGNED_BYTE));
  266. cImageDataFormat16bits: array [0 .. 4] of TGLImageDataFormat = ((ColorFlag: DDPF_RGBA;
  267. RBits: $0F00; GBits: $F0; BBits: $0F; ABits: $F000; colorFormat: GL_BGRA; TexFormat: tfRGBA4;
  268. dType: GL_UNSIGNED_SHORT_4_4_4_4_REV),
  269. (ColorFlag: DDPF_RGB; RBits: $F800; GBits: $07E0; BBits: $1F; ABits: $00; colorFormat: GL_RGB;
  270. TexFormat: tfRGB5; dType: GL_UNSIGNED_SHORT_5_6_5),
  271. (ColorFlag: DDPF_L; RBits: $FFFF; GBits: $00; BBits: $00; ABits: $00; colorFormat: GL_LUMINANCE;
  272. TexFormat: tfLUMINANCE16; dType: GL_UNSIGNED_SHORT),
  273. (ColorFlag: DDPF_LA; RBits: $FF; GBits: $00; BBits: $00; ABits: $FF00;
  274. colorFormat: GL_LUMINANCE_ALPHA; TexFormat: tfLUMINANCE8_ALPHA8; dType: GL_UNSIGNED_BYTE),
  275. (ColorFlag: DDPF_RGBA; RBits: $7C00; GBits: $03E0; BBits: $1F; ABits: $8000;
  276. colorFormat: GL_BGRA; TexFormat: tfRGB5_A1; dType: GL_UNSIGNED_SHORT_1_5_5_5_REV));
  277. cImageDataFormat24bits: array [0 .. 0] of TGLImageDataFormat = ((ColorFlag: DDPF_RGB;
  278. RBits: $FF0000; GBits: $FF00; BBits: $FF; ABits: $00; colorFormat: GL_BGR; TexFormat: tfRGB8;
  279. dType: GL_UNSIGNED_BYTE));
  280. cImageDataFormat32bits: array [0 .. 6] of TGLImageDataFormat = ((ColorFlag: DDPF_RGBA; RBits: $FF;
  281. GBits: $FF00; BBits: $FF0000; ABits: $FF000000; colorFormat: GL_RGBA; TexFormat: tfRGBA8;
  282. dType: GL_UNSIGNED_BYTE),
  283. (ColorFlag: DDPF_RGBA; RBits: $FF0000; GBits: $FF00; BBits: $FF; ABits: $FF000000;
  284. colorFormat: GL_BGRA; TexFormat: tfRGBA8; dType: GL_UNSIGNED_BYTE),
  285. (ColorFlag: DDPF_RGBA; RBits: $3FF00000; GBits: $0FFC00; BBits: $03FF; ABits: $0C0000000;
  286. colorFormat: GL_RGBA; TexFormat: tfRGB10_A2; dType: GL_UNSIGNED_INT_2_10_10_10_REV),
  287. (ColorFlag: DDPF_RGBA; RBits: $03FF; GBits: $FFC00; BBits: $3FF00000; ABits: $C0000000;
  288. colorFormat: GL_BGRA; TexFormat: tfRGB10_A2; dType: GL_UNSIGNED_INT_2_10_10_10_REV),
  289. (ColorFlag: DDPF_RGBA; RBits: $FF0000; GBits: $FF00; BBits: $FF; ABits: $FF000000;
  290. colorFormat: GL_BGRA; TexFormat: tfRGB8; dType: GL_UNSIGNED_INT_8_8_8_8),
  291. (ColorFlag: DDPF_RGBA; RBits: $FF; GBits: $FF00; BBits: $FF0000; ABits: $FF000000;
  292. colorFormat: GL_RGBA; TexFormat: tfRGB8; dType: GL_UNSIGNED_INT_8_8_8_8),
  293. (ColorFlag: DDPF_RGB; RBits: $FFFF; GBits: $FFFF0000; BBits: $00; ABits: $00;
  294. colorFormat: GL_RG; TexFormat: tfRG16; dType: GL_UNSIGNED_SHORT));
  295. procedure DecodeDXT1toBitmap32(encData, decData: PByteArray; w, h: Integer; var trans: Boolean);
  296. procedure DecodeDXT3toBitmap32(encData, decData: PByteArray; w, h: Integer);
  297. procedure DecodeDXT5toBitmap32(encData, decData: PByteArray; w, h: Integer);
  298. procedure flip_blocks_dxtc1(data: PGLubyte; numBlocks: Integer);
  299. procedure flip_blocks_dxtc3(data: PGLubyte; numBlocks: Integer);
  300. procedure flip_blocks_dxtc5(data: PGLubyte; numBlocks: Integer);
  301. procedure flip_dxt5_alpha(block: PDXT5AlphaBlock);
  302. function DDSHeaderToGLEnum(const DX9header: TDDSHeader; const DX11header: TDDS_HEADER_DXT10;
  303. const useDX11: Boolean; out iFormat: TGLinternalFormat; out colorFormat: Cardinal;
  304. out dataType: Cardinal; out bpe: Integer): Boolean;
  305. function GLEnumToDDSHeader(var DX9header: TDDSHeader; var DX11header: TDDS_HEADER_DXT10;
  306. const useDX11: Boolean; const iFormat: TGLinternalFormat; const colorFormat: Cardinal;
  307. const dataType: Cardinal; const bpe: Integer): Boolean;
  308. function FindDDSCompatibleDataFormat(const iFormat: TGLinternalFormat; out colorFormat: Cardinal;
  309. out dataType: Cardinal): Boolean;
  310. // --------------------------------------------------
  311. implementation
  312. // --------------------------------------------------
  313. procedure DecodeColor565(col: Word; out r, g, b: Byte);
  314. begin
  315. r := col and $1F;
  316. g := (col shr 5) and $3F;
  317. b := (col shr 11) and $1F;
  318. end;
  319. procedure DecodeDXT1toBitmap32(encData, decData: PByteArray; w, h: Integer; var trans: Boolean);
  320. var
  321. x, y, i, j, k, select: Integer;
  322. col0, col1: Word;
  323. colors: array [0 .. 3] of array [0 .. 3] of Byte;
  324. bitmask: Cardinal;
  325. temp: PGLubyte;
  326. r0, g0, b0, r1, g1, b1: Byte;
  327. begin
  328. trans := False;
  329. if not(Assigned(encData) and Assigned(decData)) then
  330. exit;
  331. temp := PGLubyte(encData);
  332. for y := 0 to (h div 4) - 1 do
  333. begin
  334. for x := 0 to (w div 4) - 1 do
  335. begin
  336. col0 := PWord(temp)^;
  337. Inc(temp, 2);
  338. col1 := PWord(temp)^;
  339. Inc(temp, 2);
  340. bitmask := PCardinal(temp)^;
  341. Inc(temp, 4);
  342. DecodeColor565(col0, r0, g0, b0);
  343. DecodeColor565(col1, r1, g1, b1);
  344. colors[0][0] := r0 shl 3;
  345. colors[0][1] := g0 shl 2;
  346. colors[0][2] := b0 shl 3;
  347. colors[0][3] := $FF;
  348. colors[1][0] := r1 shl 3;
  349. colors[1][1] := g1 shl 2;
  350. colors[1][2] := b1 shl 3;
  351. colors[1][3] := $FF;
  352. if col0 > col1 then
  353. begin
  354. colors[2][0] := (2 * colors[0][0] + colors[1][0] + 1) div 3;
  355. colors[2][1] := (2 * colors[0][1] + colors[1][1] + 1) div 3;
  356. colors[2][2] := (2 * colors[0][2] + colors[1][2] + 1) div 3;
  357. colors[2][3] := $FF;
  358. colors[3][0] := (colors[0][0] + 2 * colors[1][0] + 1) div 3;
  359. colors[3][1] := (colors[0][1] + 2 * colors[1][1] + 1) div 3;
  360. colors[3][2] := (colors[0][2] + 2 * colors[1][2] + 1) div 3;
  361. colors[3][3] := $FF;
  362. end
  363. else
  364. begin
  365. trans := True;
  366. colors[2][0] := (colors[0][0] + colors[1][0]) div 2;
  367. colors[2][1] := (colors[0][1] + colors[1][1]) div 2;
  368. colors[2][2] := (colors[0][2] + colors[1][2]) div 2;
  369. colors[2][3] := $FF;
  370. colors[3][0] := (colors[0][0] + 2 * colors[1][0] + 1) div 3;
  371. colors[3][1] := (colors[0][1] + 2 * colors[1][1] + 1) div 3;
  372. colors[3][2] := (colors[0][2] + 2 * colors[1][2] + 1) div 3;
  373. colors[3][3] := 0;
  374. end;
  375. k := 0;
  376. for j := 0 to 3 do
  377. begin
  378. for i := 0 to 3 do
  379. begin
  380. select := (bitmask and (3 shl (k * 2))) shr (k * 2);
  381. if ((4 * x + i) < w) and ((4 * y + j) < h) then
  382. PCardinal(@decData[((4 * y + j) * w + (4 * x + i)) * 4])^ := Cardinal(colors[select]);
  383. Inc(k);
  384. end;
  385. end;
  386. end;
  387. end;
  388. end;
  389. procedure DecodeDXT3toBitmap32(encData, decData: PByteArray; w, h: Integer);
  390. var
  391. x, y, i, j, k, select: Integer;
  392. col0, col1, wrd: Word;
  393. colors: array [0 .. 3] of array [0 .. 3] of Byte;
  394. bitmask, offset: Cardinal;
  395. temp: PGLubyte;
  396. r0, g0, b0, r1, g1, b1: Byte;
  397. alpha: array [0 .. 3] of Word;
  398. begin
  399. if not(Assigned(encData) and Assigned(decData)) then
  400. exit;
  401. temp := PGLubyte(encData);
  402. for y := 0 to (h div 4) - 1 do
  403. begin
  404. for x := 0 to (w div 4) - 1 do
  405. begin
  406. alpha[0] := PWord(temp)^;
  407. Inc(temp, 2);
  408. alpha[1] := PWord(temp)^;
  409. Inc(temp, 2);
  410. alpha[2] := PWord(temp)^;
  411. Inc(temp, 2);
  412. alpha[3] := PWord(temp)^;
  413. Inc(temp, 2);
  414. col0 := PWord(temp)^;
  415. Inc(temp, 2);
  416. col1 := PWord(temp)^;
  417. Inc(temp, 2);
  418. bitmask := PCardinal(temp)^;
  419. Inc(temp, 4);
  420. DecodeColor565(col0, r0, g0, b0);
  421. DecodeColor565(col1, r1, g1, b1);
  422. colors[0][0] := r0 shl 3;
  423. colors[0][1] := g0 shl 2;
  424. colors[0][2] := b0 shl 3;
  425. colors[0][3] := $FF;
  426. colors[1][0] := r1 shl 3;
  427. colors[1][1] := g1 shl 2;
  428. colors[1][2] := b1 shl 3;
  429. colors[1][3] := $FF;
  430. colors[2][0] := (2 * colors[0][0] + colors[1][0] + 1) div 3;
  431. colors[2][1] := (2 * colors[0][1] + colors[1][1] + 1) div 3;
  432. colors[2][2] := (2 * colors[0][2] + colors[1][2] + 1) div 3;
  433. colors[2][3] := $FF;
  434. colors[3][0] := (colors[0][0] + 2 * colors[1][0] + 1) div 3;
  435. colors[3][1] := (colors[0][1] + 2 * colors[1][1] + 1) div 3;
  436. colors[3][2] := (colors[0][2] + 2 * colors[1][2] + 1) div 3;
  437. colors[3][3] := $FF;
  438. k := 0;
  439. for j := 0 to 3 do
  440. begin
  441. for i := 0 to 3 do
  442. begin
  443. select := (bitmask and (3 shl (k * 2))) shr (k * 2);
  444. if ((4 * x + i) < w) and ((4 * y + j) < h) then
  445. PCardinal(@decData[((4 * y + j) * w + (4 * x + i)) * 4])^ := Cardinal(colors[select]);
  446. Inc(k);
  447. end;
  448. end;
  449. for j := 0 to 3 do
  450. begin
  451. wrd := alpha[j];
  452. for i := 0 to 3 do
  453. begin
  454. if (((4 * x + i) < w) and ((4 * y + j) < h)) then
  455. begin
  456. offset := ((4 * y + j) * w + (4 * x + i)) * 4 + 3;
  457. decData[offset] := wrd and $0F;
  458. decData[offset] := decData[offset] or (decData[offset] shl 4);
  459. end;
  460. wrd := wrd shr 4;
  461. end;
  462. end;
  463. end;
  464. end;
  465. end;
  466. procedure DecodeDXT5toBitmap32(encData, decData: PByteArray; w, h: Integer);
  467. var
  468. x, y, i, j, k, select: Integer;
  469. col0, col1: Word;
  470. colors: array [0 .. 3] of array [0 .. 3] of Byte;
  471. bits, bitmask, offset: Cardinal;
  472. temp, alphamask: PGLubyte;
  473. r0, g0, b0, r1, g1, b1: Byte;
  474. alphas: array [0 .. 7] of Byte;
  475. begin
  476. if not(Assigned(encData) and Assigned(decData)) then
  477. exit;
  478. temp := PGLubyte(encData);
  479. for y := 0 to (h div 4) - 1 do
  480. begin
  481. for x := 0 to (w div 4) - 1 do
  482. begin
  483. alphas[0] := temp^;
  484. Inc(temp);
  485. alphas[1] := temp^;
  486. Inc(temp);
  487. alphamask := temp;
  488. Inc(temp, 6);
  489. col0 := PWord(temp)^;
  490. Inc(temp, 2);
  491. col1 := PWord(temp)^;
  492. Inc(temp, 2);
  493. bitmask := PCardinal(temp)^;
  494. Inc(temp, 4);
  495. DecodeColor565(col0, r0, g0, b0);
  496. DecodeColor565(col1, r1, g1, b1);
  497. colors[0][0] := r0 shl 3;
  498. colors[0][1] := g0 shl 2;
  499. colors[0][2] := b0 shl 3;
  500. colors[0][3] := $FF;
  501. colors[1][0] := r1 shl 3;
  502. colors[1][1] := g1 shl 2;
  503. colors[1][2] := b1 shl 3;
  504. colors[1][3] := $FF;
  505. colors[2][0] := (2 * colors[0][0] + colors[1][0] + 1) div 3;
  506. colors[2][1] := (2 * colors[0][1] + colors[1][1] + 1) div 3;
  507. colors[2][2] := (2 * colors[0][2] + colors[1][2] + 1) div 3;
  508. colors[2][3] := $FF;
  509. colors[3][0] := (colors[0][0] + 2 * colors[1][0] + 1) div 3;
  510. colors[3][1] := (colors[0][1] + 2 * colors[1][1] + 1) div 3;
  511. colors[3][2] := (colors[0][2] + 2 * colors[1][2] + 1) div 3;
  512. colors[3][3] := $FF;
  513. k := 0;
  514. for j := 0 to 3 do
  515. begin
  516. for i := 0 to 3 do
  517. begin
  518. select := (bitmask and (3 shl (k * 2))) shr (k * 2);
  519. if ((4 * x + i) < w) and ((4 * y + j) < h) then
  520. PCardinal(@decData[((4 * y + j) * w + (4 * x + i)) * 4])^ := Cardinal(colors[select]);
  521. Inc(k);
  522. end;
  523. end;
  524. if (alphas[0] > alphas[1]) then
  525. begin
  526. alphas[2] := (6 * alphas[0] + 1 * alphas[1] + 3) div 7;
  527. alphas[3] := (5 * alphas[0] + 2 * alphas[1] + 3) div 7;
  528. alphas[4] := (4 * alphas[0] + 3 * alphas[1] + 3) div 7;
  529. alphas[5] := (3 * alphas[0] + 4 * alphas[1] + 3) div 7;
  530. alphas[6] := (2 * alphas[0] + 5 * alphas[1] + 3) div 7;
  531. alphas[7] := (1 * alphas[0] + 6 * alphas[1] + 3) div 7;
  532. end
  533. else
  534. begin
  535. alphas[2] := (4 * alphas[0] + 1 * alphas[1] + 2) div 5;
  536. alphas[3] := (3 * alphas[0] + 2 * alphas[1] + 2) div 5;
  537. alphas[4] := (2 * alphas[0] + 3 * alphas[1] + 2) div 5;
  538. alphas[5] := (1 * alphas[0] + 4 * alphas[1] + 2) div 5;
  539. alphas[6] := 0;
  540. alphas[7] := $FF;
  541. end;
  542. bits := PCardinal(alphamask)^;
  543. for j := 0 to 1 do
  544. begin
  545. for i := 0 to 3 do
  546. begin
  547. if (((4 * x + i) < w) and ((4 * y + j) < h)) then
  548. begin
  549. offset := ((4 * y + j) * w + (4 * x + i)) * 4 + 3;
  550. decData[offset] := alphas[bits and 7];
  551. end;
  552. bits := bits shr 3;
  553. end;
  554. end;
  555. Inc(alphamask, 3);
  556. bits := PCardinal(alphamask)^;
  557. for j := 2 to 3 do
  558. begin
  559. for i := 0 to 3 do
  560. begin
  561. if (((4 * x + i) < w) and ((4 * y + j) < h)) then
  562. begin
  563. offset := ((4 * y + j) * w + (4 * x + i)) * 4 + 3;
  564. decData[offset] := alphas[bits and 7];
  565. end;
  566. bits := bits shr 3;
  567. end;
  568. end;
  569. end;
  570. end;
  571. end;
  572. //==============================================================
  573. procedure flip_blocks_dxtc1(data: PGLubyte; numBlocks: Integer);
  574. var
  575. curblock: PDXTColBlock;
  576. temp: Byte;
  577. i: Integer;
  578. begin
  579. curblock := PDXTColBlock(data);
  580. for i := 0 to numBlocks - 1 do
  581. begin
  582. temp := curblock.row[0];
  583. curblock.row[0] := curblock.row[3];
  584. curblock.row[3] := temp;
  585. temp := curblock.row[1];
  586. curblock.row[1] := curblock.row[2];
  587. curblock.row[2] := temp;
  588. Inc(curblock);
  589. end;
  590. end;
  591. // flip a DXT3 color block
  592. //===============================================================
  593. procedure flip_blocks_dxtc3(data: PGLubyte; numBlocks: Integer);
  594. var
  595. curblock: PDXTColBlock;
  596. alphablock: PDXT3AlphaBlock;
  597. tempS: Word;
  598. tempB: Byte;
  599. i: Integer;
  600. begin
  601. curblock := PDXTColBlock(data);
  602. for i := 0 to numBlocks - 1 do
  603. begin
  604. alphablock := PDXT3AlphaBlock(curblock);
  605. tempS := alphablock.row[0];
  606. alphablock.row[0] := alphablock.row[3];
  607. alphablock.row[3] := tempS;
  608. tempS := alphablock.row[1];
  609. alphablock.row[1] := alphablock.row[2];
  610. alphablock.row[2] := tempS;
  611. Inc(curblock);
  612. tempB := curblock.row[0];
  613. curblock.row[0] := curblock.row[3];
  614. curblock.row[3] := tempB;
  615. tempB := curblock.row[1];
  616. curblock.row[1] := curblock.row[2];
  617. curblock.row[2] := tempB;
  618. Inc(curblock);
  619. end;
  620. end;
  621. //=================================================
  622. procedure flip_dxt5_alpha(block: PDXT5AlphaBlock);
  623. const
  624. mask = $00000007; // bits = 00 00 01 11
  625. var
  626. GBits: array [0 .. 3, 0 .. 3] of Byte;
  627. bits: Integer;
  628. begin
  629. bits := 0;
  630. Move(block.row[0], bits, sizeof(Byte) * 3);
  631. GBits[0][0] := Byte(bits and mask);
  632. bits := bits shr 3;
  633. GBits[0][1] := Byte(bits and mask);
  634. bits := bits shr 3;
  635. GBits[0][2] := Byte(bits and mask);
  636. bits := bits shr 3;
  637. GBits[0][3] := Byte(bits and mask);
  638. bits := bits shr 3;
  639. GBits[1][0] := Byte(bits and mask);
  640. bits := bits shr 3;
  641. GBits[1][1] := Byte(bits and mask);
  642. bits := bits shr 3;
  643. GBits[1][2] := Byte(bits and mask);
  644. bits := bits shr 3;
  645. GBits[1][3] := Byte(bits and mask);
  646. bits := 0;
  647. Move(block.row[3], bits, sizeof(Byte) * 3);
  648. GBits[2][0] := Byte(bits and mask);
  649. bits := bits shr 3;
  650. GBits[2][1] := Byte(bits and mask);
  651. bits := bits shr 3;
  652. GBits[2][2] := Byte(bits and mask);
  653. bits := bits shr 3;
  654. GBits[2][3] := Byte(bits and mask);
  655. bits := bits shr 3;
  656. GBits[3][0] := Byte(bits and mask);
  657. bits := bits shr 3;
  658. GBits[3][1] := Byte(bits and mask);
  659. bits := bits shr 3;
  660. GBits[3][2] := Byte(bits and mask);
  661. bits := bits shr 3;
  662. GBits[3][3] := Byte(bits and mask);
  663. // clear existing alpha bits
  664. FillChar(block.row, sizeof(Byte) * 6, 0);
  665. bits := block.row[0] + block.row[1] * $100 + block.row[2] * $10000;
  666. bits := bits or (GBits[3][0] shl 0);
  667. bits := bits or (GBits[3][1] shl 3);
  668. bits := bits or (GBits[3][2] shl 6);
  669. bits := bits or (GBits[3][3] shl 9);
  670. bits := bits or (GBits[2][0] shl 12);
  671. bits := bits or (GBits[2][1] shl 15);
  672. bits := bits or (GBits[2][2] shl 18);
  673. bits := bits or (GBits[2][3] shl 21);
  674. block.row[0] := bits and $FF;
  675. block.row[1] := (bits shr 8) and $FF;
  676. block.row[2] := (bits shr 16) and $FF;
  677. bits := block.row[3] + block.row[4] * $100 + block.row[5] * $10000;
  678. bits := bits or (GBits[1][0] shl 0);
  679. bits := bits or (GBits[1][1] shl 3);
  680. bits := bits or (GBits[1][2] shl 6);
  681. bits := bits or (GBits[1][3] shl 9);
  682. bits := bits or (GBits[0][0] shl 12);
  683. bits := bits or (GBits[0][1] shl 15);
  684. bits := bits or (GBits[0][2] shl 18);
  685. bits := bits or (GBits[0][3] shl 21);
  686. block.row[3] := bits and $FF;
  687. block.row[4] := (bits shr 8) and $FF;
  688. block.row[5] := (bits shr 16) and $FF;
  689. end;
  690. //==============================================================
  691. procedure flip_blocks_dxtc5(data: PGLubyte; numBlocks: Integer);
  692. var
  693. curblock: PDXTColBlock;
  694. temp: Byte;
  695. i: Integer;
  696. begin
  697. curblock := PDXTColBlock(data);
  698. for i := 0 to numBlocks - 1 do
  699. begin
  700. flip_dxt5_alpha(PDXT5AlphaBlock(curblock));
  701. Inc(curblock);
  702. temp := curblock.row[0];
  703. curblock.row[0] := curblock.row[3];
  704. curblock.row[3] := temp;
  705. temp := curblock.row[1];
  706. curblock.row[1] := curblock.row[2];
  707. curblock.row[2] := temp;
  708. Inc(curblock);
  709. end;
  710. end;
  711. function DDSHeaderToGLEnum(const DX9header: TDDSHeader; const DX11header: TDDS_HEADER_DXT10;
  712. const useDX11: Boolean; out iFormat: TGLinternalFormat; out colorFormat: Cardinal;
  713. out dataType: Cardinal; out bpe: Integer): Boolean;
  714. var
  715. i: Integer;
  716. begin
  717. Result := True;
  718. if useDX11 then
  719. begin
  720. Assert(False, 'DXGI images not supported.');
  721. end
  722. // Use DX9 formats
  723. else
  724. begin
  725. // figure out what the image format is
  726. if (DX9header.SurfaceFormat.ddpf.dwFlags and DDPF_FOURCC) <> 0 then
  727. begin
  728. case DX9header.SurfaceFormat.ddpf.dwFourCC of
  729. FOURCC_DXT1:
  730. begin
  731. colorFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  732. iFormat := tfCOMPRESSED_RGBA_S3TC_DXT1;
  733. dataType := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  734. bpe := 8;
  735. end;
  736. FOURCC_DXT2, FOURCC_DXT3:
  737. begin
  738. colorFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  739. iFormat := tfCOMPRESSED_RGBA_S3TC_DXT3;
  740. dataType := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  741. bpe := 16;
  742. end;
  743. FOURCC_DXT4, FOURCC_DXT5:
  744. begin
  745. colorFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  746. iFormat := tfCOMPRESSED_RGBA_S3TC_DXT5;
  747. dataType := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  748. bpe := 16;
  749. end;
  750. FOURCC_ATI1:
  751. begin
  752. colorFormat := GL_COMPRESSED_RED_RGTC1;
  753. iFormat := tfCOMPRESSED_RED_RGTC1;
  754. dataType := GL_COMPRESSED_RED_RGTC1;
  755. bpe := 8;
  756. end;
  757. FOURCC_ATI2:
  758. begin
  759. colorFormat := GL_COMPRESSED_RG_RGTC2;
  760. iFormat := tfCOMPRESSED_RG_RGTC2;
  761. dataType := GL_COMPRESSED_RG_RGTC2;
  762. bpe := 16;
  763. end;
  764. FOURCC_R8G8B8:
  765. begin
  766. colorFormat := GL_BGR;
  767. iFormat := tfRGB8;
  768. dataType := GL_UNSIGNED_BYTE;
  769. bpe := 3;
  770. end;
  771. FOURCC_A8R8G8B8:
  772. begin
  773. colorFormat := GL_BGRA;
  774. iFormat := tfRGBA8;
  775. dataType := GL_UNSIGNED_BYTE;
  776. bpe := 4;
  777. end;
  778. FOURCC_X8R8G8B8:
  779. begin
  780. colorFormat := GL_BGRA;
  781. iFormat := tfRGB8;
  782. dataType := GL_UNSIGNED_INT_8_8_8_8;
  783. bpe := 4;
  784. end;
  785. FOURCC_R5G6B5:
  786. begin
  787. colorFormat := GL_RGB;
  788. iFormat := tfRGB5;
  789. dataType := GL_UNSIGNED_SHORT_5_6_5;
  790. bpe := 2;
  791. end;
  792. FOURCC_A8:
  793. begin
  794. colorFormat := GL_ALPHA;
  795. iFormat := tfALPHA8;
  796. dataType := GL_UNSIGNED_BYTE;
  797. bpe := 1;
  798. end;
  799. FOURCC_A2B10G10R10:
  800. begin
  801. colorFormat := GL_RGBA;
  802. iFormat := tfRGB10_A2;
  803. dataType := GL_UNSIGNED_INT_10_10_10_2;
  804. bpe := 4;
  805. end;
  806. FOURCC_A8B8G8R8:
  807. begin
  808. colorFormat := GL_RGBA;
  809. iFormat := tfRGBA8;
  810. dataType := GL_UNSIGNED_BYTE;
  811. bpe := 4;
  812. end;
  813. FOURCC_X8B8G8R8:
  814. begin
  815. colorFormat := GL_RGBA;
  816. iFormat := tfRGB8;
  817. dataType := GL_UNSIGNED_INT_8_8_8_8;
  818. bpe := 4;
  819. end;
  820. FOURCC_A2R10G10B10:
  821. begin
  822. colorFormat := GL_BGRA;
  823. iFormat := tfRGB10_A2;
  824. dataType := GL_UNSIGNED_INT_10_10_10_2;
  825. bpe := 4;
  826. end;
  827. FOURCC_A16B16G16R16:
  828. begin
  829. colorFormat := GL_RGBA;
  830. iFormat := tfR16G16B16A16;
  831. dataType := GL_UNSIGNED_SHORT;
  832. bpe := 8;
  833. end;
  834. FOURCC_L8:
  835. begin
  836. colorFormat := GL_LUMINANCE;
  837. iFormat := tfLUMINANCE8;
  838. dataType := GL_UNSIGNED_BYTE;
  839. bpe := 1;
  840. end;
  841. FOURCC_A8L8:
  842. begin
  843. colorFormat := GL_LUMINANCE_ALPHA;
  844. iFormat := tfLUMINANCE8_ALPHA8;
  845. dataType := GL_UNSIGNED_BYTE;
  846. bpe := 2;
  847. end;
  848. FOURCC_L16:
  849. begin
  850. colorFormat := GL_LUMINANCE;
  851. iFormat := tfLUMINANCE16;
  852. dataType := GL_UNSIGNED_SHORT;
  853. bpe := 2;
  854. end;
  855. FOURCC_R16F:
  856. begin
  857. colorFormat := GL_RED;
  858. iFormat := tfLUMINANCE_FLOAT16;
  859. dataType := GL_HALF_FLOAT_ARB;
  860. bpe := 2;
  861. end;
  862. FOURCC_A16B16G16R16F:
  863. begin
  864. colorFormat := GL_RGBA;
  865. iFormat := tfRGBA_FLOAT16;
  866. dataType := GL_HALF_FLOAT_ARB;
  867. bpe := 8;
  868. end;
  869. FOURCC_R32F:
  870. begin
  871. colorFormat := GL_RED;
  872. iFormat := tfLUMINANCE_FLOAT32;
  873. dataType := GL_FLOAT;
  874. bpe := 4;
  875. end;
  876. FOURCC_G16R16:
  877. begin
  878. colorFormat := GL_RG;
  879. iFormat := tfRG16;
  880. dataType := GL_UNSIGNED_SHORT;
  881. bpe := 4;
  882. end;
  883. FOURCC_G16R16F:
  884. begin
  885. colorFormat := GL_RG;
  886. iFormat := tfRG16F;
  887. dataType := GL_HALF_FLOAT;
  888. bpe := 4;
  889. end;
  890. FOURCC_G32R32F:
  891. begin
  892. colorFormat := GL_RG;
  893. iFormat := tfRG32F;
  894. dataType := GL_FLOAT;
  895. bpe := 8;
  896. end;
  897. FOURCC_UNKNOWN, FOURCC_X1R5G5B5, FOURCC_A1R5G5B5, FOURCC_A4R4G4B4, FOURCC_R3G3B2,
  898. FOURCC_A8R3G3B2, FOURCC_X4R4G4B4, FOURCC_A4L4, FOURCC_D16_LOCKABLE, FOURCC_D32,
  899. FOURCC_D24X8, FOURCC_D16, FOURCC_D32F_LOCKABLE:
  900. Result := False; // these are unsupported for now
  901. end; // of case
  902. end // not FOURCC
  903. else
  904. with DX9header.SurfaceFormat.ddpf do
  905. case dwRGBBitCount of
  906. 8:
  907. begin
  908. for i := 0 to High(cImageDataFormat8bits) do
  909. if (cImageDataFormat8bits[i].ColorFlag = dwFlags) and
  910. (cImageDataFormat8bits[i].RBits = dwRBitMask) and
  911. (cImageDataFormat8bits[i].GBits = dwGBitMask) and
  912. (cImageDataFormat8bits[i].BBits = dwBBitMask) and
  913. (cImageDataFormat8bits[i].ABits = dwRGBAlphaBitMask) then
  914. begin
  915. colorFormat := cImageDataFormat8bits[i].colorFormat;
  916. iFormat := cImageDataFormat8bits[i].TexFormat;
  917. dataType := cImageDataFormat8bits[i].dType;
  918. Result := True;
  919. Break;
  920. end;
  921. bpe := 1;
  922. end;
  923. 16:
  924. begin
  925. for i := 0 to High(cImageDataFormat16bits) do
  926. if (cImageDataFormat16bits[i].ColorFlag = dwFlags) and
  927. (cImageDataFormat16bits[i].RBits = dwRBitMask) and
  928. (cImageDataFormat16bits[i].GBits = dwGBitMask) and
  929. (cImageDataFormat16bits[i].BBits = dwBBitMask) and
  930. (cImageDataFormat16bits[i].ABits = dwRGBAlphaBitMask) then
  931. begin
  932. colorFormat := cImageDataFormat16bits[i].colorFormat;
  933. iFormat := cImageDataFormat16bits[i].TexFormat;
  934. dataType := cImageDataFormat16bits[i].dType;
  935. Result := True;
  936. Break;
  937. end;
  938. bpe := 2;
  939. end;
  940. 24:
  941. begin
  942. for i := 0 to High(cImageDataFormat24bits) do
  943. if (cImageDataFormat24bits[i].ColorFlag = dwFlags) and
  944. (cImageDataFormat24bits[i].RBits = dwRBitMask) and
  945. (cImageDataFormat24bits[i].GBits = dwGBitMask) and
  946. (cImageDataFormat24bits[i].BBits = dwBBitMask) and
  947. (cImageDataFormat24bits[i].ABits = dwRGBAlphaBitMask) then
  948. begin
  949. colorFormat := cImageDataFormat24bits[i].colorFormat;
  950. iFormat := cImageDataFormat24bits[i].TexFormat;
  951. dataType := cImageDataFormat24bits[i].dType;
  952. Result := True;
  953. Break;
  954. end;
  955. bpe := 3;
  956. end;
  957. 32:
  958. begin
  959. for i := 0 to High(cImageDataFormat32bits) do
  960. if (cImageDataFormat32bits[i].ColorFlag = dwFlags) and
  961. (cImageDataFormat32bits[i].RBits = dwRBitMask) and
  962. (cImageDataFormat32bits[i].GBits = dwGBitMask) and
  963. (cImageDataFormat32bits[i].BBits = dwBBitMask) and
  964. (cImageDataFormat32bits[i].ABits = dwRGBAlphaBitMask) then
  965. begin
  966. colorFormat := cImageDataFormat32bits[i].colorFormat;
  967. iFormat := cImageDataFormat32bits[i].TexFormat;
  968. dataType := cImageDataFormat32bits[i].dType;
  969. Result := True;
  970. Break;
  971. end;
  972. bpe := 4;
  973. end;
  974. else
  975. Result := False;
  976. end; // of case
  977. end;
  978. end;
  979. //-------------------------------------------------------------------------------------
  980. function GLEnumToDDSHeader(var DX9header: TDDSHeader; var DX11header: TDDS_HEADER_DXT10;
  981. const useDX11: Boolean; const iFormat: TGLinternalFormat; const colorFormat: Cardinal;
  982. const dataType: Cardinal; const bpe: Integer): Boolean;
  983. var
  984. i: Integer;
  985. begin
  986. Result := True;
  987. if useDX11 then
  988. begin
  989. Assert(False, 'DXGI images not supported.');
  990. end;
  991. if IsCompressedFormat(iFormat) then
  992. begin
  993. with DX9header.SurfaceFormat.ddpf do
  994. begin
  995. dwFlags := DDPF_FOURCC;
  996. case iFormat of
  997. tfCOMPRESSED_RGB_S3TC_DXT1:
  998. dwFourCC := FOURCC_DXT1;
  999. tfCOMPRESSED_RGBA_S3TC_DXT1:
  1000. dwFourCC := FOURCC_DXT1;
  1001. tfCOMPRESSED_RGBA_S3TC_DXT3:
  1002. dwFourCC := FOURCC_DXT3;
  1003. tfCOMPRESSED_RGBA_S3TC_DXT5:
  1004. dwFourCC := FOURCC_DXT5;
  1005. tfCOMPRESSED_LUMINANCE_LATC1:
  1006. dwFourCC := FOURCC_ATI1;
  1007. tfCOMPRESSED_LUMINANCE_ALPHA_LATC2:
  1008. dwFourCC := FOURCC_ATI2;
  1009. else
  1010. Result := False;
  1011. end;
  1012. end;
  1013. end
  1014. else if IsFloatFormat(iFormat) then
  1015. begin
  1016. with DX9header.SurfaceFormat.ddpf do
  1017. begin
  1018. dwFlags := DDPF_FOURCC;
  1019. case iFormat of
  1020. tfINTENSITY_FLOAT16, tfLUMINANCE_FLOAT16, tfR16F:
  1021. dwFourCC := FOURCC_R16F;
  1022. tfRGBA_FLOAT16:
  1023. dwFourCC := FOURCC_A16B16G16R16F;
  1024. tfINTENSITY_FLOAT32, tfLUMINANCE_FLOAT32, tfR32F:
  1025. dwFourCC := FOURCC_R32F;
  1026. tfLUMINANCE_ALPHA_FLOAT16, tfRG16F:
  1027. dwFourCC := FOURCC_G16R16F;
  1028. tfLUMINANCE_ALPHA_FLOAT32, tfRG32F:
  1029. dwFourCC := FOURCC_G32R32F;
  1030. tfRGBA_FLOAT32:
  1031. dwFourCC := FOURCC_A32B32G32R32F
  1032. else
  1033. Result := False;
  1034. end;
  1035. end;
  1036. end
  1037. else
  1038. with DX9header.SurfaceFormat.ddpf do
  1039. begin
  1040. dwFourCC := 0;
  1041. dwRGBBitCount := bpe * 8;
  1042. case bpe of
  1043. 1:
  1044. begin
  1045. for i := 0 to High(cImageDataFormat8bits) do
  1046. if (cImageDataFormat8bits[i].colorFormat = colorFormat) and
  1047. (cImageDataFormat8bits[i].TexFormat = iFormat) and
  1048. (cImageDataFormat8bits[i].dType = dataType) then
  1049. begin
  1050. dwFlags := cImageDataFormat8bits[i].ColorFlag;
  1051. dwRBitMask := cImageDataFormat8bits[i].RBits;
  1052. dwGBitMask := cImageDataFormat8bits[i].GBits;
  1053. dwBBitMask := cImageDataFormat8bits[i].BBits;
  1054. dwRGBAlphaBitMask := cImageDataFormat8bits[i].ABits;
  1055. Break;
  1056. end;
  1057. end;
  1058. 2:
  1059. begin
  1060. for i := 0 to High(cImageDataFormat16bits) do
  1061. if (cImageDataFormat16bits[i].colorFormat = colorFormat) and
  1062. (cImageDataFormat16bits[i].TexFormat = iFormat) and
  1063. (cImageDataFormat16bits[i].dType = dataType) then
  1064. begin
  1065. dwFlags := cImageDataFormat16bits[i].ColorFlag;
  1066. dwRBitMask := cImageDataFormat16bits[i].RBits;
  1067. dwGBitMask := cImageDataFormat16bits[i].GBits;
  1068. dwBBitMask := cImageDataFormat16bits[i].BBits;
  1069. dwRGBAlphaBitMask := cImageDataFormat16bits[i].ABits;
  1070. Break;
  1071. end;
  1072. end;
  1073. 3:
  1074. begin
  1075. for i := 0 to High(cImageDataFormat24bits) do
  1076. if (cImageDataFormat24bits[i].colorFormat = colorFormat) and
  1077. (cImageDataFormat24bits[i].TexFormat = iFormat) and
  1078. (cImageDataFormat24bits[i].dType = dataType) then
  1079. begin
  1080. dwFlags := cImageDataFormat24bits[i].ColorFlag;
  1081. dwRBitMask := cImageDataFormat24bits[i].RBits;
  1082. dwGBitMask := cImageDataFormat24bits[i].GBits;
  1083. dwBBitMask := cImageDataFormat24bits[i].BBits;
  1084. dwRGBAlphaBitMask := cImageDataFormat24bits[i].ABits;
  1085. Break;
  1086. end;
  1087. end;
  1088. 4:
  1089. begin
  1090. for i := 0 to High(cImageDataFormat32bits) do
  1091. if (cImageDataFormat32bits[i].colorFormat = colorFormat) and
  1092. (cImageDataFormat32bits[i].TexFormat = iFormat) and
  1093. (cImageDataFormat32bits[i].dType = dataType) then
  1094. begin
  1095. dwFlags := cImageDataFormat32bits[i].ColorFlag;
  1096. dwRBitMask := cImageDataFormat32bits[i].RBits;
  1097. dwGBitMask := cImageDataFormat32bits[i].GBits;
  1098. dwBBitMask := cImageDataFormat32bits[i].BBits;
  1099. dwRGBAlphaBitMask := cImageDataFormat32bits[i].ABits;
  1100. Break;
  1101. end;
  1102. end;
  1103. else
  1104. Result := False;
  1105. end; // of case
  1106. end;
  1107. end;
  1108. //---------------------------------------------------------------------------------------------
  1109. function FindDDSCompatibleDataFormat(const iFormat: TGLinternalFormat; out colorFormat: Cardinal;
  1110. out dataType: Cardinal): Boolean;
  1111. var
  1112. i: Integer;
  1113. begin
  1114. Result := False;
  1115. // 32 bits data format
  1116. for i := 0 to High(cImageDataFormat32bits) do
  1117. if cImageDataFormat32bits[i].TexFormat = iFormat then
  1118. begin
  1119. colorFormat := cImageDataFormat32bits[i].colorFormat;
  1120. dataType := cImageDataFormat32bits[i].dType;
  1121. Result := True;
  1122. exit;
  1123. end;
  1124. // 24 bits data format
  1125. for i := 0 to High(cImageDataFormat24bits) do
  1126. if cImageDataFormat24bits[i].TexFormat = iFormat then
  1127. begin
  1128. colorFormat := cImageDataFormat24bits[i].colorFormat;
  1129. dataType := cImageDataFormat24bits[i].dType;
  1130. Result := True;
  1131. exit;
  1132. end;
  1133. // 16 bits data format
  1134. for i := 0 to High(cImageDataFormat16bits) do
  1135. if cImageDataFormat16bits[i].TexFormat = iFormat then
  1136. begin
  1137. colorFormat := cImageDataFormat16bits[i].colorFormat;
  1138. dataType := cImageDataFormat16bits[i].dType;
  1139. Result := True;
  1140. exit;
  1141. end;
  1142. // 8 bits data format
  1143. for i := 0 to High(cImageDataFormat8bits) do
  1144. if cImageDataFormat8bits[i].TexFormat = iFormat then
  1145. begin
  1146. colorFormat := cImageDataFormat8bits[i].colorFormat;
  1147. dataType := cImageDataFormat8bits[i].dType;
  1148. Result := True;
  1149. exit;
  1150. end;
  1151. end;
  1152. end.