Sfoglia il codice sorgente

Removed *res files

GLScene 5 anni fa
parent
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
 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 *.cur /s  - cursors
 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.Variants,
   System.Classes,
+  System.Math,
   Vcl.Graphics,
   Vcl.Controls,
   Vcl.Forms,
@@ -463,10 +464,25 @@ implementation
 
 {$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);
 begin

+ 3 - 27
Packages/GLScene.groupproj

@@ -33,12 +33,6 @@
         <Projects Include="GLScene_Cg_DT.dproj">
             <Dependencies/>
         </Projects>
-        <Projects Include="GLScene_SDL_RT.dproj">
-            <Dependencies/>
-        </Projects>
-        <Projects Include="GLScene_SDL_DT.dproj">
-            <Dependencies/>
-        </Projects>
     </ItemGroup>
     <ProjectExtensions>
         <Borland.Personality>Default.Personality.12</Borland.Personality>
@@ -137,32 +131,14 @@
     <Target Name="GLScene_Cg_DT:Make">
         <MSBuild Projects="GLScene_Cg_DT.dproj" Targets="Make"/>
     </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">
-        <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 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 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>
     <Import Project="$(BDS)\Bin\CodeGear.Group.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')"/>
 </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',
   FileQ3BSP in '..\Source\FileQ3BSP.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.FileLWObjects in '..\Source\Formats.FileLWObjects.pas',
   FileMD2 in '..\Source\FileMD2.pas',
   FileMD3 in '..\Source\FileMD3.pas',
   FileO3TCImage in '..\Source\FileO3TCImage.pas',
-  FileOCT in '..\Source\FileOCT.pas',
+  Formats.FileOCT in '..\Source\Formats.FileOCT.pas',
   FileTGA in '..\Source\FileTGA.pas',
   Formats.FileX in '..\Source\Formats.FileX.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\FileQ3BSP.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.FileLWObjects.pas"/>
         <DCCReference Include="..\Source\FileMD2.pas"/>
         <DCCReference Include="..\Source\FileMD3.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\Formats.FileX.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;
 
-(*
-   Implements FBO support for GLScene.
-   Original author of the unit is Riz.
-   Modified by DaStr, C4 and YarUnderoaker.
-*)
+(* Implements Frame Buffer OpenGL support *)
 
 interface
 

+ 4 - 15
Source/GLFileB3D.pas

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

+ 1 - 1
Source/GLFileOCT.pas

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

+ 1 - 1
Source/GLS.SceneRegister.pas

@@ -359,7 +359,7 @@ uses
   GLS.Utils,
   GLSL.AsmShader,
   GLSL.BumpShaders,
-  GLSL.CelShader,
+  GLSL.ShapeShaders,
   GLSL.LineShaders,
   GLSL.ShaderCombiner,
   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.