unit uengShaderPartInclude; {$mode objfpc}{$H+} {$I uengShaderFile.inc} interface uses Classes, SysUtils, uengShaderPart, uengShaderCodePart, uengShaderFile, uengShaderFileParser, uengShaderFileTypes, uengShaderGeneratorArgs; type //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TengShaderPartInclude = class(TengShaderCodePart) { Code Loading & Storage } private fShaderFile: TengShaderFile; fIncludeFile: String; fAbsoluteFile: String; procedure LoadShaderFile; protected function GetCount: Integer; override; function GetChild(const aIndex: Integer): TengShaderPart; override; function GetText: String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; { Code Generation } public procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override; { General } public property IncludeFile: String read fIncludeFile; property ShaderFile: TengShaderFile read fShaderFile; procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil); constructor Create(const aParent: TengShaderPart); override; destructor Destroy; override; { Class Methods } public class function GetTokenName: String; override; end; implementation uses uengShaderFileConstants; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartInclude///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TengShaderPartInclude.LoadShaderFile; begin if not Assigned(fShaderFile) then fShaderFile := TengShaderFile.Create(self); if (fShaderFile.Filename <> fAbsoluteFile) then fShaderFile.LoadFromFile(fAbsoluteFile); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartInclude.GetCount: Integer; begin if Assigned(fShaderFile) then result := 1 else result := 0; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartInclude.GetChild(const aIndex: Integer): TengShaderPart; begin if Assigned(fShaderFile) and (aIndex = 0) then result := fShaderFile else raise EengOutOfRange.Create(0, Count-1, aIndex, self); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartInclude.GetText: String; begin result := TOKEN_CHAR_BEGIN + GetTokenName + ' ''' + fIncludeFile + '''' + TOKEN_CHAR_END; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartInclude.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; begin if (aParams[0].Name <> GetTokenName) then with aParams[0] do raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self); if (aParams.Count <> 2) then raise EengInvalidParamterCount.Create(GetTokenName, 2, self); fIncludeFile := aParams[1].Name; fAbsoluteFile := ExtractFilePath(Filename) + fIncludeFile; result := ''; LoadShaderFile; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TengShaderPartInclude.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); begin LoadShaderFile; inherited GenerateCodeIntern(aArgs); if Assigned(fShaderFile) then fShaderFile.GenerateCodeIntern(aArgs); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TengShaderPartInclude.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter); begin LoadShaderFile; if (Pos('SFPF', ExtractFileName(fIncludeFile)) <> 1) then fIncludeFile := Format('SFPF%p_', [Pointer(fShaderFile)]) + ExtractFileName(fIncludeFile); fAbsoluteFile := ExtractFilePath(aFilename) + fIncludeFile; fShaderFile.SaveToFile(fAbsoluteFile, aFileWriter); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TengShaderPartInclude.Create(const aParent: TengShaderPart); begin inherited Create(aParent); fShaderFile := nil; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TengShaderPartInclude.Destroy; begin FreeAndNil(fShaderFile); inherited Destroy; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function TengShaderPartInclude.GetTokenName: String; begin result := TOKEN_INCLUDE; end; end.