123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- //
- // The graphics engine GLScene
- //
- unit Formats.OCT;
- (* Loader for FSRad OCT files *)
- interface
- {$I Stage.Defines.inc}
- uses
- System.Classes,
- System.SysUtils,
- Stage.VectorGeometry,
- Stage.VectorTypes,
- GLS.VectorLists;
- type
- TOCTHeader = record
- numVerts: Integer;
- numFaces: Integer;
- numTextures: Integer;
- numLightmaps: Integer;
- numLights: Integer;
- end;
- TOCTVertex = record
- tv: TTexPoint; // texture coordinates
- lv: TTexPoint; // lightmap coordinates
- pos: TAffineVector; // vertex position
- end;
- TOCTFace = record
- start: Integer; // first face vert in vertex array
- num: Integer; // number of verts in the face
- id: Integer; // texture index into the texture array
- lid: Integer; // lightmap index into the lightmap array
- p: THmgPlane;
- end;
- POCTFace = ^TOCTFace;
- TOCTTexture = record
- id: Integer; // texture id
- Name: array [0 .. 63] of AnsiChar; // texture name
- end;
- TOCTLightmap = record
- id: Integer; // lightmaps id
- map: array [0 .. 49151] of Byte; // 128 x 128 raw RGB data
- end;
- POCTLightmap = ^TOCTLightmap;
- TOCTLight = record
- pos: TAffineVector; // Position
- color: TAffineVector; // Color (RGB)
- intensity: Integer; // Intensity
- end;
- TOCTFile = class(TObject)
- public
- Header: TOCTHeader;
- Vertices: array of TOCTVertex;
- Faces: array of TOCTFace;
- Textures: array of TOCTTexture;
- Lightmaps: array of TOCTLightmap;
- Lights: array of TOCTLight;
- PlayerPos: TAffineVector;
- constructor Create; overload;
- constructor Create(octStream: TStream); overload;
- (* Saves content to stream in OCT format.
- The Header is automatically prepared before streaming. *)
- procedure SaveToStream(aStream: TStream);
- procedure AddTriangles(vertexCoords: TGLAffineVectorList;
- texMapCoords: TGLAffineVectorList; const textureName: String);
- procedure AddLight(const lightPos: TAffineVector; const lightColor: TGLVector;
- lightIntensity: Integer);
- end;
- implementation // ------------------------------------------------------------
- // ------------------
- // ------------------ TOCTFile ------------------
- // ------------------
- constructor TOCTFile.Create;
- begin
- inherited Create;
- end;
- constructor TOCTFile.Create(octStream: TStream);
- begin
- inherited Create;
- // Read in the header
- octStream.Read(Header, SizeOf(Header));
- // then the rest of the stuff
- SetLength(Vertices, Header.numVerts);
- octStream.Read(Vertices[0], Header.numVerts * SizeOf(TOCTVertex));
- SetLength(Faces, Header.numFaces);
- octStream.Read(Faces[0], Header.numFaces * SizeOf(TOCTFace));
- SetLength(Textures, Header.numTextures);
- octStream.Read(Textures[0], Header.numTextures * SizeOf(TOCTTexture));
- SetLength(Lightmaps, Header.numLightmaps);
- octStream.Read(Lightmaps[0], Header.numLightmaps * SizeOf(TOCTLightmap));
- SetLength(Lights, Header.numLights);
- octStream.Read(Lights[0], Header.numLights * SizeOf(TOCTLight));
- octStream.Read(PlayerPos, SizeOf(PlayerPos))
- end;
- procedure TOCTFile.SaveToStream(aStream: TStream);
- begin
- with Header, aStream do
- begin
- numVerts := Length(Vertices);
- numFaces := Length(Faces);
- numTextures := Length(Textures);
- numLightmaps := Length(Lightmaps);
- numLights := Length(Lights);
- Write(Header, SizeOf(Header));
- Write(Vertices[0], numVerts * SizeOf(TOCTVertex));
- Write(Faces[0], numFaces * SizeOf(TOCTFace));
- Write(Textures[0], numTextures * SizeOf(TOCTTexture));
- Write(Lightmaps[0], numLightmaps * SizeOf(TOCTLightmap));
- Write(Lights[0], numLights * SizeOf(TOCTLight));
- Write(PlayerPos, SizeOf(PlayerPos))
- end;
- end;
- procedure TOCTFile.AddTriangles(vertexCoords: TGLAffineVectorList;
- texMapCoords: TGLAffineVectorList; const textureName: String);
- var
- i: Integer;
- baseIdx, texIdx: Integer;
- begin
- Assert((texMapCoords = nil) or (texMapCoords.Count = vertexCoords.Count));
- texIdx := Length(Textures);
- SetLength(Textures, texIdx + 1);
- Move(textureName[1], Textures[texIdx].Name[0], Length(textureName));
- SetLength(Lightmaps, 1);
- FillChar(Lightmaps[0].map[0], 128 * 3, 255);
- baseIdx := Length(Vertices);
- SetLength(Vertices, baseIdx + vertexCoords.Count);
- for i := 0 to vertexCoords.Count - 1 do
- with Vertices[baseIdx + i] do
- begin
- pos := vertexCoords.List[i];
- if Assigned(texMapCoords) then
- tv := PTexPoint(@texMapCoords.List[i])^;
- end;
- SetLength(Faces, vertexCoords.Count div 3);
- i := 0;
- while i < vertexCoords.Count do
- begin
- with Faces[i div 3] do
- begin
- start := baseIdx + i;
- num := 3;
- id := texIdx;
- p := PlaneMake(vertexCoords[i], CalcPlaneNormal(vertexCoords[i + 0],
- vertexCoords[i + 1], vertexCoords[i + 0]));
- end;
- Inc(i, 3);
- end;
- end;
- procedure TOCTFile.AddLight(const lightPos: TAffineVector;
- const lightColor: TGLVector; lightIntensity: Integer);
- var
- n: Integer;
- begin
- n := Length(Lights);
- SetLength(Lights, n + 1);
- with Lights[n] do
- begin
- pos := lightPos;
- color := PAffineVector(@lightColor)^;
- intensity := lightIntensity;
- end;
- end;
- //---------------------------------------------------------------------------
- end.
|