Formatx.DDSImage.pas 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. //
  2. // The graphics GaLaXy Engine. The unit of GXScene
  3. //
  4. unit Formatx.DDSImage;
  5. (*
  6. Alternative for DDS unit with more supported formats of flat image:
  7. Alpha8, Luminance8, R3G3B2, RGB5A1, RGBA4, Alpha8Luminance8, Luminance16, R5G6B5,
  8. RGB8, R10G10B10A2, RGBA8, RGBA16, R16F, RGBA16F, R32F, RGBA32F, GR16, GR16F, GR32F,
  9. Compressed RGB S3TC DXT1, Compressed RGBA S3TC DXT1, Compressed RGBA S3TC DXT3,
  10. Compressed RGBA S3TC DXT5
  11. But it down color to RGBA8 because becomes to TBitmap
  12. Good for preview picture in OpenDialog,
  13. so you may include both DDSImage (preview) and GLFileDDS (loading)
  14. *)
  15. interface
  16. {$I Stage.Defines.inc}
  17. uses
  18. Winapi.OpenGL,
  19. Winapi.Windows,
  20. System.Classes,
  21. System.SysUtils,
  22. FMX.Graphics,
  23. FMX.Types,
  24. Stage.VectorGeometry,
  25. Stage.TextureFormat,
  26. GXS.Graphics,
  27. GXS.Context,
  28. GXS.FileDDS,
  29. Formatx.DXTC;
  30. type
  31. TDDSImage = class(TBitmap)
  32. public
  33. procedure LoadFromStream(stream: TStream); //override; -> E2170 Cannot override a non-virtual method override;
  34. procedure SaveToStream(stream: TStream); //override; -> E2170 Cannot override a non-virtual method override;
  35. end;
  36. EDDSException = class(Exception);
  37. implementation //-------------------------------------------------------------
  38. // ------------------
  39. // ------------------ TDDSImage ------------------
  40. // ------------------
  41. procedure TDDSImage.LoadFromStream(stream: TStream);
  42. var
  43. FullDDS: TgxDDSImage;
  44. DDSImage: TDDSImage; // added to replace Scanline in FMX
  45. BitmapData: TBitmapData;
  46. bCubeMap: Boolean;
  47. src, dst: PGLubyte;
  48. y: integer;
  49. begin
  50. FullDDS := TgxDDSImage.Create;
  51. DDSImage := TDDSImage.Create;
  52. try
  53. FullDDS.LoadFromStream(stream);
  54. DDSImage.LoadFromStream(stream);
  55. except
  56. FullDDS.Free;
  57. DDSImage.Free;
  58. raise;
  59. end;
  60. bCubeMap := FullDDS.CubeMap;
  61. FullDDS.Narrow;
  62. // TODO : E2129 Cannot assign to a read-only property
  63. (*PixelFormat := glpf32bit;*)
  64. // TODO : E2064 Left side cannot be assigned to
  65. (*Transparent := True; *)
  66. Width := FullDDS.LevelWidth[0];
  67. Height := FullDDS.LevelHeight[0];
  68. src := PGLubyte(FullDDS.Data);
  69. if bCubeMap then
  70. for y := 0 to Height - 1 do
  71. begin
  72. DDSImage.Map(TMapAccess.ReadWrite, BitmapData);
  73. dst := BitmapData.GetScanline(y);
  74. BGRA32ToRGBA32(src, dst, Width);
  75. Inc(src, Width * 4);
  76. end
  77. else
  78. for y := 0 to Height - 1 do
  79. begin
  80. DDSImage.Map(TMapAccess.ReadWrite, BitmapData);
  81. dst := BitmapData.GetScanline(Height - 1 - y);
  82. BGRA32ToRGBA32(src, dst, Width);
  83. Inc(src, Width * 4);
  84. end;
  85. FullDDS.Free;
  86. DDSImage.Free;
  87. end;
  88. procedure TDDSImage.SaveToStream(stream: TStream);
  89. const
  90. Magic: array[0..3] of AnsiChar = 'DDS ';
  91. var
  92. header: TDDSHeader;
  93. rowSize: integer;
  94. i: Integer;
  95. begin
  96. FillChar(header, SizeOf(TDDSHeader), 0);
  97. header.magic := cardinal(Magic);
  98. with header.SurfaceFormat do
  99. begin
  100. dwSize := sizeof(TDDSURFACEDESC2);
  101. dwFlags := DDSD_CAPS + DDSD_PIXELFORMAT + DDSD_WIDTH + DDSD_HEIGHT + DDSD_PITCH;
  102. dwWidth := Width;
  103. dwHeight := Height;
  104. ddpf.dwSize := sizeof(TDDPIXELFORMAT);
  105. case PixelFormat of
  106. TPixelFormat.RGBA:
  107. begin
  108. ddpf.dwFlags := DDPF_RGB;
  109. ddpf.dwRGBBitCount := 32;
  110. ddpf.dwRBitMask := $00FF0000;
  111. ddpf.dwGBitMask := $0000FF00;
  112. ddpf.dwBBitMask := $000000FF;
  113. if Transparent=1 then
  114. begin
  115. ddpf.dwFlags := ddpf.dwFlags + DDPF_ALPHAPIXELS;
  116. ddpf.dwRGBAlphaBitMask := $FF000000;
  117. end;
  118. end;
  119. else
  120. raise EDDSException.Create('Unsupported pixel format');
  121. end;
  122. rowSize := (ddpf.dwRGBBitCount div 8) * dwWidth;
  123. dwPitchOrLinearSize := dwHeight * cardinal(rowSize);
  124. dwCaps := DDSCAPS_TEXTURE;
  125. stream.Write(header, SizeOf(TDDSHeader));
  126. for i := 0 to Height - 1 do
  127. // TODO : E2003 Undeclared identifier: 'ScanLine'
  128. (* stream.Write(ScanLine[i]^, rowSize);*)
  129. end;
  130. end;
  131. initialization // -------------------------------------------------------------
  132. // TODO : E2003 Undeclared identifier: 'RegisterFileFormat'
  133. (*
  134. TPicture.RegisterFileFormat(
  135. 'dds', 'Microsoft DirectDraw Surface', TDDSImage);
  136. *)
  137. finalization // --------------------------------------------------------------
  138. // TODO : E2003 Undeclared identifier: 'UnregisterGraphicClass'
  139. (*
  140. TPicture.UnregisterGraphicClass(TDDSImage);
  141. *)
  142. end.