Sfoglia il codice sorgente

* implemented SaveToFile

master
Bergmann89 11 anni fa
parent
commit
55407c60da
5 ha cambiato i file con 212 aggiunte e 26 eliminazioni
  1. +67
    -5
      uengShaderFile.pas
  2. +22
    -18
      uengShaderFileParser.pas
  3. +6
    -0
      uengShaderFileTypes.pas
  4. +83
    -1
      uengShaderPart.pas
  5. +34
    -2
      uengShaderPartInclude.pas

+ 67
- 5
uengShaderFile.pas Vedi File

@@ -12,7 +12,7 @@ interface


uses uses
Classes, sysutils, Classes, sysutils,
uengShaderCodeGenerator, uengShaderFileParser, uengShaderFileTypes
uengShaderPart, uengShaderCodeGenerator, uengShaderFileParser, uengShaderFileTypes


{$IFDEF USE_BITSPACE_UTILS} {$IFDEF USE_BITSPACE_UTILS}
, uutlSerialization , uutlSerialization
@@ -31,12 +31,21 @@ type
function GetFilename: String; override; function GetFilename: String; override;
function GetFileReader: IengShaderFileReader; override; function GetFileReader: IengShaderFileReader; override;
function GetFileWriter: IengShaderFileWriter; override; function GetFileWriter: IengShaderFileWriter; override;
public { general methods }
procedure LoadCode(const aFilename: String; const aFileReader: IengShaderFileReader = nil);

{ General }
protected
procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList); override;
public
procedure LoadFromFile(const aFilename: String; const aFlags: TengShaderFileLoadFlags = []; const aFileReader: IengShaderFileReader = nil);
procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);
destructor Destroy; override;
end; end;


implementation implementation


uses
uengShaderPartInclude;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderFile//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderFile////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -62,7 +71,16 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.LoadCode(const aFilename: String; const aFileReader: IengShaderFileReader);
procedure TengShaderFile.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList);
begin
if (sfCurrentFileOnly in aFlags) then
exclude(aFlags, sfSearchParents);
inherited FindIntern(aFlags, aDepth, aTypes, aList);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFlags: TengShaderFileLoadFlags;
const aFileReader: IengShaderFileReader);
var var
args: TengParseArgs; args: TengParseArgs;
token: String; token: String;
@@ -79,8 +97,10 @@ begin
if not fFileReader.LoadStream(aFilename, ms) then if not fFileReader.LoadStream(aFilename, ms) then
raise EengShaderPart.Create('unable to open file: ' + aFilename, Line, Col, Filename); raise EengShaderPart.Create('unable to open file: ' + aFilename, Line, Col, Filename);
ms.Position := 0; ms.Position := 0;
fFilename := aFilename;
args := TengParseArgs.Create(ms, Filename); args := TengParseArgs.Create(ms, Filename);
try try
args.Flags := aFlags;
token := ParseText(args); token := ParseText(args);
if (token <> '') then with args do if (token <> '') then with args do
raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename); raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename);
@@ -88,9 +108,51 @@ begin
FreeAndNil(args); FreeAndNil(args);
end; end;
finally finally
fFileReader := nil;
if not (lfLazyInclude in aFlags) then
fFileReader := nil;
end; end;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
var
l: TengShaderPart.TSearchList;
i: Integer;
sl: TStringList;
ms: TMemoryStream;
begin
fFileWriter := aFileWriter;
if not Assigned(fFileWriter) then
fFileWriter := FileWriter;
if not Assigned(fFileWriter) then
fFileWriter := TengShaderFileWriter.Create;

l := TengShaderPart.TSearchList.Create;
sl := TStringList.Create;
ms := TMemoryStream.Create;
try
FindAll([sfSearchChildren, sfCurrentFileOnly], [TengShaderPartInclude], l);
for i := 0 to l.Count-1 do
(l[i] as TengShaderPartInclude).SaveToFile(aFilename, aFileWriter);
sl.Text := Text;
sl.SaveToStream(ms);
ms.Position := 0;
fFileWriter.SaveStream(aFilename, ms);
finally
FreeAndNil(l);
FreeAndNil(sl);
FreeAndNil(ms);
fFileWriter := nil;
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TengShaderFile.Destroy;
begin
fFileReader := nil;
fFileWriter := nil;
inherited Destroy;
end;

end. end.



+ 22
- 18
uengShaderFileParser.pas Vedi File

@@ -6,7 +6,8 @@ unit uengShaderFileParser;
interface interface


uses uses
Classes, SysUtils
Classes, SysUtils,
uengShaderFileTypes


{$IFDEF USE_BITSPACE_UTILS} {$IFDEF USE_BITSPACE_UTILS}
, uutlGenerics , uutlGenerics
@@ -36,6 +37,7 @@ type
private private
fFilename: String; fFilename: String;
fCode: TStringList; fCode: TStringList;
fFlags: TengShaderFileLoadFlags;
fLineLength: Integer; fLineLength: Integer;
fLineCount: Integer; fLineCount: Integer;
fCurrentLine: String; fCurrentLine: String;
@@ -61,6 +63,8 @@ type
property Col: Integer read fCol write SetCol; property Col: Integer read fCol write SetCol;
property Line: Integer read fLine write SetLine; property Line: Integer read fLine write SetLine;


property Flags: TengShaderFileLoadFlags read fFlags write fFlags;

procedure NextCol; procedure NextCol;
procedure NextLine; procedure NextLine;
function ExtractToken(const aParameters: TengTokenParameterList): Boolean; function ExtractToken(const aParameters: TengTokenParameterList): Boolean;
@@ -73,7 +77,7 @@ type
implementation implementation


uses uses
uengShaderFileConstants, uengShaderFileTypes;
uengShaderFileConstants;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengTokenParameterList//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengTokenParameterList////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -150,7 +154,7 @@ type
TParseFlags = set of TParseFlag; TParseFlags = set of TParseFlag;


var var
flags: TParseFlags;
pf: TParseFlags;
ct: TCharType; ct: TCharType;
s: String; s: String;
pLine, pCol, oldLine, oldCol: Integer; pLine, pCol, oldLine, oldCol: Integer;
@@ -203,26 +207,26 @@ begin
ct := ctUnknown; ct := ctUnknown;
oldLine := Line; oldLine := Line;
oldCol := Col; oldCol := Col;
flags := [];
pf := [];
if (CurrentLine[Col+1] = TOKEN_CHAR_COMMENT) then if (CurrentLine[Col+1] = TOKEN_CHAR_COMMENT) then
Include(flags, pfIsComment);
Include(pf, pfIsComment);
AddPart; // initialize AddPart; // initialize


while not EndOfFile do begin while not EndOfFile do begin
while not EndOfLine do begin while not EndOfLine do begin
case CurrentChar of case CurrentChar of
TOKEN_CHAR_BEGIN: begin TOKEN_CHAR_BEGIN: begin
if (pfQuote in flags) then
if (pfQuote in pf) then
s := s + CurrentChar s := s + CurrentChar
else if not (pfInToken in flags) then
Include(flags, pfInToken)
else if not (pfInToken in pf) then
Include(pf, pfInToken)
else else
EengShaderPart.Create('invalid char in token', Line, Col, Filename); EengShaderPart.Create('invalid char in token', Line, Col, Filename);
end; end;


TOKEN_CHAR_END: begin TOKEN_CHAR_END: begin
if not (pfQuote in flags) then begin
AddPart(not (pfIsComment in flags));
if not (pfQuote in pf) then begin
AddPart(not (pfIsComment in pf));
NextCol; NextCol;
if (aParameters.Count <= 0) or (aParameters[0].Name = TOKEN_CHAR_IDENT) then if (aParameters.Count <= 0) or (aParameters[0].Name = TOKEN_CHAR_IDENT) then
raise EengShaderPart.Create('empty token', Line, Col, Filename); raise EengShaderPart.Create('empty token', Line, Col, Filename);
@@ -232,25 +236,25 @@ begin
end; end;


TOKEN_CHAR_QUOTE: begin TOKEN_CHAR_QUOTE: begin
if not (pfQuote in flags) and not (pfIsComment in flags) then
if not (pfQuote in pf) and not (pfIsComment in pf) then
AddPart; AddPart;
s := s + CurrentChar; s := s + CurrentChar;
if (pfQuote in flags)
then exclude(flags, pfQuote)
else include(flags, pfQuote);
if not (pfQuote in flags) and not (pfIsComment in flags) then
if (pfQuote in pf)
then exclude(pf, pfQuote)
else include(pf, pfQuote);
if not (pfQuote in pf) and not (pfIsComment in pf) then
AddPart; AddPart;
end; end;


TOKEN_CHAR_COMMENT: begin TOKEN_CHAR_COMMENT: begin
s := s + CurrentChar; s := s + CurrentChar;
if (pfIsComment in flags) and not (pfCommentTokenAdded in flags) then begin
include(flags, pfCommentTokenAdded);
if (pfIsComment in pf) and not (pfCommentTokenAdded in pf) then begin
include(pf, pfCommentTokenAdded);
AddPart(false); AddPart(false);
end; end;
end; end;
else else
if not (pfQuote in flags) and not (pfIsComment in flags) then begin
if not (pfQuote in pf) and not (pfIsComment in pf) then begin
if (CurrentChar in TOKEN_SPLIT_CHARS) then begin if (CurrentChar in TOKEN_SPLIT_CHARS) then begin
AddPart; AddPart;
end else if (CurrentChar in VALID_TOKEN_CHARS) then begin end else if (CurrentChar in VALID_TOKEN_CHARS) then begin


+ 6
- 0
uengShaderFileTypes.pas Vedi File

@@ -23,6 +23,12 @@ type
TIntfObjNoRefCount = uutlCommon.TutlInterfaceNoRefCount; TIntfObjNoRefCount = uutlCommon.TutlInterfaceNoRefCount;
{$ENDIF} {$ENDIF}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderFileLoadFlag = (
lfLazyInclude // include files will only be loaded when needed (this will store a reference to the passed IengShaderFileReader)
);
TengShaderFileLoadFlags = set of TengShaderFileLoadFlag;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EengShaderPart = class(Exception) EengShaderPart = class(Exception)
public public


+ 83
- 1
uengShaderPart.pas Vedi File

@@ -18,7 +18,18 @@ uses


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderFileSearchFlag = (
sfFirstOnly, // search first match only
sfEvaluateIf, // evaluate if statements before search and process with suitable subtree
sfSearchChildren, // search in children
sfSearchParents, // search in parents
sfCurrentFileOnly // do not search in other files
);
TengShaderFileSearchFlags = set of TengShaderFileSearchFlag;

TengShaderPart = class;
CengShaderPart = class of TengShaderPart; CengShaderPart = class of TengShaderPart;
TengShaderPartList = specialize TutlSimpleList<TengShaderPart>;
TengShaderPart = class(TIntfObjNoRefCount) TengShaderPart = class(TIntfObjNoRefCount)
{ Nested Types } { Nested Types }
public type public type
@@ -33,6 +44,11 @@ type
constructor Create(const aOwner: TengShaderPart); constructor Create(const aOwner: TengShaderPart);
end; end;


TSearchList = class(TengShaderPartList)
public
constructor Create;
end;

{ Code Loading & Storage } { Code Loading & Storage }
private { members } private { members }
fRoot: TengShaderPart; fRoot: TengShaderPart;
@@ -52,6 +68,8 @@ type
function ParseText(const aArgs: TengParseArgs): String; function ParseText(const aArgs: TengParseArgs): String;


{ General } { General }
protected
procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList); virtual;
public { general methods } public { general methods }
property Root: TengShaderPart read fRoot; property Root: TengShaderPart read fRoot;
property Parent: TengShaderPart read fParent; property Parent: TengShaderPart read fParent;
@@ -68,6 +86,8 @@ type


function HasParent(const aType: CengShaderPart; const aIncludeSelf: Boolean = false): Boolean; function HasParent(const aType: CengShaderPart; const aIncludeSelf: Boolean = false): Boolean;
function GetParent(const aType: CengShaderPart; out aPart): Boolean; function GetParent(const aType: CengShaderPart; out aPart): Boolean;
function FindFirst(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart): TengShaderPart;
procedure FindAll(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart; const aList: TSearchList);
function GetEnumerator: TEnumerator; function GetEnumerator: TEnumerator;


constructor Create(const aParent: TengShaderPart); virtual; constructor Create(const aParent: TengShaderPart); virtual;
@@ -78,13 +98,25 @@ type
class function CheckToken(const aToken: String): Boolean; virtual; class function CheckToken(const aToken: String): Boolean; virtual;
class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); virtual; class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); virtual;
end; end;
TengShaderPartList = specialize TutlSimpleList<TengShaderPart>;


implementation implementation


uses uses
uengShaderFileConstants; uengShaderFileConstants;


function CheckType(const aShaderPart: TengShaderPart; const aTypes: array of CengShaderPart): Boolean;
var
c: CengShaderPart;
begin
result := true;
if (Length(aTypes) = 0) then
exit;
for c in aTypes do
if (aShaderPart is c) then
exit;
result := false;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart.TEnumerator//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPart.TEnumerator////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -108,6 +140,14 @@ begin
fPosition := -1; fPosition := -1;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart.TSearchList////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPart.TSearchList.Create;
begin
inherited Create(false);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPart////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -169,6 +209,26 @@ begin
end; end;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList);
var
c: TengShaderPart;
begin
if (sfFirstOnly in aFlags) and (aList.Count > 0) then
exit;

if CheckType(self, aTypes) then
aList.Add(self);

if (sfSearchChildren in aFlags) then begin
for c in self do
c.FindIntern(aFlags, aDepth+1, aTypes, aList);
end;

if (sfSearchParents in aFlags) and Assigned(Parent) then
Parent.FindIntern(aFlags, aDepth-1, aTypes, aList);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPart.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
begin begin
@@ -195,6 +255,28 @@ begin
result := false; result := false;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.FindFirst(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart): TengShaderPart;
var
l: TSearchList;
begin
l := TSearchList.Create;
try
FindIntern(aFlags + [sfFirstOnly], 0, aTypes, l);
if (l.Count > 0)
then result := l[0]
else result := nil;
finally
FreeAndNil(l);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.FindAll(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart; const aList: TSearchList);
begin
FindIntern(aFlags, 0, aTypes, aList);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.GetEnumerator: TEnumerator; function TengShaderPart.GetEnumerator: TEnumerator;
begin begin


+ 34
- 2
uengShaderPartInclude.pas Vedi File

@@ -7,7 +7,7 @@ interface


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderFile, uengShaderFileParser;
uengShaderPart, uengShaderFile, uengShaderFileParser, uengShaderFileTypes;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -17,6 +17,7 @@ type
fShaderFile: TengShaderFile; fShaderFile: TengShaderFile;
fIncludeFile: String; fIncludeFile: String;
fAbsoluteFile: String; fAbsoluteFile: String;
procedure LoadShaderFile(const aFlags: TengShaderFileLoadFlags);
protected protected
function GetCount: Integer; override; function GetCount: Integer; override;
function GetChild(const aIndex: Integer): TengShaderPart; override; function GetChild(const aIndex: Integer): TengShaderPart; override;
@@ -24,8 +25,11 @@ type
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ General } { General }
protected
procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList); override;
public public
property IncludeFile: String read fIncludeFile; property IncludeFile: String read fIncludeFile;
procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);
constructor Create(const aParent: TengShaderPart); override; constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override; destructor Destroy; override;


@@ -38,10 +42,19 @@ implementation


uses uses
FileUtil, FileUtil,
uengShaderFileTypes, uengShaderFileConstants;
uengShaderFileConstants;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartInclude///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartInclude/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInclude.LoadShaderFile(const aFlags: TengShaderFileLoadFlags);
begin
if not Assigned(fShaderFile) then
fShaderFile := TengShaderFile.Create(self);
if (fShaderFile.Filename <> fAbsoluteFile) then
fShaderFile.LoadFromFile(fAbsoluteFile, aFlags);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartInclude.GetCount: Integer; function TengShaderPartInclude.GetCount: Integer;
begin begin
@@ -74,6 +87,25 @@ begin
fIncludeFile := aParams[1].Name; fIncludeFile := aParams[1].Name;
fAbsoluteFile := CreateAbsolutePath(fIncludeFile, ExtractFilePath(Filename)); fAbsoluteFile := CreateAbsolutePath(fIncludeFile, ExtractFilePath(Filename));
result := ''; result := '';
if not (lfLazyInclude in aArgs.Flags) then
LoadShaderFile(aArgs.Flags);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInclude.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList);
begin
if (sfCurrentFileOnly in aFlags) then
exclude(aFlags, sfSearchChildren);
inherited FindIntern(aFlags, aDepth, aTypes, aList);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInclude.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
begin
LoadShaderFile([]);
fIncludeFile := Format('%p_', [Pointer(fShaderFile)]) + ExtractFileName(fIncludeFile);
fAbsoluteFile := CreateAbsolutePath(fIncludeFile, ExtractFilePath(aFilename));
fShaderFile.SaveToFile(fAbsoluteFile, aFileWriter);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


Caricamento…
Annulla
Salva