2
0

Formats.OCT.pas 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //
  2. // The graphics engine GLScene
  3. //
  4. unit Formats.OCT;
  5. (* Loader for FSRad OCT files *)
  6. interface
  7. {$I Stage.Defines.inc}
  8. uses
  9. System.Classes,
  10. System.SysUtils,
  11. Stage.VectorGeometry,
  12. Stage.VectorTypes,
  13. GLS.VectorLists;
  14. type
  15. TOCTHeader = record
  16. numVerts: Integer;
  17. numFaces: Integer;
  18. numTextures: Integer;
  19. numLightmaps: Integer;
  20. numLights: Integer;
  21. end;
  22. TOCTVertex = record
  23. tv: TTexPoint; // texture coordinates
  24. lv: TTexPoint; // lightmap coordinates
  25. pos: TAffineVector; // vertex position
  26. end;
  27. TOCTFace = record
  28. start: Integer; // first face vert in vertex array
  29. num: Integer; // number of verts in the face
  30. id: Integer; // texture index into the texture array
  31. lid: Integer; // lightmap index into the lightmap array
  32. p: THmgPlane;
  33. end;
  34. POCTFace = ^TOCTFace;
  35. TOCTTexture = record
  36. id: Integer; // texture id
  37. Name: array [0 .. 63] of AnsiChar; // texture name
  38. end;
  39. TOCTLightmap = record
  40. id: Integer; // lightmaps id
  41. map: array [0 .. 49151] of Byte; // 128 x 128 raw RGB data
  42. end;
  43. POCTLightmap = ^TOCTLightmap;
  44. TOCTLight = record
  45. pos: TAffineVector; // Position
  46. color: TAffineVector; // Color (RGB)
  47. intensity: Integer; // Intensity
  48. end;
  49. TOCTFile = class(TObject)
  50. public
  51. Header: TOCTHeader;
  52. Vertices: array of TOCTVertex;
  53. Faces: array of TOCTFace;
  54. Textures: array of TOCTTexture;
  55. Lightmaps: array of TOCTLightmap;
  56. Lights: array of TOCTLight;
  57. PlayerPos: TAffineVector;
  58. constructor Create; overload;
  59. constructor Create(octStream: TStream); overload;
  60. (* Saves content to stream in OCT format.
  61. The Header is automatically prepared before streaming. *)
  62. procedure SaveToStream(aStream: TStream);
  63. procedure AddTriangles(vertexCoords: TGLAffineVectorList;
  64. texMapCoords: TGLAffineVectorList; const textureName: String);
  65. procedure AddLight(const lightPos: TAffineVector; const lightColor: TGLVector;
  66. lightIntensity: Integer);
  67. end;
  68. implementation // ------------------------------------------------------------
  69. // ------------------
  70. // ------------------ TOCTFile ------------------
  71. // ------------------
  72. constructor TOCTFile.Create;
  73. begin
  74. inherited Create;
  75. end;
  76. constructor TOCTFile.Create(octStream: TStream);
  77. begin
  78. inherited Create;
  79. // Read in the header
  80. octStream.Read(Header, SizeOf(Header));
  81. // then the rest of the stuff
  82. SetLength(Vertices, Header.numVerts);
  83. octStream.Read(Vertices[0], Header.numVerts * SizeOf(TOCTVertex));
  84. SetLength(Faces, Header.numFaces);
  85. octStream.Read(Faces[0], Header.numFaces * SizeOf(TOCTFace));
  86. SetLength(Textures, Header.numTextures);
  87. octStream.Read(Textures[0], Header.numTextures * SizeOf(TOCTTexture));
  88. SetLength(Lightmaps, Header.numLightmaps);
  89. octStream.Read(Lightmaps[0], Header.numLightmaps * SizeOf(TOCTLightmap));
  90. SetLength(Lights, Header.numLights);
  91. octStream.Read(Lights[0], Header.numLights * SizeOf(TOCTLight));
  92. octStream.Read(PlayerPos, SizeOf(PlayerPos))
  93. end;
  94. procedure TOCTFile.SaveToStream(aStream: TStream);
  95. begin
  96. with Header, aStream do
  97. begin
  98. numVerts := Length(Vertices);
  99. numFaces := Length(Faces);
  100. numTextures := Length(Textures);
  101. numLightmaps := Length(Lightmaps);
  102. numLights := Length(Lights);
  103. Write(Header, SizeOf(Header));
  104. Write(Vertices[0], numVerts * SizeOf(TOCTVertex));
  105. Write(Faces[0], numFaces * SizeOf(TOCTFace));
  106. Write(Textures[0], numTextures * SizeOf(TOCTTexture));
  107. Write(Lightmaps[0], numLightmaps * SizeOf(TOCTLightmap));
  108. Write(Lights[0], numLights * SizeOf(TOCTLight));
  109. Write(PlayerPos, SizeOf(PlayerPos))
  110. end;
  111. end;
  112. procedure TOCTFile.AddTriangles(vertexCoords: TGLAffineVectorList;
  113. texMapCoords: TGLAffineVectorList; const textureName: String);
  114. var
  115. i: Integer;
  116. baseIdx, texIdx: Integer;
  117. begin
  118. Assert((texMapCoords = nil) or (texMapCoords.Count = vertexCoords.Count));
  119. texIdx := Length(Textures);
  120. SetLength(Textures, texIdx + 1);
  121. Move(textureName[1], Textures[texIdx].Name[0], Length(textureName));
  122. SetLength(Lightmaps, 1);
  123. FillChar(Lightmaps[0].map[0], 128 * 3, 255);
  124. baseIdx := Length(Vertices);
  125. SetLength(Vertices, baseIdx + vertexCoords.Count);
  126. for i := 0 to vertexCoords.Count - 1 do
  127. with Vertices[baseIdx + i] do
  128. begin
  129. pos := vertexCoords.List[i];
  130. if Assigned(texMapCoords) then
  131. tv := PTexPoint(@texMapCoords.List[i])^;
  132. end;
  133. SetLength(Faces, vertexCoords.Count div 3);
  134. i := 0;
  135. while i < vertexCoords.Count do
  136. begin
  137. with Faces[i div 3] do
  138. begin
  139. start := baseIdx + i;
  140. num := 3;
  141. id := texIdx;
  142. p := PlaneMake(vertexCoords[i], CalcPlaneNormal(vertexCoords[i + 0],
  143. vertexCoords[i + 1], vertexCoords[i + 0]));
  144. end;
  145. Inc(i, 3);
  146. end;
  147. end;
  148. procedure TOCTFile.AddLight(const lightPos: TAffineVector;
  149. const lightColor: TGLVector; lightIntensity: Integer);
  150. var
  151. n: Integer;
  152. begin
  153. n := Length(Lights);
  154. SetLength(Lights, n + 1);
  155. with Lights[n] do
  156. begin
  157. pos := lightPos;
  158. color := PAffineVector(@lightColor)^;
  159. intensity := lightIntensity;
  160. end;
  161. end;
  162. //---------------------------------------------------------------------------
  163. end.