GXS.FileOCT.pas 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. //
  2. // The graphics engine GLXEngine. The unit of GXScene for Delphi
  3. //
  4. unit GXS.FileOCT;
  5. (*
  6. Support-code to load OCT Files into TgxFreeForm-Components in GLScene.
  7. (OCT being the format output from FSRad, http://www.fluidstudios.com/fsrad.html).
  8. *)
  9. interface
  10. {$I Stage.Defines.inc}
  11. uses
  12. System.SysUtils,
  13. System.Classes,
  14. FMX.Graphics,
  15. Stage.VectorGeometry,
  16. Stage.TextureFormat,
  17. GXS.VectorFileObjects,
  18. GXS.ApplicationFileIO,
  19. GXS.Texture,
  20. GXS.Material,
  21. GXS.Graphics,
  22. GXS.State,
  23. GXS.ImageUtils,
  24. Formatx.OCT;
  25. type
  26. // The OCT vector file (FSRad output).
  27. TgxOCTgxVectorFile = class(TgxVectorFile)
  28. public
  29. class function Capabilities: TDataFileCapabilities; override;
  30. procedure LoadFromStream(aStream: TStream); override;
  31. end;
  32. var
  33. // Scaling factor, 1.0 = unchanged
  34. vFileOCTLightmapBrightness: single = 1;
  35. // Scaling factor, 1.0 = unchanged
  36. vFileOCTLightmapGammaCorrection: single = 1;
  37. // Flag to avoid loading materials (useful for IDE Extensions or scene editors)
  38. vFileOCTAllocateMaterials: boolean = True;
  39. // ------------------------------------------------------------------
  40. implementation
  41. // ------------------------------------------------------------------
  42. // ------------------
  43. // ------------------ TgxOCTgxVectorFile ------------------
  44. // ------------------
  45. class function TgxOCTgxVectorFile.Capabilities: TDataFileCapabilities;
  46. begin
  47. Result := [dfcRead];
  48. end;
  49. procedure TgxOCTgxVectorFile.LoadFromStream(aStream: TStream);
  50. var
  51. i, y, n: integer;
  52. oct: TOCTFile;
  53. octFace: POCTFace;
  54. octLightmap: POCTLightmap;
  55. mo: TgxMeshObject;
  56. fg: TgxFGVertexIndexList;
  57. lightmapLib: TgxMaterialLibrary;
  58. lightmapBmp: TBitmap;
  59. libMat: TgxLibMaterial;
  60. begin
  61. oct := TOCTFile.Create(aStream);
  62. try
  63. mo := TgxMeshObject.CreateOwned(Owner.MeshObjects);
  64. mo.Mode := momFaceGroups;
  65. lightmapLib := Owner.LightmapLibrary;
  66. if (Assigned(lightmapLib)) and (vFileOCTAllocateMaterials) then
  67. begin
  68. // import lightmaps
  69. n := oct.Header.numLightmaps;
  70. lightmapBmp := TBitmap.Create;
  71. try
  72. // TODO : E2129 Cannot assign to a read-only property
  73. (*lightmapBmp.PixelFormat := glpf24bit;*)
  74. lightmapBmp.Width := 128;
  75. lightmapBmp.Height := 128;
  76. for i := 0 to n - 1 do
  77. begin
  78. octLightmap := @oct.Lightmaps[i];
  79. // Brightness correction
  80. if vFileOCTLightmapBrightness <> 1.0 then
  81. BrightenRGBArray(@octLightmap.map,
  82. lightmapBmp.Width * lightmapBmp.Height,
  83. vFileOCTLightmapBrightness);
  84. // Gamma correction
  85. if vFileOCTLightmapGammaCorrection <> 1.0 then
  86. GammaCorrectRGBArray(@octLightmap.map,
  87. lightmapBmp.Width * lightmapBmp.Height,
  88. vFileOCTLightmapGammaCorrection);
  89. // convert RAW RGB to BMP
  90. for y := 0 to 127 do
  91. // TODO : E2003 Undeclared identifier: 'ScanLine'
  92. (*
  93. Move(octLightmap.map[y * 128 * 3],
  94. lightmapBmp.ScanLine[127 - y]^, 128 * 3);
  95. *)
  96. // spawn lightmap
  97. libMat := lightmapLib.AddTextureMaterial(IntToStr(i), lightmapBmp);
  98. with libMat.Material.Texture do
  99. begin
  100. MinFilter := miLinear;
  101. TextureWrap := twNone;
  102. TextureFormat := tfRGB;
  103. end;
  104. end;
  105. finally
  106. lightmapBmp.Free;
  107. end;
  108. end;
  109. // import geometry
  110. n := oct.Header.numVerts;
  111. mo.Vertices.AdjustCapacityToAtLeast(n);
  112. mo.TexCoords.AdjustCapacityToAtLeast(n);
  113. mo.LightMapTexCoords.AdjustCapacityToAtLeast(n);
  114. for i := 0 to n - 1 do
  115. with oct.Vertices[i] do
  116. begin
  117. mo.Vertices.Add(pos.X, pos.Y, pos.Z);
  118. mo.TexCoords.Add(tv.s, tv.t);
  119. mo.LightMapTexCoords.Add(lv.s, lv.t);
  120. end;
  121. // import faces
  122. n := oct.Header.numFaces;
  123. for i := 0 to n - 1 do
  124. begin
  125. octFace := @oct.Faces[i];
  126. fg := TgxFGVertexIndexList.CreateOwned(mo.FaceGroups);
  127. fg.Mode := fgmmTriangleFan;
  128. fg.VertexIndices.AddSerie(octFace.start, 1, octFace.num);
  129. if (Assigned(lightmapLib)) and (vFileOCTAllocateMaterials) then
  130. fg.LightMapIndex := octFace.lid;
  131. end;
  132. finally
  133. oct.Free;
  134. end;
  135. end;
  136. // ------------------------------------------------------------------
  137. initialization
  138. // ------------------------------------------------------------------
  139. RegisterVectorFileFormat('oct', 'FSRad OCT files', TgxOCTgxVectorFile);
  140. end.