GLS.FileOCT.pas 4.2 KB

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