Bladeren bron

Removed *res files

GLScene 5 jaren geleden
bovenliggende
commit
6869b44c53

+ 1 - 1
CleanRelease.bat

@@ -56,7 +56,7 @@ attrib +R "AdvDemos/Q3Demo/Model/animation.cfg"
 rem del *.cfg /s  - there are quake's animations
 rem del *.cfg /s  - there are quake's animations
 attrib -R "AdvDemos/Q3Demo/Model/animation.cfg"
 attrib -R "AdvDemos/Q3Demo/Model/animation.cfg"
 
 
-rem del *.res /s
+del *.res /s
 rem del *.ico /s  - some projects have own icos
 rem del *.ico /s  - some projects have own icos
 rem del *.cur /s  - cursors
 rem del *.cur /s  - cursors
 rem del *.obj /s  - obj models in media and resources for lazarus
 rem del *.obj /s  - obj models in media and resources for lazarus

+ 20 - 4
Demos/Delphi/glslshaders/ShadersLab/UMainForm.pas

@@ -9,6 +9,7 @@ uses
   System.SysUtils,
   System.SysUtils,
   System.Variants,
   System.Variants,
   System.Classes,
   System.Classes,
+  System.Math,
   Vcl.Graphics,
   Vcl.Graphics,
   Vcl.Controls,
   Vcl.Controls,
   Vcl.Forms,
   Vcl.Forms,
@@ -463,10 +464,25 @@ implementation
 
 
 {$R *.dfm}
 {$R *.dfm}
 
 
-uses Math,
-  GLFileOBJ, GLFileSTL, GLFileLWO, GLFileQ3BSP, GLFileOCT, GLFileMS3D,
-  GLFileNMF, GLFileMD3, GLFile3DS, GLFileMD2, GLFileSMD, GLFilePLY, GLFileGTS,
-  GLFileVRML, GLFileMD5, GLS.FileTIN, GLFileDXF, GLS.FileGRD;
+uses 
+  GLFileOBJ, 
+  GLFileSTL, 
+  GLFileLWO, 
+  GLFileQ3BSP, 
+  GLFileOCT, 
+  GLFileMS3D,
+  GLFileNMF, 
+  GLFileMD3, 
+  GLFile3DS, 
+  GLFileMD2, 
+  GLFileSMD, 
+  GLFilePLY, 
+  GLFileGTS,
+  GLFileVRML, 
+  GLFileMD5, 
+  GLS.FileTIN, 
+  GLFileDXF, 
+  GLS.FileGRD;
 
 
 procedure TMainForm.Button10Click(Sender: TObject);
 procedure TMainForm.Button10Click(Sender: TObject);
 begin
 begin

+ 3 - 27
Packages/GLScene.groupproj

@@ -33,12 +33,6 @@
         <Projects Include="GLScene_Cg_DT.dproj">
         <Projects Include="GLScene_Cg_DT.dproj">
             <Dependencies/>
             <Dependencies/>
         </Projects>
         </Projects>
-        <Projects Include="GLScene_SDL_RT.dproj">
-            <Dependencies/>
-        </Projects>
-        <Projects Include="GLScene_SDL_DT.dproj">
-            <Dependencies/>
-        </Projects>
     </ItemGroup>
     </ItemGroup>
     <ProjectExtensions>
     <ProjectExtensions>
         <Borland.Personality>Default.Personality.12</Borland.Personality>
         <Borland.Personality>Default.Personality.12</Borland.Personality>
@@ -137,32 +131,14 @@
     <Target Name="GLScene_Cg_DT:Make">
     <Target Name="GLScene_Cg_DT:Make">
         <MSBuild Projects="GLScene_Cg_DT.dproj" Targets="Make"/>
         <MSBuild Projects="GLScene_Cg_DT.dproj" Targets="Make"/>
     </Target>
     </Target>
-    <Target Name="GLScene_SDL_RT">
-        <MSBuild Projects="GLScene_SDL_RT.dproj"/>
-    </Target>
-    <Target Name="GLScene_SDL_RT:Clean">
-        <MSBuild Projects="GLScene_SDL_RT.dproj" Targets="Clean"/>
-    </Target>
-    <Target Name="GLScene_SDL_RT:Make">
-        <MSBuild Projects="GLScene_SDL_RT.dproj" Targets="Make"/>
-    </Target>
-    <Target Name="GLScene_SDL_DT">
-        <MSBuild Projects="GLScene_SDL_DT.dproj"/>
-    </Target>
-    <Target Name="GLScene_SDL_DT:Clean">
-        <MSBuild Projects="GLScene_SDL_DT.dproj" Targets="Clean"/>
-    </Target>
-    <Target Name="GLScene_SDL_DT:Make">
-        <MSBuild Projects="GLScene_SDL_DT.dproj" Targets="Make"/>
-    </Target>
     <Target Name="Build">
     <Target Name="Build">
-        <CallTarget Targets="GLScene_RT;GLScene_DT;GLScene_Sounds_RT;GLScene_Sounds_DT;GLScene_Physics_RT;GLScene_Physics_DT;GLScene_Parallel_RT;GLScene_Parallel_DT;GLScene_Cg_RT;GLScene_Cg_DT;GLScene_SDL_RT;GLScene_SDL_DT"/>
+        <CallTarget Targets="GLScene_RT;GLScene_DT;GLScene_Sounds_RT;GLScene_Sounds_DT;GLScene_Physics_RT;GLScene_Physics_DT;GLScene_Parallel_RT;GLScene_Parallel_DT;GLScene_Cg_RT;GLScene_Cg_DT"/>
     </Target>
     </Target>
     <Target Name="Clean">
     <Target Name="Clean">
-        <CallTarget Targets="GLScene_RT:Clean;GLScene_DT:Clean;GLScene_Sounds_RT:Clean;GLScene_Sounds_DT:Clean;GLScene_Physics_RT:Clean;GLScene_Physics_DT:Clean;GLScene_Parallel_RT:Clean;GLScene_Parallel_DT:Clean;GLScene_Cg_RT:Clean;GLScene_Cg_DT:Clean;GLScene_SDL_RT:Clean;GLScene_SDL_DT:Clean"/>
+        <CallTarget Targets="GLScene_RT:Clean;GLScene_DT:Clean;GLScene_Sounds_RT:Clean;GLScene_Sounds_DT:Clean;GLScene_Physics_RT:Clean;GLScene_Physics_DT:Clean;GLScene_Parallel_RT:Clean;GLScene_Parallel_DT:Clean;GLScene_Cg_RT:Clean;GLScene_Cg_DT:Clean"/>
     </Target>
     </Target>
     <Target Name="Make">
     <Target Name="Make">
-        <CallTarget Targets="GLScene_RT:Make;GLScene_DT:Make;GLScene_Sounds_RT:Make;GLScene_Sounds_DT:Make;GLScene_Physics_RT:Make;GLScene_Physics_DT:Make;GLScene_Parallel_RT:Make;GLScene_Parallel_DT:Make;GLScene_Cg_RT:Make;GLScene_Cg_DT:Make;GLScene_SDL_RT:Make;GLScene_SDL_DT:Make"/>
+        <CallTarget Targets="GLScene_RT:Make;GLScene_DT:Make;GLScene_Sounds_RT:Make;GLScene_Sounds_DT:Make;GLScene_Physics_RT:Make;GLScene_Physics_DT:Make;GLScene_Parallel_RT:Make;GLScene_Parallel_DT:Make;GLScene_Cg_RT:Make;GLScene_Cg_DT:Make"/>
     </Target>
     </Target>
     <Import Project="$(BDS)\Bin\CodeGear.Group.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')"/>
     <Import Project="$(BDS)\Bin\CodeGear.Group.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')"/>
 </Project>
 </Project>

BIN
Packages/GLScene.res


BIN
Packages/GLSceneObjects.res


BIN
Packages/GLSceneParallel.res


BIN
Packages/GLScenePhysics.res


BIN
Packages/GLSceneSDL.res


BIN
Packages/GLSceneShaders.res


BIN
Packages/GLSceneSounds.res


BIN
Packages/GLScene_Cg_DT.res


BIN
Packages/GLScene_Cg_RT.res


BIN
Packages/GLScene_DT.res


BIN
Packages/GLScene_Parallel_DT.res


BIN
Packages/GLScene_Parallel_RT.res


BIN
Packages/GLScene_Physics_DT.res


BIN
Packages/GLScene_Physics_RT.res


+ 2 - 2
Packages/GLScene_RT.dpk

@@ -45,13 +45,13 @@ contains
   FileHDRImage in '..\Source\FileHDRImage.pas',
   FileHDRImage in '..\Source\FileHDRImage.pas',
   FileQ3BSP in '..\Source\FileQ3BSP.pas',
   FileQ3BSP in '..\Source\FileQ3BSP.pas',
   FileQ3MD3 in '..\Source\FileQ3MD3.pas',
   FileQ3MD3 in '..\Source\FileQ3MD3.pas',
-  FileB3D in '..\Source\FileB3D.pas',
+  Formats.FileB3D in '..\Source\Formats.FileB3D.pas',
   Formats.FileGL2 in '..\Source\Formats.FileGL2.pas',
   Formats.FileGL2 in '..\Source\Formats.FileGL2.pas',
   Formats.FileLWObjects in '..\Source\Formats.FileLWObjects.pas',
   Formats.FileLWObjects in '..\Source\Formats.FileLWObjects.pas',
   FileMD2 in '..\Source\FileMD2.pas',
   FileMD2 in '..\Source\FileMD2.pas',
   FileMD3 in '..\Source\FileMD3.pas',
   FileMD3 in '..\Source\FileMD3.pas',
   FileO3TCImage in '..\Source\FileO3TCImage.pas',
   FileO3TCImage in '..\Source\FileO3TCImage.pas',
-  FileOCT in '..\Source\FileOCT.pas',
+  Formats.FileOCT in '..\Source\Formats.FileOCT.pas',
   FileTGA in '..\Source\FileTGA.pas',
   FileTGA in '..\Source\FileTGA.pas',
   Formats.FileX in '..\Source\Formats.FileX.pas',
   Formats.FileX in '..\Source\Formats.FileX.pas',
   Formats.FileVFW in '..\Source\Formats.FileVFW.pas',
   Formats.FileVFW in '..\Source\Formats.FileVFW.pas',

+ 2 - 2
Packages/GLScene_RT.dproj

@@ -148,13 +148,13 @@
         <DCCReference Include="..\Source\FileHDRImage.pas"/>
         <DCCReference Include="..\Source\FileHDRImage.pas"/>
         <DCCReference Include="..\Source\FileQ3BSP.pas"/>
         <DCCReference Include="..\Source\FileQ3BSP.pas"/>
         <DCCReference Include="..\Source\FileQ3MD3.pas"/>
         <DCCReference Include="..\Source\FileQ3MD3.pas"/>
-        <DCCReference Include="..\Source\FileB3D.pas"/>
+        <DCCReference Include="..\Source\Formats.FileB3D.pas"/>
         <DCCReference Include="..\Source\Formats.FileGL2.pas"/>
         <DCCReference Include="..\Source\Formats.FileGL2.pas"/>
         <DCCReference Include="..\Source\Formats.FileLWObjects.pas"/>
         <DCCReference Include="..\Source\Formats.FileLWObjects.pas"/>
         <DCCReference Include="..\Source\FileMD2.pas"/>
         <DCCReference Include="..\Source\FileMD2.pas"/>
         <DCCReference Include="..\Source\FileMD3.pas"/>
         <DCCReference Include="..\Source\FileMD3.pas"/>
         <DCCReference Include="..\Source\FileO3TCImage.pas"/>
         <DCCReference Include="..\Source\FileO3TCImage.pas"/>
-        <DCCReference Include="..\Source\FileOCT.pas"/>
+        <DCCReference Include="..\Source\Formats.FileOCT.pas"/>
         <DCCReference Include="..\Source\FileTGA.pas"/>
         <DCCReference Include="..\Source\FileTGA.pas"/>
         <DCCReference Include="..\Source\Formats.FileX.pas"/>
         <DCCReference Include="..\Source\Formats.FileX.pas"/>
         <DCCReference Include="..\Source\Formats.FileVFW.pas"/>
         <DCCReference Include="..\Source\Formats.FileVFW.pas"/>

BIN
Packages/GLScene_RT.res


BIN
Packages/GLScene_SDL_DT.res


BIN
Packages/GLScene_SDL_RT.res


BIN
Packages/GLScene_Sounds_DT.res


BIN
Packages/GLScene_Sounds_RT.res


+ 684 - 686
Source/FileB3D.pas → Source/Formats.FileB3D.pas

@@ -1,686 +1,684 @@
-//
-// This unit is part of the GLScene Engine, http://glscene.org
-//
-
-unit FileB3D;
-
-(* File streaming class for the B3D loader *)
-
-interface
-
-{$I GLScene.inc}
-{$R-}
-
-uses
-  System.Classes, 
-  System.SysUtils,
-   
-  Scene.VectorGeometry, 
-  Scene.VectorTypes, 
-  Scene.VectorLists;
-
-
-type
-  TB3DChunkType = (bctUnknown, bctHeader, bctTexture, bctBrush, bctNode, bctVertex, bctTriangle,
-    bctMesh, bctBone, bctKeyFrame, bctAnimation);
-
-  PB3DChunk = ^TB3DChunk;
-  TB3DChunk = record
-    chunk: array[0..3] of char;
-    length: Integer;
-  end;
-
-  PBB3DChunk = ^TBB3DChunk;
-  TBB3DChunk = record
-    Version: Integer;
-  end;
-
-  PTEXSChunk = ^TTEXSChunk;
-  TTEXSChunk = record
-    fileName: array[0..255] of char; //texture file name this is the filename of the texture, ie "wall.bmp"  Has to be in the local Directory
-    flags, blend: Integer;  //blitz3D TextureFLags and TextureBlend: default=1,2
-  		            //these are the same as far as I know as the flags for a texture in Blitz3D
-    x_pos, y_pos: Single;   //x and y position of texture: default=0,0
-    x_scale, y_scale: Single; //x and y scale of texture: default=1,1
-    rotation: Single;         //rotation of texture (in radians): default=0 radian = 180/pi degrees
-  end;
-
-  PBRUSChunk = ^TBRUSChunk;
-  TBRUSChunk = record
-    n_texs: Integer;
-    name: array[0..255] of Char; //eg "WATER" - just use texture name by default
-    red, green, blue, alpha: Single;  //Blitz3D Brushcolor and Brushalpha: default=1,1,1,1
-    shininess: Single; //Blitz3D BrushShininess: default=0
-    blend, fx: Integer; //Blitz3D Brushblend and BrushFX: default=1,0
-    texture_id: array of Integer; //textures used in brush, ie if there is more then one texture used, ie Alphamaps, colour maps etc,
-                                  //you put all ID's here as ints.
-  end;
-
-  PVertexData = ^TVertexData;
-  TVertexData = record
-    next: PVertexData;
-    x, y, z: Single; //always present
-    nx, ny, nz: Single; //vertex normal: present if (flags&1)
-    red, green, blue, alpha: Single; //vertex color: present if (flags&2)
-    tex_coords: array of Single; //tex coords
-  end;
-
-  PVRTSChunk = ^TVRTSChunk;
-  TVRTSChunk = record
-    flags: Integer; //1=normal values present, 2=rgba values present
-    tex_coord_sets: Integer; //texture coords per vertex (eg: 1 for simple U/V) max=8
-    tex_coord_set_size: Integer; //components per set (eg: 2 for simple U/V) max=4
-    vertices: PVertexData;
-  end;
-
-  PTRISChunk = ^TTRISChunk;
-  TTRISChunk = record
-    next: PTRISChunk;
-    brush_id: Integer; //brush applied to these TRIs: default=-1
-    vertex_id: array of Integer; //vertex indices
-  end;
-
-  PMESHChunk = ^TMESHChunk;
-  TMESHChunk = record
-    brush_id: Integer; //'master' brush: default=-1
-    vertices: TVRTSChunk;  //vertices
-    triangles: PTRISChunk;  //1 or more sets of triangles
-  end;
-
-  PBONEChunk = ^TBONEChunk;
-  TBONEChunk = record
-    vertex_id: Integer; //vertex affected by this bone
-    weight: Single; //;how much the vertex is affected
-  end;
-
-  PKEYSChunk = ^TKEYSChunk;
-  TKEYSChunk = record
-    next: PKEYSChunk;
-    flags: Integer; //1=position, 2=scale, 4=rotation
-    frame: Integer; //where key occurs
-    position: TAffineVector; //present if (flags&1)
-    scale: TAffineVector; //present if (flags&2)
-    rotation: TVector; //present if (flags&4)
-  end;
-
-  PANIMChunk = ^TANIMChunk;
-  TANIMChunk = record
-    flags: Integer; //unused: default=0
-    frames: Integer; //how many frames in anim
-    fps: Single; //default=60
-  end;
-
-  PNODEChunk = ^TNODEChunk;
-  TNODEChunk = record
-    name: array[0..255] of char; //name of node
-    position: TAffineVector;  //local...
-    scale: TAffineVector; //coord...
-    rotation: TVector; //system...
-    //array of node elements
-    //should be one of meshes or bones, support meshes only for now
-    meshes: PMESHChunk; //what 'kind' of node this is - if unrecognized, just use a Blitz3D pivot.
-    {
-    not supprot yet
-    bones: PBONEChunk;
-    }
-    keys: PKEYSChunk; //optional animation keys
-    nodes: PNODEChunk; //optional child nodes
-    animation: TANIMChunk; //optional animation
-    next: PNODEChunk; //point to the next node
-    level: Integer;
-  end;
-
-type
-  TB3DMaterial = class
-  public
-    MaterialData: TBRUSChunk;
-    constructor Create;
-    destructor Destroy; override;
-    function GetMaterialName: string;
-  end;
-
-  TB3DTexture = class
-  public
-    TextureData: TTEXSChunk;
-    constructor Create;
-    destructor Destroy; override;
-    function GetTextureName: string;
-  end;
-
-  TB3DNode = class
-  public
-    NodeData: PNODEChunk;
-    constructor Create;
-    destructor Destroy; override;
-    function GetNodeName: string;
-    procedure DestroyNodeData(Node: PNODEChunk);
-  end;
-
-  // TFileB3D
-  //
-  TFileB3D = class
-  private
-    fTextures: TStringList;
-    fMaterials: TStringList;
-    fNodes: TB3DNode;
-    procedure FreeLists;
-    function GetChunkType(const aChunk: TB3DChunk): TB3DChunkType;
-    function SkipChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
-    function ReadTextureChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
-    function ReadMaterialChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
-    function ReadNodeChunk(aStream: TStream; const aChunk: TB3DChunk; Node: PNODEChunk; level: Integer): Integer;
-    function ReadMeshChunk(aStream: TStream; const aChunk: TB3DChunk; Mesh: PMESHChunk): Integer;
-    function ReadVerticesChunk(aStream: TStream; const aChunk: TB3DChunk; Vertices: PVRTSChunk): Integer;
-    function ReadTrianglesChunk(aStream: TStream; const aChunk: TB3DChunk; Triangle: PTRISChunk): Integer;
-  public
-    constructor Create; virtual;
-    destructor Destroy; override;
-    procedure LoadFromStream(aStream : TStream);
-    //for test only
-    procedure Check;
-    
-    property Textures: TStringList read fTextures;
-    property Materials: TStringList read fMaterials;
-    property Nodes: TB3DNode read fNodes;
-  end;
-
-//-----------------------------------------------------------------------
-implementation
-//-----------------------------------------------------------------------
-
-constructor TB3DMaterial.Create;
-begin
-  inherited Create;
-  fillChar(MaterialData, sizeof(TBRUSChunk), 0);
-end;
-
-destructor TB3DMaterial.Destroy;
-begin
-  SetLength(MaterialData.texture_id, 0);
-  inherited Destroy;
-end;
-
-function TB3DMaterial.GetMaterialName: string;
-begin
-  SetString(Result, MaterialData.name, strlen(MaterialData.name));
-end;
-
-constructor TB3DTexture.Create;
-begin
-  inherited Create;
-  fillChar(TextureData, sizeof(TTEXSChunk), 0);
-end;
-
-destructor TB3DTexture.Destroy;
-begin
-  inherited Destroy;
-end;
-
-function TB3DTexture.GetTextureName: string;
-begin
-  SetString(Result, TextureData.fileName, strlen(TextureData.fileName));
-end;
-
-constructor TB3DNode.Create;
-begin
-  inherited Create;
-  NodeData := nil;
-end;
-
-destructor TB3DNode.Destroy;
-begin
-  DestroyNodeData(NodeData);
-  inherited Destroy;
-end;
-
-function TB3DNode.GetNodeName: string;
-begin
-  SetString(Result, NodeData^.name, strlen(NodeData^.name));
-end;
-
-procedure DeleteVertices(var aVertex: PVertexData);
-var
-  V: PVertexData;
-begin
-  while aVertex<>nil do
-  begin
-    SetLength(aVertex^.tex_coords, 0);
-    V := aVertex^.next;
-    freeMem(aVertex);
-    aVertex := nil;
-    DeleteVertices(V);
-  end;
-end;
-
-procedure DeleteTriangles(var aTriangle: PTRISChunk);
-var
-  T: PTRISChunk;
-begin
-  while aTriangle<>nil do
-  begin
-    SetLength(aTriangle^.vertex_id, 0);
-    T := aTriangle^.next;
-    freeMem(aTriangle);
-    aTriangle := nil;
-    DeleteTriangles(T);
-  end;
-end;
-
-procedure TB3DNode.DestroyNodeData(Node: PNODEChunk);
-var
-  oldNode, PNode: PNODEChunk;
-begin
-  PNode := Node;
-  while PNode<>nil do
-  begin
-    if PNode^.meshes<>nil then
-    begin
-      DeleteTriangles(PNode^.meshes^.triangles);
-      DeleteVertices(PNode^.meshes^.vertices.vertices);
-      freeMem(PNode^.meshes);
-      PNode^.meshes := nil;
-    end;
-    if PNode^.keys<>nil then
-      freeMem(PNode^.keys);
-    DestroyNodeData(PNode^.nodes);
-    oldNode := PNode;
-    PNode := PNode^.next;
-    freeMem(oldNode);
-  end;
-end;
-
-//------------------------------------------------------------------------------
-constructor TFileB3D.Create;
-begin
-  inherited Create;
-  fTextures := TStringList.Create;
-  fMaterials := TStringList.Create;
-  fNodes := TB3DNode.Create;
-end;
-
-destructor TFileB3D.Destroy;
-begin
-  FreeLists;
-  fTextures.free;
-  fMaterials.free;
-  fNodes.free;
-  inherited Destroy;
-end;
-
-function TFileB3D.GetChunkType(const aChunk: TB3DChunk): TB3DChunkType;
-begin
-  Result := bctUnKnown;
-  if StrLIComp(aChunk.chunk, 'BB3D', 4)=0 then
-    Result := bctHeader;
-  if StrLIComp(aChunk.chunk, 'TEXS', 4)=0 then
-    Result := bctTexture;
-  if StrLIComp(aChunk.chunk, 'BRUS', 4)=0 then
-    Result := bctBrush;
-  if StrLIComp(aChunk.chunk, 'NODE', 4)=0 then
-    Result := bctNode;
-  if StrLIComp(aChunk.chunk, 'VRTS', 4)=0 then
-    Result := bctVertex;
-  if StrLIComp(aChunk.chunk, 'BONE', 4)=0 then
-    Result := bctBone;
-  if StrLIComp(aChunk.chunk, 'KEYS', 4)=0 then
-    Result := bctKeyFrame;
-  if StrLIComp(aChunk.chunk, 'ANIM', 4)=0 then
-    Result := bctAnimation;
-  if StrLIComp(aChunk.chunk, 'MESH', 4)=0 then
-    Result := bctMesh;
-  if StrLIComp(aChunk.chunk, 'TRIS', 4)=0 then
-    Result := bctTriangle;
-end;
-
-function TFileB3D.SkipChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
-begin
-  aStream.Seek(aChunk.length, soFromCurrent);
-  Result := aChunk.length;
-end;
-
-function ReadString(aStream: TStream; buffer: PChar; MaxCount: Integer): Integer;
-begin
-  Result := 0;
-  while Result<MaxCount do
-  begin
-    aStream.Read(buffer[Result], sizeof(char));
-    Inc(result);
-    if buffer[result-1]=#0 then
-      break;
-  end;
-end;
-
-function TFileB3D.ReadTextureChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
-var
-  Texture: TB3DTexture;
-  Count: Integer;
-begin
-  Result := 0;
-  if aChunk.length<5 then
-    exit;
-  Count := 0;
-  while Count<aChunk.length do
-  begin
-    Texture := TB3DTexture.Create;
-    Inc(Count, ReadString(aStream, Texture.TextureData.fileName, 255));
-    Inc(Count, aStream.Read(Texture.TextureData.flags, sizeof(integer)));
-    Inc(Count, aStream.Read(Texture.TextureData.blend, sizeof(integer)));
-    Inc(Count, aStream.Read(Texture.TextureData.x_pos, sizeof(single)));
-    Inc(Count, aStream.Read(Texture.TextureData.y_pos, sizeof(single)));
-    Inc(Count, aStream.Read(Texture.TextureData.x_scale, sizeof(single)));
-    Inc(Count, aStream.Read(Texture.TextureData.y_scale, sizeof(single)));
-    Inc(Count, aStream.Read(Texture.TextureData.rotation, sizeof(single)));
-    fTextures.AddObject(Texture.GetTextureName, Texture);
-  end;
-  Result := fTextures.Count;
-end;
-
-function TFileB3D.ReadMaterialChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
-var
-  Material: TB3DMaterial;
-  Count, I: Integer;
-  TextureCount: Integer;
-begin
-  Result := 0;
-  if aChunk.length<5 then
-    exit;
-  Count := 0;
-  TextureCount := 0;
-  while Count<aChunk.length do
-  begin
-    Material := TB3DMaterial.Create;
-    if Count=0 then
-    begin
-      Inc(Count, aStream.Read(Material.MaterialData.n_texs, sizeof(integer)));
-      TextureCount := Material.MaterialData.n_texs;
-    end else
-      Material.MaterialData.n_texs := TextureCount;
-    Inc(Count, ReadString(aStream, Material.MaterialData.name, 255));
-    Inc(Count, aStream.Read(Material.MaterialData.red, sizeof(single)));
-    Inc(Count, aStream.Read(Material.MaterialData.green, sizeof(single)));
-    Inc(Count, aStream.Read(Material.MaterialData.blue, sizeof(single)));
-    Inc(Count, aStream.Read(Material.MaterialData.alpha, sizeof(single)));
-    Inc(Count, aStream.Read(Material.MaterialData.shininess, sizeof(single)));
-    Inc(Count, aStream.Read(Material.MaterialData.blend, sizeof(integer)));
-    Inc(Count, aStream.Read(Material.MaterialData.fx, sizeof(integer)));
-    SetLength(Material.MaterialData.texture_id, TextureCount);
-    for I:=0 to TextureCount-1 do
-      Inc(Count, aStream.Read(Material.MaterialData.texture_id[I], sizeof(Integer)));
-    fMaterials.AddObject(Material.GetMaterialName, Material);
-  end;
-  Result := fMaterials.Count;
-end;
-
-function TFileB3D.ReadMeshChunk(aStream: TStream; const aChunk: TB3DChunk; Mesh: PMESHChunk): Integer;
-var
-  C: TB3DChunk;
-  T: PTRISChunk;
-begin
-  Result := 0;
-  fillChar(Mesh^, sizeof(TMESHChunk), 0);
-  Mesh^.brush_id := -1;
-  Inc(Result, aStream.Read(Mesh^.brush_id, sizeof(Integer)));
-  T := nil;
-  while Result<aChunk.length do
-  begin
-    Inc(Result, aStream.Read(C, sizeof(TB3DChunk)));
-    case GetChunkType(C) of
-      bctVertex:
-      begin
-        Inc(Result, ReadVerticesChunk(aStream, C, @(Mesh^.vertices)));
-      end;
-      bctTriangle:
-      begin
-        if Mesh^.triangles=nil then
-        begin
-          GetMem(Mesh^.triangles, sizeof(TTRISChunk));
-          fillChar(Mesh^.triangles^, sizeof(TTRISChunk), 0);
-          Inc(Result, ReadTrianglesChunk(aStream, C, Mesh^.triangles));
-        end else
-        begin
-          if T=nil then
-          begin
-            GetMem(T, sizeof(TTRISChunk));
-            fillChar(T^, sizeof(TTRISChunk), 0);
-            Inc(Result, ReadTrianglesChunk(aStream, C, T));
-            Mesh^.triangles^.next := T;
-          end else
-          begin
-            GetMem(T^.next, sizeof(TTRISChunk));
-            fillChar(T^.next^, sizeof(TTRISChunk), 0);
-            Inc(Result, ReadTrianglesChunk(aStream, C, T^.next));
-            T := T^.next;
-          end;
-        end;
-      end;
-      else
-        inc(Result, SkipChunk(aStream, C));
-    end;
-  end;
-end;
-
-function TFileB3D.ReadVerticesChunk(aStream: TStream; const aChunk: TB3DChunk; Vertices: PVRTSChunk): Integer;
-var
-  v: PVertexData;
-  v1: PVertexData;
-  size: Integer;
-begin
-  Result := 0;
-  fillChar(Vertices^, sizeof(TVRTSChunk), 0);
-  Inc(Result, aStream.Read(Vertices^.flags, sizeof(Integer)));
-  Inc(Result, aStream.Read(Vertices^.tex_coord_sets, sizeof(Integer)));
-  Inc(Result, aStream.Read(Vertices^.tex_coord_set_size, sizeof(Integer)));
-  size := Vertices^.tex_coord_set_size*Vertices^.tex_coord_sets;
-  v := nil;
-  while Result<aChunk.length do
-  begin
-    if Vertices^.vertices=nil then
-    begin
-      GetMem(Vertices^.vertices, sizeof(TVertexData));
-      fillChar(vertices^.vertices^, sizeof(TVertexData), 0);
-    end else
-    begin
-      if v=nil then
-      begin
-        GetMem(v, sizeof(TVertexData));
-        fillChar(v^, sizeof(TVertexData), 0);
-        vertices^.vertices^.next := v;
-      end else
-      begin
-        GetMem(v^.next, sizeof(TVertexData));
-        fillChar(v^.next^, sizeof(TVertexData), 0);
-        v := v^.next;
-      end;
-    end;
-    if v=nil then
-      v1 := vertices^.vertices
-    else
-      v1 := v;
-    Inc(Result, aStream.Read(v1^.x, sizeof(single)));
-    Inc(Result, aStream.Read(v1^.y, sizeof(single)));
-    Inc(Result, aStream.Read(v1^.z, sizeof(single)));
-    //W3D Begin
-    if (Vertices^.flags and 1)>0 then begin
-      Inc(Result, aStream.Read(v1^.nx, sizeof(single)));
-      Inc(Result, aStream.Read(v1^.ny, sizeof(single)));
-      Inc(Result, aStream.Read(v1^.nz, sizeof(single)));
-    end;
-    if (Vertices^.flags and 2)>0 then begin
-      Inc(Result, aStream.Read(v1^.red, sizeof(single)));
-      Inc(Result, aStream.Read(v1^.green, sizeof(single)));
-      Inc(Result, aStream.Read(v1^.blue, sizeof(single)));
-      Inc(Result, aStream.Read(v1^.alpha, sizeof(single)));
-    end;
-    //W3D END
-    SetLength(v1^.tex_coords, size);
-    Inc(Result, aStream.Read(v1^.tex_coords[0], size*sizeof(single)));
-  end;
-end;
-
-function TFileB3D.ReadTrianglesChunk(aStream: TStream; const aChunk: TB3DChunk; Triangle: PTRISChunk): Integer;
-begin
-  Result := 0;
-  if Triangle=nil then
-  begin
-    GetMem(Triangle, sizeof(TTRISChunk));
-    fillChar(Triangle^, sizeof(TTRISChunk), 0);
-    Triangle^.brush_id := -1;
-  end;
-  Inc(Result, aStream.Read(Triangle^.brush_id, sizeof(Integer)));
-  SetLength(Triangle^.vertex_id, (aChunk.length-Result) div sizeof(Integer));
-  Inc(Result, aStream.Read(Triangle^.vertex_id[0], (aChunk.length-Result)));
-end;
-
-//read in only the mesh data, the keyframes and animation had been dropped
-function TFileB3D.ReadNodeChunk(aStream: TStream; const aChunk: TB3DChunk; Node: PNODEChunk; level: Integer): Integer;
-var
-  Count: Integer;
-  C: TB3DChunk;
-  N: PNODEChunk;
-begin
-  N := nil;
-  fillChar(Node^, sizeof(TNODEChunk), 0);
-  Node^.level := level;
-  Count := 0;
-  Inc(Count, ReadString(aStream, Node^.name, 255));
-  Inc(Count, aStream.Read(Node^.position.X, sizeof(TAffineVector)));
-  Inc(Count, aStream.Read(Node^.scale.X, sizeof(TAffineVector)));
-  Inc(Count, aStream.Read(Node^.rotation.X, sizeof(TVector)));
-  while Count<aChunk.length do
-  begin
-    Inc(Count, aStream.Read(C, sizeof(TB3DChunk)));
-    case GetChunkType(C) of
-      bctMesh:
-      begin
-        GetMem(Node^.meshes, sizeof(TMESHChunk));
-        Inc(Count, ReadMeshChunk(aStream, C, Node^.meshes));
-      end;
-      bctKeyframe:
-      begin
-        Inc(Count, SkipChunk(aStream, C));
-      end;
-      bctNode:
-      begin
-        if N=nil then
-        begin
-          GetMem(N, sizeof(TNODEChunk));
-          fillChar(N^, sizeof(TNODEChunk), 0);
-          Inc(Count, ReadNodeChunk(aStream, C, N, level + 1));
-          Node^.next := N;
-        end else
-        begin
-          GetMem(N^.next, sizeof(TNODEChunk));
-          fillChar(N^.next^, sizeof(TNODEChunk), 0);
-          Inc(Count, ReadNodeChunk(aStream, C, N^.next, level + 1));
-          N := N^.next;
-        end;
-      end;
-      bctAnimation:
-      begin
-        Inc(Count, SkipChunk(aStream, C));
-      end;
-      else
-        Inc(Count, SkipChunk(aStream, C));
-    end;
-  end;
-  Result := Count;
-end;
-
-procedure TFileB3D.LoadFromStream(aStream : TStream);
-var
-  aChunk: TB3DChunk;
-  FileSize: Integer;
-begin
-  FileSize := aStream.Size;
-  while aStream.Position<FileSize do
-  begin
-    aStream.Read(aChunk, sizeof(TB3DChunk));
-    case GetChunkType(aChunk) of
-      bctHeader:
-      begin
-        FileSize := aChunk.length - sizeof(TB3DChunk) - sizeof(TBB3DChunk);
-        aStream.Seek(sizeof(TBB3DChunk), soFromCurrent);
-      end;
-      bctTexture:
-      begin
-        ReadTextureChunk(aStream, aChunk);
-      end;
-      bctBrush:
-      begin
-        ReadMaterialChunk(aStream, aChunk);
-      end;
-      bctNode:
-      begin
-        if fNodes.NodeData=nil then
-        begin
-          GetMem(fNodes.NodeData, sizeof(TNODEChunk));
-          ReadNodeChunk(aStream, aChunk, fNodes.NodeData, 0);
-        end;
-      end;
-      else
-        SkipChunk(aStream, aChunk);
-    end;
-  end;
-end;
-
-procedure TFileB3D.FreeLists;
-begin
-  while fTextures.Count>0 do
-  begin
-    fTextures.Objects[0].free;
-    ftextures.Delete(0);
-  end;
-  while fMaterials.Count>0 do
-  begin
-    fMaterials.Objects[0].free;
-    fMaterials.Delete(0);
-  end;
-end;
-
-//for test only
-procedure TFileB3D.Check;
-var
-  NodeLevel: Integer;
-//  NodeCount: Integer;
-  Node: PNODEChunk;
-//  VerticesCount: Integer;
-//  FaceCount: Integer;
-  Face: PTRISChunk;
-  Vertex: PVertexData;
-begin
-  NodeLevel := 0;
-//  NodeCount := 0;
-//  VerticesCount := 0;
-//  FaceCount := 0;
-  Node := fNodes.NodeData;
-  while Node<>nil do
-  begin
-    if Node^.meshes<>nil then
-//      Inc(NodeCount);
-    if Node^.level>NodeLevel then
-      NodeLevel := Node^.level;
-    if Node^.meshes<>nil then
-    begin
-      Vertex := Node^.meshes.vertices.vertices;
-      while Vertex<>nil do
-      begin
-//        Inc(VerticesCount);
-        Vertex := Vertex.next;
-      end;
-      Face := Node^.meshes.triangles;
-      while Face<>nil do
-      begin
-//        Inc(FaceCount);
-        Face := Face.next;
-      end;
-    end;
-    Node := Node^.next;
-  end;
-
-  //MessageBeep(FaceCount);
-  //MessageBeep(VerticesCount);
-  //MessageBeep(NodeLevel);
-  //MessageBeep(NodeCount);
-end;
-
-end.
+//
+// This unit is part of the GLScene Engine, http://glscene.org
+//
+
+unit Formats.FileB3D;
+
+(* File streaming class for the B3D loader *)
+
+interface
+
+{$I GLScene.inc}
+{$R-}
+
+uses
+  System.Classes, 
+  System.SysUtils,
+   
+  Scene.VectorGeometry, 
+  Scene.VectorTypes, 
+  Scene.VectorLists;
+
+
+type
+  TB3DChunkType = (bctUnknown, bctHeader, bctTexture, bctBrush, bctNode, bctVertex, bctTriangle,
+    bctMesh, bctBone, bctKeyFrame, bctAnimation);
+
+  PB3DChunk = ^TB3DChunk;
+  TB3DChunk = record
+    chunk: array[0..3] of char;
+    length: Integer;
+  end;
+
+  PBB3DChunk = ^TBB3DChunk;
+  TBB3DChunk = record
+    Version: Integer;
+  end;
+
+  PTEXSChunk = ^TTEXSChunk;
+  TTEXSChunk = record
+    fileName: array[0..255] of char; //texture file name this is the filename of the texture, ie "wall.bmp"  Has to be in the local Directory
+    flags, blend: Integer;  //blitz3D TextureFLags and TextureBlend: default=1,2
+  		            //these are the same as far as I know as the flags for a texture in Blitz3D
+    x_pos, y_pos: Single;   //x and y position of texture: default=0,0
+    x_scale, y_scale: Single; //x and y scale of texture: default=1,1
+    rotation: Single;         //rotation of texture (in radians): default=0 radian = 180/pi degrees
+  end;
+
+  PBRUSChunk = ^TBRUSChunk;
+  TBRUSChunk = record
+    n_texs: Integer;
+    name: array[0..255] of Char; //eg "WATER" - just use texture name by default
+    red, green, blue, alpha: Single;  //Blitz3D Brushcolor and Brushalpha: default=1,1,1,1
+    shininess: Single; //Blitz3D BrushShininess: default=0
+    blend, fx: Integer; //Blitz3D Brushblend and BrushFX: default=1,0
+    texture_id: array of Integer; //textures used in brush, ie if there is more then one texture used, ie Alphamaps, colour maps etc,
+                                  //you put all ID's here as ints.
+  end;
+
+  PVertexData = ^TVertexData;
+  TVertexData = record
+    next: PVertexData;
+    x, y, z: Single; //always present
+    nx, ny, nz: Single; //vertex normal: present if (flags&1)
+    red, green, blue, alpha: Single; //vertex color: present if (flags&2)
+    tex_coords: array of Single; //tex coords
+  end;
+
+  PVRTSChunk = ^TVRTSChunk;
+  TVRTSChunk = record
+    flags: Integer; //1=normal values present, 2=rgba values present
+    tex_coord_sets: Integer; //texture coords per vertex (eg: 1 for simple U/V) max=8
+    tex_coord_set_size: Integer; //components per set (eg: 2 for simple U/V) max=4
+    vertices: PVertexData;
+  end;
+
+  PTRISChunk = ^TTRISChunk;
+  TTRISChunk = record
+    next: PTRISChunk;
+    brush_id: Integer; //brush applied to these TRIs: default=-1
+    vertex_id: array of Integer; //vertex indices
+  end;
+
+  PMESHChunk = ^TMESHChunk;
+  TMESHChunk = record
+    brush_id: Integer; //'master' brush: default=-1
+    vertices: TVRTSChunk;  //vertices
+    triangles: PTRISChunk;  //1 or more sets of triangles
+  end;
+
+  PBONEChunk = ^TBONEChunk;
+  TBONEChunk = record
+    vertex_id: Integer; //vertex affected by this bone
+    weight: Single; //;how much the vertex is affected
+  end;
+
+  PKEYSChunk = ^TKEYSChunk;
+  TKEYSChunk = record
+    next: PKEYSChunk;
+    flags: Integer; //1=position, 2=scale, 4=rotation
+    frame: Integer; //where key occurs
+    position: TAffineVector; //present if (flags&1)
+    scale: TAffineVector; //present if (flags&2)
+    rotation: TVector; //present if (flags&4)
+  end;
+
+  PANIMChunk = ^TANIMChunk;
+  TANIMChunk = record
+    flags: Integer; //unused: default=0
+    frames: Integer; //how many frames in anim
+    fps: Single; //default=60
+  end;
+
+  PNODEChunk = ^TNODEChunk;
+  TNODEChunk = record
+    name: array[0..255] of char; //name of node
+    position: TAffineVector;  //local...
+    scale: TAffineVector; //coord...
+    rotation: TVector; //system...
+    //array of node elements
+    //should be one of meshes or bones, support meshes only for now
+    meshes: PMESHChunk; //what 'kind' of node this is - if unrecognized, just use a Blitz3D pivot.
+    (*
+    not supprot yet
+    bones: PBONEChunk;
+    *)
+    keys: PKEYSChunk; //optional animation keys
+    nodes: PNODEChunk; //optional child nodes
+    animation: TANIMChunk; //optional animation
+    next: PNODEChunk; //point to the next node
+    level: Integer;
+  end;
+
+type
+  TB3DMaterial = class
+  public
+    MaterialData: TBRUSChunk;
+    constructor Create;
+    destructor Destroy; override;
+    function GetMaterialName: string;
+  end;
+
+  TB3DTexture = class
+  public
+    TextureData: TTEXSChunk;
+    constructor Create;
+    destructor Destroy; override;
+    function GetTextureName: string;
+  end;
+
+  TB3DNode = class
+  public
+    NodeData: PNODEChunk;
+    constructor Create;
+    destructor Destroy; override;
+    function GetNodeName: string;
+    procedure DestroyNodeData(Node: PNODEChunk);
+  end;
+
+  TFileB3D = class
+  private
+    fTextures: TStringList;
+    fMaterials: TStringList;
+    fNodes: TB3DNode;
+    procedure FreeLists;
+    function GetChunkType(const aChunk: TB3DChunk): TB3DChunkType;
+    function SkipChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
+    function ReadTextureChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
+    function ReadMaterialChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
+    function ReadNodeChunk(aStream: TStream; const aChunk: TB3DChunk; Node: PNODEChunk; level: Integer): Integer;
+    function ReadMeshChunk(aStream: TStream; const aChunk: TB3DChunk; Mesh: PMESHChunk): Integer;
+    function ReadVerticesChunk(aStream: TStream; const aChunk: TB3DChunk; Vertices: PVRTSChunk): Integer;
+    function ReadTrianglesChunk(aStream: TStream; const aChunk: TB3DChunk; Triangle: PTRISChunk): Integer;
+  public
+    constructor Create; virtual;
+    destructor Destroy; override;
+    procedure LoadFromStream(aStream : TStream);
+    //for test only
+    procedure Check;
+    
+    property Textures: TStringList read fTextures;
+    property Materials: TStringList read fMaterials;
+    property Nodes: TB3DNode read fNodes;
+  end;
+
+//-----------------------------------------------------------------------
+implementation
+//-----------------------------------------------------------------------
+
+constructor TB3DMaterial.Create;
+begin
+  inherited Create;
+  fillChar(MaterialData, sizeof(TBRUSChunk), 0);
+end;
+
+destructor TB3DMaterial.Destroy;
+begin
+  SetLength(MaterialData.texture_id, 0);
+  inherited Destroy;
+end;
+
+function TB3DMaterial.GetMaterialName: string;
+begin
+  SetString(Result, MaterialData.name, strlen(MaterialData.name));
+end;
+
+constructor TB3DTexture.Create;
+begin
+  inherited Create;
+  fillChar(TextureData, sizeof(TTEXSChunk), 0);
+end;
+
+destructor TB3DTexture.Destroy;
+begin
+  inherited Destroy;
+end;
+
+function TB3DTexture.GetTextureName: string;
+begin
+  SetString(Result, TextureData.fileName, strlen(TextureData.fileName));
+end;
+
+constructor TB3DNode.Create;
+begin
+  inherited Create;
+  NodeData := nil;
+end;
+
+destructor TB3DNode.Destroy;
+begin
+  DestroyNodeData(NodeData);
+  inherited Destroy;
+end;
+
+function TB3DNode.GetNodeName: string;
+begin
+  SetString(Result, NodeData^.name, strlen(NodeData^.name));
+end;
+
+procedure DeleteVertices(var aVertex: PVertexData);
+var
+  V: PVertexData;
+begin
+  while aVertex<>nil do
+  begin
+    SetLength(aVertex^.tex_coords, 0);
+    V := aVertex^.next;
+    freeMem(aVertex);
+    aVertex := nil;
+    DeleteVertices(V);
+  end;
+end;
+
+procedure DeleteTriangles(var aTriangle: PTRISChunk);
+var
+  T: PTRISChunk;
+begin
+  while aTriangle<>nil do
+  begin
+    SetLength(aTriangle^.vertex_id, 0);
+    T := aTriangle^.next;
+    freeMem(aTriangle);
+    aTriangle := nil;
+    DeleteTriangles(T);
+  end;
+end;
+
+procedure TB3DNode.DestroyNodeData(Node: PNODEChunk);
+var
+  oldNode, PNode: PNODEChunk;
+begin
+  PNode := Node;
+  while PNode<>nil do
+  begin
+    if PNode^.meshes<>nil then
+    begin
+      DeleteTriangles(PNode^.meshes^.triangles);
+      DeleteVertices(PNode^.meshes^.vertices.vertices);
+      freeMem(PNode^.meshes);
+      PNode^.meshes := nil;
+    end;
+    if PNode^.keys<>nil then
+      freeMem(PNode^.keys);
+    DestroyNodeData(PNode^.nodes);
+    oldNode := PNode;
+    PNode := PNode^.next;
+    freeMem(oldNode);
+  end;
+end;
+
+//------------------------------------------------------------------------------
+constructor TFileB3D.Create;
+begin
+  inherited Create;
+  fTextures := TStringList.Create;
+  fMaterials := TStringList.Create;
+  fNodes := TB3DNode.Create;
+end;
+
+destructor TFileB3D.Destroy;
+begin
+  FreeLists;
+  fTextures.free;
+  fMaterials.free;
+  fNodes.free;
+  inherited Destroy;
+end;
+
+function TFileB3D.GetChunkType(const aChunk: TB3DChunk): TB3DChunkType;
+begin
+  Result := bctUnKnown;
+  if StrLIComp(aChunk.chunk, 'BB3D', 4)=0 then
+    Result := bctHeader;
+  if StrLIComp(aChunk.chunk, 'TEXS', 4)=0 then
+    Result := bctTexture;
+  if StrLIComp(aChunk.chunk, 'BRUS', 4)=0 then
+    Result := bctBrush;
+  if StrLIComp(aChunk.chunk, 'NODE', 4)=0 then
+    Result := bctNode;
+  if StrLIComp(aChunk.chunk, 'VRTS', 4)=0 then
+    Result := bctVertex;
+  if StrLIComp(aChunk.chunk, 'BONE', 4)=0 then
+    Result := bctBone;
+  if StrLIComp(aChunk.chunk, 'KEYS', 4)=0 then
+    Result := bctKeyFrame;
+  if StrLIComp(aChunk.chunk, 'ANIM', 4)=0 then
+    Result := bctAnimation;
+  if StrLIComp(aChunk.chunk, 'MESH', 4)=0 then
+    Result := bctMesh;
+  if StrLIComp(aChunk.chunk, 'TRIS', 4)=0 then
+    Result := bctTriangle;
+end;
+
+function TFileB3D.SkipChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
+begin
+  aStream.Seek(aChunk.length, soFromCurrent);
+  Result := aChunk.length;
+end;
+
+function ReadString(aStream: TStream; buffer: PChar; MaxCount: Integer): Integer;
+begin
+  Result := 0;
+  while Result<MaxCount do
+  begin
+    aStream.Read(buffer[Result], sizeof(char));
+    Inc(result);
+    if buffer[result-1]=#0 then
+      break;
+  end;
+end;
+
+function TFileB3D.ReadTextureChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
+var
+  Texture: TB3DTexture;
+  Count: Integer;
+begin
+  Result := 0;
+  if aChunk.length<5 then
+    exit;
+  Count := 0;
+  while Count<aChunk.length do
+  begin
+    Texture := TB3DTexture.Create;
+    Inc(Count, ReadString(aStream, Texture.TextureData.fileName, 255));
+    Inc(Count, aStream.Read(Texture.TextureData.flags, sizeof(integer)));
+    Inc(Count, aStream.Read(Texture.TextureData.blend, sizeof(integer)));
+    Inc(Count, aStream.Read(Texture.TextureData.x_pos, sizeof(single)));
+    Inc(Count, aStream.Read(Texture.TextureData.y_pos, sizeof(single)));
+    Inc(Count, aStream.Read(Texture.TextureData.x_scale, sizeof(single)));
+    Inc(Count, aStream.Read(Texture.TextureData.y_scale, sizeof(single)));
+    Inc(Count, aStream.Read(Texture.TextureData.rotation, sizeof(single)));
+    fTextures.AddObject(Texture.GetTextureName, Texture);
+  end;
+  Result := fTextures.Count;
+end;
+
+function TFileB3D.ReadMaterialChunk(aStream: TStream; const aChunk: TB3DChunk): Integer;
+var
+  Material: TB3DMaterial;
+  Count, I: Integer;
+  TextureCount: Integer;
+begin
+  Result := 0;
+  if aChunk.length<5 then
+    exit;
+  Count := 0;
+  TextureCount := 0;
+  while Count<aChunk.length do
+  begin
+    Material := TB3DMaterial.Create;
+    if Count=0 then
+    begin
+      Inc(Count, aStream.Read(Material.MaterialData.n_texs, sizeof(integer)));
+      TextureCount := Material.MaterialData.n_texs;
+    end else
+      Material.MaterialData.n_texs := TextureCount;
+    Inc(Count, ReadString(aStream, Material.MaterialData.name, 255));
+    Inc(Count, aStream.Read(Material.MaterialData.red, sizeof(single)));
+    Inc(Count, aStream.Read(Material.MaterialData.green, sizeof(single)));
+    Inc(Count, aStream.Read(Material.MaterialData.blue, sizeof(single)));
+    Inc(Count, aStream.Read(Material.MaterialData.alpha, sizeof(single)));
+    Inc(Count, aStream.Read(Material.MaterialData.shininess, sizeof(single)));
+    Inc(Count, aStream.Read(Material.MaterialData.blend, sizeof(integer)));
+    Inc(Count, aStream.Read(Material.MaterialData.fx, sizeof(integer)));
+    SetLength(Material.MaterialData.texture_id, TextureCount);
+    for I:=0 to TextureCount-1 do
+      Inc(Count, aStream.Read(Material.MaterialData.texture_id[I], sizeof(Integer)));
+    fMaterials.AddObject(Material.GetMaterialName, Material);
+  end;
+  Result := fMaterials.Count;
+end;
+
+function TFileB3D.ReadMeshChunk(aStream: TStream; const aChunk: TB3DChunk; Mesh: PMESHChunk): Integer;
+var
+  C: TB3DChunk;
+  T: PTRISChunk;
+begin
+  Result := 0;
+  fillChar(Mesh^, sizeof(TMESHChunk), 0);
+  Mesh^.brush_id := -1;
+  Inc(Result, aStream.Read(Mesh^.brush_id, sizeof(Integer)));
+  T := nil;
+  while Result<aChunk.length do
+  begin
+    Inc(Result, aStream.Read(C, sizeof(TB3DChunk)));
+    case GetChunkType(C) of
+      bctVertex:
+      begin
+        Inc(Result, ReadVerticesChunk(aStream, C, @(Mesh^.vertices)));
+      end;
+      bctTriangle:
+      begin
+        if Mesh^.triangles=nil then
+        begin
+          GetMem(Mesh^.triangles, sizeof(TTRISChunk));
+          fillChar(Mesh^.triangles^, sizeof(TTRISChunk), 0);
+          Inc(Result, ReadTrianglesChunk(aStream, C, Mesh^.triangles));
+        end else
+        begin
+          if T=nil then
+          begin
+            GetMem(T, sizeof(TTRISChunk));
+            fillChar(T^, sizeof(TTRISChunk), 0);
+            Inc(Result, ReadTrianglesChunk(aStream, C, T));
+            Mesh^.triangles^.next := T;
+          end else
+          begin
+            GetMem(T^.next, sizeof(TTRISChunk));
+            fillChar(T^.next^, sizeof(TTRISChunk), 0);
+            Inc(Result, ReadTrianglesChunk(aStream, C, T^.next));
+            T := T^.next;
+          end;
+        end;
+      end;
+      else
+        inc(Result, SkipChunk(aStream, C));
+    end;
+  end;
+end;
+
+function TFileB3D.ReadVerticesChunk(aStream: TStream; const aChunk: TB3DChunk; Vertices: PVRTSChunk): Integer;
+var
+  v: PVertexData;
+  v1: PVertexData;
+  size: Integer;
+begin
+  Result := 0;
+  fillChar(Vertices^, sizeof(TVRTSChunk), 0);
+  Inc(Result, aStream.Read(Vertices^.flags, sizeof(Integer)));
+  Inc(Result, aStream.Read(Vertices^.tex_coord_sets, sizeof(Integer)));
+  Inc(Result, aStream.Read(Vertices^.tex_coord_set_size, sizeof(Integer)));
+  size := Vertices^.tex_coord_set_size*Vertices^.tex_coord_sets;
+  v := nil;
+  while Result<aChunk.length do
+  begin
+    if Vertices^.vertices=nil then
+    begin
+      GetMem(Vertices^.vertices, sizeof(TVertexData));
+      fillChar(vertices^.vertices^, sizeof(TVertexData), 0);
+    end else
+    begin
+      if v=nil then
+      begin
+        GetMem(v, sizeof(TVertexData));
+        fillChar(v^, sizeof(TVertexData), 0);
+        vertices^.vertices^.next := v;
+      end else
+      begin
+        GetMem(v^.next, sizeof(TVertexData));
+        fillChar(v^.next^, sizeof(TVertexData), 0);
+        v := v^.next;
+      end;
+    end;
+    if v=nil then
+      v1 := vertices^.vertices
+    else
+      v1 := v;
+    Inc(Result, aStream.Read(v1^.x, sizeof(single)));
+    Inc(Result, aStream.Read(v1^.y, sizeof(single)));
+    Inc(Result, aStream.Read(v1^.z, sizeof(single)));
+    //W3D Begin
+    if (Vertices^.flags and 1)>0 then begin
+      Inc(Result, aStream.Read(v1^.nx, sizeof(single)));
+      Inc(Result, aStream.Read(v1^.ny, sizeof(single)));
+      Inc(Result, aStream.Read(v1^.nz, sizeof(single)));
+    end;
+    if (Vertices^.flags and 2)>0 then begin
+      Inc(Result, aStream.Read(v1^.red, sizeof(single)));
+      Inc(Result, aStream.Read(v1^.green, sizeof(single)));
+      Inc(Result, aStream.Read(v1^.blue, sizeof(single)));
+      Inc(Result, aStream.Read(v1^.alpha, sizeof(single)));
+    end;
+    //W3D END
+    SetLength(v1^.tex_coords, size);
+    Inc(Result, aStream.Read(v1^.tex_coords[0], size*sizeof(single)));
+  end;
+end;
+
+function TFileB3D.ReadTrianglesChunk(aStream: TStream; const aChunk: TB3DChunk; Triangle: PTRISChunk): Integer;
+begin
+  Result := 0;
+  if Triangle=nil then
+  begin
+    GetMem(Triangle, sizeof(TTRISChunk));
+    fillChar(Triangle^, sizeof(TTRISChunk), 0);
+    Triangle^.brush_id := -1;
+  end;
+  Inc(Result, aStream.Read(Triangle^.brush_id, sizeof(Integer)));
+  SetLength(Triangle^.vertex_id, (aChunk.length-Result) div sizeof(Integer));
+  Inc(Result, aStream.Read(Triangle^.vertex_id[0], (aChunk.length-Result)));
+end;
+
+//read in only the mesh data, the keyframes and animation had been dropped
+function TFileB3D.ReadNodeChunk(aStream: TStream; const aChunk: TB3DChunk; Node: PNODEChunk; level: Integer): Integer;
+var
+  Count: Integer;
+  C: TB3DChunk;
+  N: PNODEChunk;
+begin
+  N := nil;
+  fillChar(Node^, sizeof(TNODEChunk), 0);
+  Node^.level := level;
+  Count := 0;
+  Inc(Count, ReadString(aStream, Node^.name, 255));
+  Inc(Count, aStream.Read(Node^.position.X, sizeof(TAffineVector)));
+  Inc(Count, aStream.Read(Node^.scale.X, sizeof(TAffineVector)));
+  Inc(Count, aStream.Read(Node^.rotation.X, sizeof(TVector)));
+  while Count<aChunk.length do
+  begin
+    Inc(Count, aStream.Read(C, sizeof(TB3DChunk)));
+    case GetChunkType(C) of
+      bctMesh:
+      begin
+        GetMem(Node^.meshes, sizeof(TMESHChunk));
+        Inc(Count, ReadMeshChunk(aStream, C, Node^.meshes));
+      end;
+      bctKeyframe:
+      begin
+        Inc(Count, SkipChunk(aStream, C));
+      end;
+      bctNode:
+      begin
+        if N=nil then
+        begin
+          GetMem(N, sizeof(TNODEChunk));
+          fillChar(N^, sizeof(TNODEChunk), 0);
+          Inc(Count, ReadNodeChunk(aStream, C, N, level + 1));
+          Node^.next := N;
+        end else
+        begin
+          GetMem(N^.next, sizeof(TNODEChunk));
+          fillChar(N^.next^, sizeof(TNODEChunk), 0);
+          Inc(Count, ReadNodeChunk(aStream, C, N^.next, level + 1));
+          N := N^.next;
+        end;
+      end;
+      bctAnimation:
+      begin
+        Inc(Count, SkipChunk(aStream, C));
+      end;
+      else
+        Inc(Count, SkipChunk(aStream, C));
+    end;
+  end;
+  Result := Count;
+end;
+
+procedure TFileB3D.LoadFromStream(aStream : TStream);
+var
+  aChunk: TB3DChunk;
+  FileSize: Integer;
+begin
+  FileSize := aStream.Size;
+  while aStream.Position<FileSize do
+  begin
+    aStream.Read(aChunk, sizeof(TB3DChunk));
+    case GetChunkType(aChunk) of
+      bctHeader:
+      begin
+        FileSize := aChunk.length - sizeof(TB3DChunk) - sizeof(TBB3DChunk);
+        aStream.Seek(sizeof(TBB3DChunk), soFromCurrent);
+      end;
+      bctTexture:
+      begin
+        ReadTextureChunk(aStream, aChunk);
+      end;
+      bctBrush:
+      begin
+        ReadMaterialChunk(aStream, aChunk);
+      end;
+      bctNode:
+      begin
+        if fNodes.NodeData=nil then
+        begin
+          GetMem(fNodes.NodeData, sizeof(TNODEChunk));
+          ReadNodeChunk(aStream, aChunk, fNodes.NodeData, 0);
+        end;
+      end;
+      else
+        SkipChunk(aStream, aChunk);
+    end;
+  end;
+end;
+
+procedure TFileB3D.FreeLists;
+begin
+  while fTextures.Count>0 do
+  begin
+    fTextures.Objects[0].free;
+    ftextures.Delete(0);
+  end;
+  while fMaterials.Count>0 do
+  begin
+    fMaterials.Objects[0].free;
+    fMaterials.Delete(0);
+  end;
+end;
+
+//for test only
+procedure TFileB3D.Check;
+var
+  NodeLevel: Integer;
+//  NodeCount: Integer;
+  Node: PNODEChunk;
+//  VerticesCount: Integer;
+//  FaceCount: Integer;
+  Face: PTRISChunk;
+  Vertex: PVertexData;
+begin
+  NodeLevel := 0;
+//  NodeCount := 0;
+//  VerticesCount := 0;
+//  FaceCount := 0;
+  Node := fNodes.NodeData;
+  while Node<>nil do
+  begin
+    if Node^.meshes<>nil then
+//      Inc(NodeCount);
+    if Node^.level>NodeLevel then
+      NodeLevel := Node^.level;
+    if Node^.meshes<>nil then
+    begin
+      Vertex := Node^.meshes.vertices.vertices;
+      while Vertex<>nil do
+      begin
+//        Inc(VerticesCount);
+        Vertex := Vertex.next;
+      end;
+      Face := Node^.meshes.triangles;
+      while Face<>nil do
+      begin
+//        Inc(FaceCount);
+        Face := Face.next;
+      end;
+    end;
+    Node := Node^.next;
+  end;
+
+  //MessageBeep(FaceCount);
+  //MessageBeep(VerticesCount);
+  //MessageBeep(NodeLevel);
+  //MessageBeep(NodeCount);
+end;
+
+end.

+ 195 - 196
Source/FileOCT.pas → Source/Formats.FileOCT.pas

@@ -1,196 +1,195 @@
-//
-// This unit is part of the GLScene Engine, http://glscene.org
-//
-
-unit FileOCT;
-
-(* Loader for FSRad OCT files *)
-
-interface
-
-{$I GLScene.inc}
-
-uses
-  System.Classes,
-  System.SysUtils,
-
-  Scene.VectorGeometry,
-  Scene.VectorTypes,
-  Scene.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: TAffineVectorList;
-      texMapCoords: TAffineVectorList; const textureName: String);
-    procedure AddLight(const lightPos: TAffineVector; const lightColor: TVector;
-      lightIntensity: Integer);
-  end;
-
-  // ------------------------------------------------------------------
-implementation
-
-// ------------------------------------------------------------------
-
-uses
-  GLMeshUtils;
-
-// ------------------
-// ------------------ 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: TAffineVectorList;
-  texMapCoords: TAffineVectorList; 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: TVector; 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.
+//
+// This unit is part of the GLScene Engine, http://glscene.org
+//
+
+unit Formats.FileOCT;
+
+(* Loader for FSRad OCT files *)
+
+interface
+
+{$I GLScene.inc}
+
+uses
+  System.Classes,
+  System.SysUtils,
+
+  Scene.VectorGeometry,
+  Scene.VectorTypes,
+  Scene.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: TAffineVectorList;
+      texMapCoords: TAffineVectorList; const textureName: String);
+    procedure AddLight(const lightPos: TAffineVector; const lightColor: TVector;
+      lightIntensity: Integer);
+  end;
+
+// ------------------------------------------------------------------
+implementation
+// ------------------------------------------------------------------
+
+uses
+  GLMeshUtils;
+
+// ------------------
+// ------------------ 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: TAffineVectorList;
+  texMapCoords: TAffineVectorList; 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: TVector; 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.

+ 1 - 5
Source/GLFBO.pas

@@ -4,11 +4,7 @@
 
 
 unit GLFBO;
 unit GLFBO;
 
 
-(*
-   Implements FBO support for GLScene.
-   Original author of the unit is Riz.
-   Modified by DaStr, C4 and YarUnderoaker.
-*)
+(* Implements Frame Buffer OpenGL support *)
 
 
 interface
 interface
 
 

+ 4 - 15
Source/GLFileB3D.pas

@@ -20,7 +20,7 @@ uses
   Scene.VectorTypes, 
   Scene.VectorTypes, 
   Scene.VectorGeometry, 
   Scene.VectorGeometry, 
   Scene.VectorLists,
   Scene.VectorLists,
-  FileB3D;
+  Formats.FileB3D;
 
 
 type
 type
   TGLB3DVectorFile = class(TGLVectorFile)
   TGLB3DVectorFile = class(TGLVectorFile)
@@ -86,7 +86,6 @@ var
             TexName := ATex.GetTextureName
             TexName := ATex.GetTextureName
           else
           else
             TexName := '';
             TexName := '';
-
           if not FileExists(TexName) then
           if not FileExists(TexName) then
             TexName := ExtractFileName(TexName);
             TexName := ExtractFileName(TexName);
           if TexName <> '' then
           if TexName <> '' then
@@ -97,7 +96,6 @@ var
             LibMat := MatLib.Materials.Add;
             LibMat := MatLib.Materials.Add;
             LibMat.Name := Result + IntToStr(MaterialNum);
             LibMat.Name := Result + IntToStr(MaterialNum);
           end;
           end;
-
           Libmat.Material.FrontProperties.Diffuse.Red := AMat.MaterialData.Red;
           Libmat.Material.FrontProperties.Diffuse.Red := AMat.MaterialData.Red;
           Libmat.Material.FrontProperties.Diffuse.Green :=
           Libmat.Material.FrontProperties.Diffuse.Green :=
             AMat.MaterialData.Green;
             AMat.MaterialData.Green;
@@ -108,37 +106,30 @@ var
           Libmat.Material.FrontProperties.Shininess :=
           Libmat.Material.FrontProperties.Shininess :=
             Round(AMat.MaterialData.Shininess * 100.0);
             Round(AMat.MaterialData.Shininess * 100.0);
           Libmat.Material.MaterialOptions := [MoNoLighting];
           Libmat.Material.MaterialOptions := [MoNoLighting];
-
           if AMat.MaterialData.Alpha <> 1 then
           if AMat.MaterialData.Alpha <> 1 then
           begin
           begin
             Libmat.Material.FaceCulling := FcNoCull;
             Libmat.Material.FaceCulling := FcNoCull;
             Libmat.Material.BlendingMode := BmTransparency;
             Libmat.Material.BlendingMode := BmTransparency;
           end;
           end;
-
           if Assigned(ATex) then
           if Assigned(ATex) then
           begin
           begin
-
             LibMat.TextureOffset.AsAffineVector :=
             LibMat.TextureOffset.AsAffineVector :=
               AffineVectorMake(ATex.TextureData.X_pos,
               AffineVectorMake(ATex.TextureData.X_pos,
               ATex.TextureData.Y_pos, 0);
               ATex.TextureData.Y_pos, 0);
-
             LibMat.TextureScale.AsAffineVector :=
             LibMat.TextureScale.AsAffineVector :=
               AffineVectorMake(ATex.TextureData.X_scale,
               AffineVectorMake(ATex.TextureData.X_scale,
               ATex.TextureData.Y_scale, 1);
               ATex.TextureData.Y_scale, 1);
-
             if ATex.TextureData.Flags = 2 then
             if ATex.TextureData.Flags = 2 then
             begin
             begin
               Libmat.Material.FaceCulling := FcNoCull;
               Libmat.Material.FaceCulling := FcNoCull;
               Libmat.Material.BlendingMode := BmTransparency;
               Libmat.Material.BlendingMode := BmTransparency;
             end;
             end;
-
             if AMat.MaterialData.Alpha <> 1 then
             if AMat.MaterialData.Alpha <> 1 then
             begin
             begin
               Libmat.Material.Texture.ImageAlpha := TiaAlphaFromIntensity;
               Libmat.Material.Texture.ImageAlpha := TiaAlphaFromIntensity;
               Libmat.Material.Texture.TextureFormat := TfRGBA;
               Libmat.Material.Texture.TextureFormat := TfRGBA;
               Libmat.Material.Texture.TextureMode := TmModulate;
               Libmat.Material.Texture.TextureMode := TmModulate;
             end;
             end;
-
           end;
           end;
         end;
         end;
         // add lightmap material
         // add lightmap material
@@ -302,15 +293,14 @@ begin
           FaceGroup.Reverse;
           FaceGroup.Reverse;
 
 
         end;
         end;
-
         RotQuat := QuaternionMake([Node^.Rotation.Z, Node^.Rotation.Y,
         RotQuat := QuaternionMake([Node^.Rotation.Z, Node^.Rotation.Y,
           Node^.Rotation.W], Node^.Rotation.X);
           Node^.Rotation.W], Node^.Rotation.X);
         RotMat := QuaternionToMatrix(RotQuat);
         RotMat := QuaternionToMatrix(RotQuat);
         Mo.Vertices.TransformAsVectors(RotMat);
         Mo.Vertices.TransformAsVectors(RotMat);
-
-        { mo.SetPosition( Node^.Position[1], Node^.Position[0], Node^.Position[2]);
+        (*
+          mo.SetPosition( Node^.Position[1], Node^.Position[0], Node^.Position[2]);
           mo.SetScale( Node^.Scale[1], Node^.Scale[0], Node^.Scale[2]);
           mo.SetScale( Node^.Scale[1], Node^.Scale[0], Node^.Scale[2]);
-        }
+        *)
         if Pos('ENT_', UpperCase(Mo.Name)) = 0 then
         if Pos('ENT_', UpperCase(Mo.Name)) = 0 then
           V := AffineVectorMake(Node^.Position.Y,
           V := AffineVectorMake(Node^.Position.Y,
             Node^.Position.X, Node^.Position.Z)
             Node^.Position.X, Node^.Position.Z)
@@ -318,7 +308,6 @@ begin
         begin
         begin
           V := AffineVectorMake(0.0, 0.0, 0.0);
           V := AffineVectorMake(0.0, 0.0, 0.0);
         end;
         end;
-
         V1 := AffineVectorMake(Node^.Scale.Y, Node^.Scale.X, Node^.Scale.Z);
         V1 := AffineVectorMake(Node^.Scale.Y, Node^.Scale.X, Node^.Scale.Z);
         Matrix := CreateScaleAndTranslationMatrix(VectorMake(V1), VectorMake(V));
         Matrix := CreateScaleAndTranslationMatrix(VectorMake(V1), VectorMake(V));
         Mo.Vertices.TransformAsPoints(Matrix);
         Mo.Vertices.TransformAsPoints(Matrix);

+ 1 - 1
Source/GLFileOCT.pas

@@ -28,7 +28,7 @@ uses
   GLVectorFileObjects,
   GLVectorFileObjects,
   Scene.VectorGeometry,
   Scene.VectorGeometry,
   GLApplicationFileIO,
   GLApplicationFileIO,
-  FileOCT;
+  Formats.FileOCT;
 
 
 type
 type
 
 

+ 1 - 1
Source/GLS.SceneRegister.pas

@@ -359,7 +359,7 @@ uses
   GLS.Utils,
   GLS.Utils,
   GLSL.AsmShader,
   GLSL.AsmShader,
   GLSL.BumpShaders,
   GLSL.BumpShaders,
-  GLSL.CelShader,
+  GLSL.ShapeShaders,
   GLSL.LineShaders,
   GLSL.LineShaders,
   GLSL.ShaderCombiner,
   GLSL.ShaderCombiner,
   GLSL.PhongShader,
   GLSL.PhongShader,

+ 0 - 880
Source/GLSL.TextureSharingShader.pas

@@ -1,880 +0,0 @@
-//
-// This unit is part of the GLScene Engine, http://glscene.org
-//
-
-unit GLSL.TextureSharingShader;
-
-(*
-    This shader allows to apply multiple textures, gathering them from existing materials.
-    This allows saving resources, since you can reference the textures of any material in
-    any materialLibrary.
-    Note that actually the component references a Material (not a texture) but
-    it uses that material's texture. The referenced material settings will be ignored,
-    but the texture's settings (like TextureMode, ImageGamma, ImageBrightness) will be used.
-    Instead the local material settings (listed in the collection) will be used.
-*)
-
-interface
-
-uses
-  System.Classes, 
-  System.SysUtils,
-  
-  GLScene, 
-  GLContext,
-  GLTexture,
-  Scene.VectorTypes,
-  Scene.VectorGeometry,
-  GlColor,
-  GLMaterial, 
-  Scene.Strings,
-  GLVectorFileObjects, 
-  XOpenGL, 
-  GLState, 
-  Scene.PersistentClasses,
-  GLCoordinates,
-  GLRenderContextInfo;
-
-type
-  TGLTextureSharingShader = class;
-
-  TGLTextureSharingShaderMaterial = class(TGLInterfacedCollectionItem, IGLMaterialLibrarySupported)
-  private
-    FTextureMatrix: TMatrix;
-    FNeedToUpdateTextureMatrix: Boolean;
-    FTextureMatrixIsUnitary: Boolean;
-    FLibMaterial: TGLLibMaterial;
-    FTexOffset: TGLCoordinates2;
-    FTexScale: TGLCoordinates2;
-    FBlendingMode: TGLBlendingMode;
-    FSpecular: TGLColor;
-    FAmbient: TGLColor;
-    FDiffuse: TGLColor;
-    FEmission: TGLColor;
-    FShininess: TGLShininess;
-    FMaterialLibrary: TGLMaterialLibrary;
-    FLibMaterialName: TGLLibMaterialName;
-    procedure SetAmbient(const Value: TGLColor);
-    procedure SetDiffuse(const Value: TGLColor);
-    procedure SetEmission(const Value: TGLColor);
-    procedure SetShininess(const Value: TGLShininess);
-    procedure SetSpecular(const Value: TGLColor);
-    procedure SetMaterialLibrary(const Value: TGLMaterialLibrary);
-    procedure SetLibMaterialName(const Value: TGLLibMaterialName);
-    procedure SetBlendingMode(const Value: TGLBlendingMode);
-    procedure SetLibMaterial(const Value: TGLLibMaterial);
-    procedure SetTexOffset(const Value: TGLCoordinates2);
-    procedure SetTexScale(const Value: TGLCoordinates2);
-    function GetTextureMatrix: TMatrix;
-    function GetTextureMatrixIsUnitary: Boolean;
-  protected
-    procedure coordNotifychange(Sender: TObject);
-    procedure OtherNotifychange(Sender: TObject);
-    function GetDisplayName: string; override;
-    function GetTextureSharingShader: TGLTextureSharingShader;
-    // Implementing IGLMaterialLibrarySupported.
-    function GetMaterialLibrary: TGLAbstractMaterialLibrary; virtual;
-  public
-    procedure Apply(var rci: TGLRenderContextInfo);
-    procedure UnApply(var rci: TGLRenderContextInfo);
-    constructor Create(Collection: TCollection); override;
-    destructor Destroy; override;
-    property LibMaterial: TGLLibMaterial read FLibMaterial write SetLibMaterial;
-    property TextureMatrix: TMatrix read GetTextureMatrix;
-    property TextureMatrixIsUnitary: Boolean read GetTextureMatrixIsUnitary;
-  published
-    property TexOffset: TGLCoordinates2 read FTexOffset write SetTexOffset;
-    property TexScale: TGLCoordinates2 read FTexScale write SetTexScale;
-    property BlendingMode: TGLBlendingMode read FBlendingMode write SetBlendingMode;
-    property Emission: TGLColor read FEmission write SetEmission;
-    property Ambient: TGLColor read FAmbient write SetAmbient;
-    property Diffuse: TGLColor read FDiffuse write SetDiffuse;
-    property Specular: TGLColor read FSpecular write SetSpecular;
-    property Shininess: TGLShininess read FShininess write SetShininess;
-    property MaterialLibrary: TGLMaterialLibrary read FMaterialLibrary write SetMaterialLibrary;
-    property LibMaterialName: TGLLibMaterialName read FLibMaterialName write SetLibMaterialName;
-  end;
-
-  TGLTextureSharingShaderMaterials = class(TOwnedCollection)
-  protected
-    function GetItems(const AIndex: Integer): TGLTextureSharingShaderMaterial;
-    procedure SetItems(const AIndex: Integer; const Value: TGLTextureSharingShaderMaterial);
-    function GetParent: TGLTextureSharingShader;
-  public
-    function Add: TGLTextureSharingShaderMaterial;
-    constructor Create(AOwner: TGLTextureSharingShader);
-    property Items[const AIndex: Integer]: TGLTextureSharingShaderMaterial read GetItems write SetItems; default;
-  end;
-
-  TGLTextureSharingShader = class(TGLShader)
-  private
-    FMaterials: TGLTextureSharingShaderMaterials;
-    FCurrentPass: Integer;
-    procedure SetMaterials(const Value: TGLTextureSharingShaderMaterials);
-  protected
-    procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
-    function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
-    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
-  public
-    constructor Create(AOwner: TComponent); override;
-    destructor Destroy; override;
-    function AddLibMaterial(const ALibMaterial: TGLLibMaterial): TGLTextureSharingShaderMaterial;
-    function FindLibMaterial(const ALibMaterial: TGLLibMaterial): TGLTextureSharingShaderMaterial;
-  published
-    property Materials: TGLTextureSharingShaderMaterials read FMaterials write SetMaterials;
-  end;
-
-(* A shader that allows texture combiner setup. *)
-
-  // A shader that can setup the texture combiner.
-  TGLTextureCombineShader = class(TGLShader)
-  private
-    FCombiners: TStringList;
-    FCommandCache: TCombinerCache;
-    FCombinerIsValid: Boolean; // to avoid reparsing invalid stuff
-    FDesignTimeEnabled: Boolean;
-    FMaterialLibrary: TGLMaterialLibrary;
-    FLibMaterial3Name: TGLLibMaterialName;
-    currentLibMaterial3: TGLLibMaterial;
-    FLibMaterial4Name: TGLLibMaterialName;
-    currentLibMaterial4: TGLLibMaterial;
-    FApplied3, FApplied4: Boolean;
-  protected
-    procedure SetCombiners(const val: TStringList);
-    procedure SetDesignTimeEnabled(const val: Boolean);
-    procedure SetMaterialLibrary(const val: TGLMaterialLibrary);
-    procedure SetLibMaterial3Name(const val: TGLLibMaterialName);
-    procedure SetLibMaterial4Name(const val: TGLLibMaterialName);
-    procedure NotifyLibMaterial3Destruction;
-    procedure NotifyLibMaterial4Destruction;
-    procedure DoInitialize(var rci: TGLRenderContextInfo; Sender: TObject); override;
-    procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
-    function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
-    procedure DoFinalize; override;
-  public
-    constructor Create(AOwner: TComponent); override;
-    destructor Destroy; override;
-    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
-    procedure NotifyChange(Sender: TObject); override;
-  published
-    property Combiners: TStringList read FCombiners write SetCombiners;
-    property DesignTimeEnabled: Boolean read FDesignTimeEnabled write SetDesignTimeEnabled;
-    property MaterialLibrary: TGLMaterialLibrary read FMaterialLibrary write SetMaterialLibrary;
-    property LibMaterial3Name: TGLLibMaterialName read FLibMaterial3Name write SetLibMaterial3Name;
-    property LibMaterial4Name: TGLLibMaterialName read FLibMaterial4Name write SetLibMaterial4Name;
-  end;
-
-//================================================
-implementation
-//================================================
-
-//-----------------------------------
-// TGLTextureSharingShaderMaterial
-//-----------------------------------
-
-procedure TGLTextureSharingShaderMaterial.Apply(var rci: TGLRenderContextInfo);
-begin
-  if not Assigned(FLibMaterial) then
-    Exit;
-  xgl.BeginUpdate;
-  if Assigned(FLibMaterial.Shader) then
-  begin
-    case FLibMaterial.Shader.ShaderStyle of
-      ssHighLevel: FLibMaterial.Shader.Apply(rci, FLibMaterial);
-      ssReplace:
-      begin
-        FLibMaterial.Shader.Apply(rci, FLibMaterial);
-        Exit;
-      end;
-    end;
-  end;
-  if not FLibMaterial.Material.Texture.Disabled then
-  begin
-    if not (GetTextureMatrixIsUnitary) then
-    begin
-      rci.GLStates.SetGLTextureMatrix(TextureMatrix);
-    end;
-  end;
-
-  if moNoLighting in FLibMaterial.Material.MaterialOptions then
-    rci.GLStates.Disable(stLighting);
-
-  if stLighting in rci.GLStates.States then
-  begin
-    rci.GLStates.SetGLMaterialColors(cmFront,
-      Emission.Color, Ambient.Color, Diffuse.Color, Specular.Color, Shininess);
-    rci.GLStates.PolygonMode :=FLibMaterial.Material.PolygonMode;
-  end
-  else
-    FLibMaterial.Material.FrontProperties.ApplyNoLighting(rci, cmFront);
-  if (stCullFace in rci.GLStates.States) then
-  begin
-    case FLibMaterial.Material.FaceCulling of
-      fcBufferDefault: if not rci.bufferFaceCull then
-        begin
-          rci.GLStates.Disable(stCullFace);
-          FLibMaterial.Material.BackProperties.Apply(rci, cmBack);
-        end;
-      fcCull: ; // nothing to do
-      fcNoCull:
-      begin
-        rci.GLStates.Disable(stCullFace);
-        FLibMaterial.Material.BackProperties.Apply(rci, cmBack);
-      end;
-      else
-        Assert(False);
-    end;
-  end
-  else
-  begin
-    // currently NOT culling
-    case FLibMaterial.Material.FaceCulling of
-      fcBufferDefault:
-      begin
-        if rci.bufferFaceCull then
-          rci.GLStates.Enable(stCullFace)
-        else
-          FLibMaterial.Material.BackProperties.Apply(rci, cmBack);
-      end;
-      fcCull: rci.GLStates.Enable(stCullFace);
-      fcNoCull: FLibMaterial.Material.BackProperties.Apply(rci, cmBack);
-      else
-        Assert(False);
-    end;
-  end;
-
-  // Apply Blending mode
-  if not rci.ignoreBlendingRequests then
-    case BlendingMode of
-      bmOpaque:
-      begin
-        rci.GLStates.Disable(stBlend);
-        rci.GLStates.Disable(stAlphaTest);
-      end;
-      bmTransparency:
-      begin
-        rci.GLStates.Enable(stBlend);
-        rci.GLStates.Enable(stAlphaTest);
-        rci.GLStates.SetBlendFunc(bfSrcAlpha, bfOneMinusSrcAlpha);
-      end;
-      bmAdditive:
-      begin
-        rci.GLStates.Enable(stBlend);
-        rci.GLStates.Enable(stAlphaTest);
-        rci.GLStates.SetBlendFunc(bfSrcAlpha, bfOne);
-      end;
-      bmAlphaTest50:
-      begin
-        rci.GLStates.Disable(stBlend);
-        rci.GLStates.Enable(stAlphaTest);
-        rci.GLStates.SetGLAlphaFunction(cfGEqual, 0.5);
-      end;
-      bmAlphaTest100:
-      begin
-        rci.GLStates.Disable(stBlend);
-        rci.GLStates.Enable(stAlphaTest);
-        rci.GLStates.SetGLAlphaFunction(cfGEqual, 1.0);
-      end;
-      bmModulate:
-      begin
-        rci.GLStates.Enable(stBlend);
-        rci.GLStates.Enable(stAlphaTest);
-        rci.GLStates.SetBlendFunc(bfDstColor, bfZero);
-      end;
-      else
-        Assert(False);
-    end;
-  // Fog switch
-  if moIgnoreFog in FLibMaterial.Material.MaterialOptions then
-  begin
-    if stFog in rci.GLStates.States then
-    begin
-      rci.GLStates.Disable(stFog);
-      Inc(rci.fogDisabledCounter);
-    end;
-  end;
-
-  if not Assigned(FLibMaterial.Material.TextureEx) then
-  begin
-    if Assigned(FLibMaterial.Material.Texture) then
-      FLibMaterial.Material.Texture.Apply(rci);
-  end
-  else
-  begin
-    if Assigned(FLibMaterial.Material.Texture) and not FLibMaterial.Material.TextureEx.IsTextureEnabled(0) then
-      FLibMaterial.Material.Texture.Apply(rci)
-    else
-    if FLibMaterial.Material.TextureEx.Count > 0 then
-      FLibMaterial.Material.TextureEx.Apply(rci);
-  end;
-
-  if Assigned(FLibMaterial.Shader) then
-  begin
-    case FLibMaterial.Shader.ShaderStyle of
-      ssLowLevel: FLibMaterial.Shader.Apply(rci, FLibMaterial);
-    end;
-  end;
-  xgl.EndUpdate;
-end;
-
-procedure TGLTextureSharingShaderMaterial.coordNotifychange(Sender: TObject);
-begin
-  FNeedToUpdateTextureMatrix := True;
-  GetTextureSharingShader.NotifyChange(Self);
-end;
-
-constructor TGLTextureSharingShaderMaterial.Create(Collection: TCollection);
-begin
-  inherited;
-  FSpecular := TGLColor.Create(Self);
-  FSpecular.OnNotifyChange := OtherNotifychange;
-  FAmbient := TGLColor.Create(Self);
-  FAmbient.OnNotifyChange := OtherNotifychange;
-  FDiffuse := TGLColor.Create(Self);
-  FDiffuse.OnNotifyChange := OtherNotifychange;
-  FEmission := TGLColor.Create(Self);
-  FEmission.OnNotifyChange := OtherNotifychange;
-
-  FTexOffset := TGLCoordinates2.CreateInitialized(Self, NullHmgVector, csPoint2d);
-  FTexOffset.OnNotifyChange := coordNotifychange;
-
-  FTexScale := TGLCoordinates2.CreateInitialized(Self, XYZHmgVector, csPoint2d);
-  FTexScale.OnNotifyChange := coordNotifychange;
-  FNeedToUpdateTextureMatrix := True;
-end;
-
-destructor TGLTextureSharingShaderMaterial.Destroy;
-begin
-  FSpecular.Free;
-  FAmbient.Free;
-  FDiffuse.Free;
-  FEmission.Free;
-  FTexOffset.Free;
-  FTexScale.Free;
-  inherited;
-end;
-
-
-function TGLTextureSharingShaderMaterial.GetDisplayName: string;
-var
-  st: string;
-begin
-  if Assigned(MaterialLibrary) then
-    st := MaterialLibrary.Name
-  else
-    st := '';
-  Result := '[' + st + '.' + Self.LibMaterialName + ']';
-end;
-
-function TGLTextureSharingShaderMaterial.GetMaterialLibrary: TGLAbstractMaterialLibrary;
-begin
-  Result := FMaterialLibrary;
-end;
-
-function TGLTextureSharingShaderMaterial.GetTextureMatrix: TMatrix;
-begin
-  if FNeedToUpdateTextureMatrix then
-  begin
-    if not (TexOffset.Equals(NullHmgVector) and TexScale.Equals(XYZHmgVector)) then
-    begin
-      FTextureMatrixIsUnitary := False;
-      FTextureMatrix := CreateScaleAndTranslationMatrix(TexScale.AsVector, TexOffset.AsVector)
-    end
-    else
-      FTextureMatrixIsUnitary := True;
-    FNeedToUpdateTextureMatrix := False;
-  end;
-  Result := FTextureMatrix;
-end;
-
-function TGLTextureSharingShaderMaterial.GetTextureMatrixIsUnitary: Boolean;
-begin
-  if FNeedToUpdateTextureMatrix then
-    GetTextureMatrix;
-  Result := FTextureMatrixIsUnitary;
-end;
-
-function TGLTextureSharingShaderMaterial.GetTextureSharingShader: TGLTextureSharingShader;
-begin
-  if Collection is TGLTextureSharingShaderMaterials then
-    Result := TGLTextureSharingShaderMaterials(Collection).GetParent
-  else
-    Result := nil;
-end;
-
-procedure TGLTextureSharingShaderMaterial.OtherNotifychange(Sender: TObject);
-begin
-  GetTextureSharingShader.NotifyChange(Self);
-end;
-
-procedure TGLTextureSharingShaderMaterial.SetAmbient(const Value: TGLColor);
-begin
-  FAmbient.Assign(Value);
-end;
-
-procedure TGLTextureSharingShaderMaterial.SetBlendingMode(const Value: TGLBlendingMode);
-begin
-  FBlendingMode := Value;
-end;
-
-procedure TGLTextureSharingShaderMaterial.SetDiffuse(const Value: TGLColor);
-begin
-  FDiffuse.Assign(Value);
-end;
-
-procedure TGLTextureSharingShaderMaterial.SetEmission(const Value: TGLColor);
-begin
-  FEmission.Assign(Value);
-end;
-
-procedure TGLTextureSharingShaderMaterial.SetLibMaterialName(const Value: TGLLibMaterialName);
-begin
-  FLibMaterialName := Value;
-  if (FLibMaterialName = '') or (FMaterialLibrary = nil) then
-    FLibMaterial := nil
-  else
-    SetLibMaterial(FMaterialLibrary.LibMaterialByName(FLibMaterialName));
-end;
-
-procedure TGLTextureSharingShaderMaterial.SetLibMaterial(const Value: TGLLibMaterial);
-begin
-  FLibMaterial := Value;
-  if FLibMaterial <> nil then
-  begin
-    FLibMaterialName := FLibMaterial.DisplayName;
-    FMaterialLibrary := TGLMaterialLibrary(TGLLibMaterials(Value.Collection).Owner);
-    if not (csloading in GetTextureSharingShader.ComponentState) then
-    begin
-      FTexOffset.Assign(FLibMaterial.TextureOffset);
-      FTexScale.Assign(FLibMaterial.TextureScale);
-      FBlendingMode := FLibMaterial.Material.BlendingMode;
-      fEmission.Assign(FLibMaterial.Material.FrontProperties.Emission);
-      fAmbient.Assign(FLibMaterial.Material.FrontProperties.Ambient);
-      fDiffuse.Assign(FLibMaterial.Material.FrontProperties.Diffuse);
-      fSpecular.Assign(FLibMaterial.Material.FrontProperties.Specular);
-      fShininess := FLibMaterial.Material.FrontProperties.Shininess;
-    end;
-  end;
-end;
-
-
-procedure TGLTextureSharingShaderMaterial.SetMaterialLibrary(const Value: TGLMaterialLibrary);
-begin
-  FMaterialLibrary := Value;
-  if (FLibMaterialName = '') or (FMaterialLibrary = nil) then
-    FLibMaterial := nil
-  else
-    SetLibMaterial(FMaterialLibrary.LibMaterialByName(FLibMaterialName));
-end;
-
-procedure TGLTextureSharingShaderMaterial.SetShininess(const Value: TGLShininess);
-begin
-  FShininess := Value;
-end;
-
-procedure TGLTextureSharingShaderMaterial.SetSpecular(const Value: TGLColor);
-begin
-  FSpecular.Assign(Value);
-end;
-
-procedure TGLTextureSharingShaderMaterial.SetTexOffset(const Value: TGLCoordinates2);
-begin
-  FTexOffset.Assign(Value);
-  FNeedToUpdateTextureMatrix := True;
-end;
-
-procedure TGLTextureSharingShaderMaterial.SetTexScale(const Value: TGLCoordinates2);
-begin
-  FTexScale.Assign(Value);
-  FNeedToUpdateTextureMatrix := True;
-end;
-
-procedure TGLTextureSharingShaderMaterial.UnApply(var rci: TGLRenderContextInfo);
-begin
-  if not Assigned(FLibMaterial) then
-    Exit;
-
-  if Assigned(FLibMaterial.Shader) then
-  begin
-    case FLibMaterial.Shader.ShaderStyle of
-      ssLowLevel: FLibMaterial.Shader.UnApply(rci);
-      ssReplace:
-      begin
-        FLibMaterial.Shader.UnApply(rci);
-        Exit;
-      end;
-    end;
-  end;
-
-  FLibMaterial.Material.UnApply(rci);
-
-  if not FLibMaterial.Material.Texture.Disabled then
-    if not (GetTextureMatrixIsUnitary) then
-    begin
-      rci.GLStates.ResetGLTextureMatrix;
-    end;
-
-  if Assigned(FLibMaterial.Shader) then
-  begin
-    case FLibMaterial.Shader.ShaderStyle of
-      ssHighLevel: FLibMaterial.Shader.UnApply(rci);
-    end;
-  end;
-end;
-
-//-----------------------------------
-// TGLTextureSharingShader
-//-----------------------------------
-
-function TGLTextureSharingShader.AddLibMaterial(const ALibMaterial: TGLLibMaterial): TGLTextureSharingShaderMaterial;
-begin
-  Result := FMaterials.Add;
-  Result.SetLibMaterial(ALibMaterial);
-end;
-
-constructor TGLTextureSharingShader.Create(AOwner: TComponent);
-begin
-  inherited;
-  FMaterials := TGLTextureSharingShaderMaterials.Create(Self);
-  ShaderStyle := ssReplace;
-end;
-
-destructor TGLTextureSharingShader.Destroy;
-begin
-  FMaterials.Free;
-  inherited;
-end;
-
-procedure TGLTextureSharingShader.DoApply(var rci: TGLRenderContextInfo; Sender: TObject);
-begin
-  if Materials.Count > 0 then
-  begin
-    rci.GLStates.Enable(stDepthTest);
-    rci.GLStates.DepthFunc := cfLEqual;
-    Materials[0].Apply(rci);
-    FCurrentPass := 1;
-  end;
-end;
-
-function TGLTextureSharingShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
-begin
-  Result := False;
-  if Materials.Count > 0 then
-  begin
-    Materials[FCurrentPass - 1].UnApply(rci);
-    if FCurrentPass < Materials.Count then
-    begin
-      Materials[FCurrentPass].Apply(rci);
-      Inc(FCurrentPass);
-      Result := True;
-    end
-    else
-    begin
-      rci.GLStates.DepthFunc := cfLess;
-      rci.GLStates.Disable(stBlend);
-      rci.GLStates.Disable(stAlphaTest);
-      FCurrentPass := 0;
-    end;
-  end;
-end;
-
-function TGLTextureSharingShader.FindLibMaterial(const ALibMaterial: TGLLibMaterial): TGLTextureSharingShaderMaterial;
-var
-  I: Integer;
-begin
-  Result := nil;
-  for I := 0 to FMaterials.Count - 1 do
-    if FMaterials[I].FLibMaterial = ALibMaterial then
-    begin
-      Result := FMaterials[I];
-      Break;
-    end;
-end;
-
-procedure TGLTextureSharingShader.Notification(AComponent: TComponent; Operation: TOperation);
-var
-  I: Integer;
-begin
-  inherited;
-  if Operation = opRemove then
-  begin
-    if AComponent is TGLMaterialLibrary then
-    begin
-      for I := 0 to Materials.Count - 1 do
-      begin
-        if Materials.Items[I].MaterialLibrary = AComponent then
-          Materials.Items[I].MaterialLibrary := nil;
-      end;
-    end;
-  end;
-end;
-
-procedure TGLTextureSharingShader.SetMaterials(const Value: TGLTextureSharingShaderMaterials);
-begin
-  FMaterials.Assign(Value);
-end;
-
-//-----------------------------------
-// TGLTextureSharingShaderMaterials
-//-----------------------------------
-
-function TGLTextureSharingShaderMaterials.Add: TGLTextureSharingShaderMaterial;
-begin
-  Result := (inherited Add) as TGLTextureSharingShaderMaterial;
-end;
-
-constructor TGLTextureSharingShaderMaterials.Create(AOwner: TGLTextureSharingShader);
-begin
-  inherited Create(AOwner, TGLTextureSharingShaderMaterial);
-end;
-
-function TGLTextureSharingShaderMaterials.GetItems(const AIndex: Integer): TGLTextureSharingShaderMaterial;
-begin
-  Result := (inherited Items[AIndex]) as TGLTextureSharingShaderMaterial;
-end;
-
-function TGLTextureSharingShaderMaterials.GetParent: TGLTextureSharingShader;
-begin
-  Result := TGLTextureSharingShader(GetOwner);
-end;
-
-procedure TGLTextureSharingShaderMaterials.SetItems(const AIndex: Integer; const Value: TGLTextureSharingShaderMaterial);
-begin
-  inherited Items[AIndex] := Value;
-end;
-
-// ------------------
-// ------------------ TGLTextureCombineShader ------------------
-// ------------------
-
-constructor TGLTextureCombineShader.Create(AOwner: TComponent);
-begin
-  inherited;
-  ShaderStyle := ssLowLevel;
-  FCombiners := TStringList.Create;
-  TStringList(FCombiners).OnChange := NotifyChange;
-  FCombinerIsValid := True;
-  FCommandCache := nil;
-end;
-
-destructor TGLTextureCombineShader.Destroy;
-begin
-  if Assigned(currentLibMaterial3) then
-    currentLibMaterial3.UnregisterUser(Self);
-  if Assigned(currentLibMaterial4) then
-    currentLibMaterial4.UnregisterUser(Self);
-  inherited;
-  FCombiners.Free;
-end;
-
-procedure TGLTextureCombineShader.Notification(AComponent: TComponent; Operation: TOperation);
-begin
-  if (FMaterialLibrary = AComponent) and (Operation = opRemove) then
-  begin
-    NotifyLibMaterial3Destruction;
-    NotifyLibMaterial4Destruction;
-    FMaterialLibrary := nil;
-  end;
-  inherited;
-end;
-
-procedure TGLTextureCombineShader.NotifyChange(Sender: TObject);
-begin
-  FCombinerIsValid := True;
-  FCommandCache := nil;
-  inherited NotifyChange(Sender);
-end;
-
-
-procedure TGLTextureCombineShader.NotifyLibMaterial3Destruction;
-begin
-  FLibMaterial3Name := '';
-  currentLibMaterial3 := nil;
-end;
-
-
-procedure TGLTextureCombineShader.NotifyLibMaterial4Destruction;
-begin
-  FLibMaterial4Name := '';
-  currentLibMaterial4 := nil;
-end;
-
-
-procedure TGLTextureCombineShader.SetMaterialLibrary(const val: TGLMaterialLibrary);
-begin
-  FMaterialLibrary := val;
-  SetLibMaterial3Name(LibMaterial3Name);
-  SetLibMaterial4Name(LibMaterial4Name);
-end;
-
-
-procedure TGLTextureCombineShader.SetLibMaterial3Name(const val: TGLLibMaterialName);
-var
-  newLibMaterial: TGLLibMaterial;
-begin
-  // locate new libmaterial
-  if Assigned(FMaterialLibrary) then
-    newLibMaterial := MaterialLibrary.Materials.GetLibMaterialByName(val)
-  else
-    newLibMaterial := nil;
-  FLibMaterial3Name := val;
-  // unregister if required
-  if newLibMaterial <> currentLibMaterial3 then
-  begin
-    // unregister from old
-    if Assigned(currentLibMaterial3) then
-      currentLibMaterial3.UnregisterUser(Self);
-    currentLibMaterial3 := newLibMaterial;
-    // register with new
-    if Assigned(currentLibMaterial3) then
-      currentLibMaterial3.RegisterUser(Self);
-    NotifyChange(Self);
-  end;
-end;
-
-
-procedure TGLTextureCombineShader.SetLibMaterial4Name(const val: TGLLibMaterialName);
-var
-  newLibMaterial: TGLLibMaterial;
-begin
-  // locate new libmaterial
-  if Assigned(FMaterialLibrary) then
-    newLibMaterial := MaterialLibrary.Materials.GetLibMaterialByName(val)
-  else
-    newLibMaterial := nil;
-  FLibMaterial4Name := val;
-  // unregister if required
-  if newLibMaterial <> currentLibMaterial4 then
-  begin
-    // unregister from old
-    if Assigned(currentLibMaterial4) then
-      currentLibMaterial4.UnregisterUser(Self);
-    currentLibMaterial4 := newLibMaterial;
-    // register with new
-    if Assigned(currentLibMaterial4) then
-      currentLibMaterial4.RegisterUser(Self);
-    NotifyChange(Self);
-  end;
-end;
-
-
-procedure TGLTextureCombineShader.DoInitialize(var rci: TGLRenderContextInfo; Sender: TObject);
-begin
-end;
-
-
-procedure TGLTextureCombineShader.DoApply(var rci: TGLRenderContextInfo; Sender: TObject);
-var
-  n, units: Integer;
-begin
-  if not GL.ARB_multitexture then
-    Exit;
-  FApplied3 := False;
-  FApplied4 := False;
-  if FCombinerIsValid and (FDesignTimeEnabled or (not (csDesigning in ComponentState))) then
-  begin
-    try
-      if Assigned(currentLibMaterial3) or Assigned(currentLibMaterial4) then
-      begin
-        gl.GetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, @n);
-        units := 0;
-        if Assigned(currentLibMaterial3) and (n >= 3) then
-        begin
-          with currentLibMaterial3.Material.Texture do
-          begin
-            if Enabled then
-            begin
-              if currentLibMaterial3.TextureMatrixIsIdentity then
-                ApplyAsTextureN(3, rci)
-              else
-                ApplyAsTextureN(3, rci, @currentLibMaterial3.TextureMatrix.V[0].X);
-              //                     ApplyAsTextureN(3, rci, currentLibMaterial3);
-              Inc(units, 4);
-              FApplied3 := True;
-            end;
-          end;
-        end;
-        if Assigned(currentLibMaterial4) and (n >= 4) then
-        begin
-          with currentLibMaterial4.Material.Texture do
-          begin
-            if Enabled then
-            begin
-              if currentLibMaterial4.TextureMatrixIsIdentity then
-                ApplyAsTextureN(4, rci)
-              else
-                ApplyAsTextureN(4, rci, @currentLibMaterial4.TextureMatrix.V[0].X);
-              //                     ApplyAsTextureN(4, rci, currentLibMaterial4);
-              Inc(units, 8);
-              FApplied4 := True;
-            end;
-          end;
-        end;
-        if units > 0 then
-          xgl.MapTexCoordToArbitraryAdd(units);
-      end;
-
-      if Length(FCommandCache) = 0 then
-        FCommandCache := GetTextureCombiners(FCombiners);
-      for n := 0 to High(FCommandCache) do
-      begin
-        rci.GLStates.ActiveTexture := FCommandCache[n].ActiveUnit;
-        gl.TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
-        gl.TexEnvi(GL_TEXTURE_ENV, FCommandCache[n].Arg1, FCommandCache[n].Arg2);
-      end;
-      rci.GLStates.ActiveTexture := 0;
-    except
-      on E: Exception do
-      begin
-        FCombinerIsValid := False;
-        InformationDlg(E.ClassName + ': ' + E.Message);
-      end;
-    end;
-  end;
-end;
-
-function TGLTextureCombineShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
-begin
-  if FApplied3 then
-    with currentLibMaterial3.Material.Texture do
-      UnApplyAsTextureN(3, rci, (not currentLibMaterial3.TextureMatrixIsIdentity));
-  if FApplied4 then
-    with currentLibMaterial4.Material.Texture do
-      UnApplyAsTextureN(4, rci, (not currentLibMaterial4.TextureMatrixIsIdentity));
-  Result := False;
-end;
-
-
-procedure TGLTextureCombineShader.DoFinalize;
-begin
-end;
-
-
-procedure TGLTextureCombineShader.SetCombiners(const val: TStringList);
-begin
-  if val <> FCombiners then
-  begin
-    FCombiners.Assign(val);
-    NotifyChange(Self);
-  end;
-end;
-
-
-procedure TGLTextureCombineShader.SetDesignTimeEnabled(const val: Boolean);
-begin
-  if val <> FDesignTimeEnabled then
-  begin
-    FDesignTimeEnabled := val;
-    NotifyChange(Self);
-  end;
-end;
-
-
-//================================================
-initialization
-//================================================
-
-  RegisterClasses([TGLTextureSharingShader, TGLTextureSharingShaderMaterials,
-                   TGLTextureSharingShaderMaterial, TGLTextureCombineShader]);
-
-end.