GXS.CgShader.pas 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256
  1. //
  2. // The graphics engine GXScene
  3. //
  4. unit GXS.CgShader;
  5. (* Base Cg shader classes *)
  6. interface
  7. uses
  8. Winapi.OpenGL,
  9. Winapi.OpenGLext,
  10. System.Classes,
  11. System.SysUtils,
  12. Stage.VectorGeometry,
  13. GXS.VectorLists,
  14. Stage.VectorTypes,
  15. GXS.Texture,
  16. Stage.Strings,
  17. GXS.Cadencer,
  18. GXS.Context,
  19. GXS.BaseClasses,
  20. GXS.RenderContextInfo,
  21. GXS.Material,
  22. Stage.TextureFormat,
  23. Cg.Import,
  24. Cg.GL;
  25. { .$DEFINE OutputCompilerWarnings }
  26. (* Define OutputCompilerWarnings to output CG compiler warnings to a file. Useful
  27. for detecting bugs caused by using uninitialized value, implicit type cast, etc. *)
  28. type
  29. ECGxShaderException = class(EShaderException);
  30. TCGxCustomShader = class;
  31. TCGxProgram = class;
  32. TCGxParameter = class;
  33. TCGxApplyEvent = procedure(CgProgram: TCGxProgram; Sender: TObject) of object;
  34. TCgUnApplyEvent = procedure(CgProgram: TCGxProgram) of object;
  35. TCGxShaderEvent = procedure(CgShader: TCGxCustomShader) of object;
  36. TCGxProgramType = (ptVertex, ptFragment);
  37. // Available vertex program profile
  38. TCgVPProfile = (vpDetectLatest, vp20, vp30, vp40, arbvp1);
  39. // Available fragment program profile
  40. TCgFPProfile = (fpDetectLatest, fp20, fp30, fp40, arbfp1);
  41. TPrecisionSetting = (psFull, psFast);
  42. // Wrapper around a Cg program.
  43. TCGxProgram = class(TgxUpdateAbleObject)
  44. private
  45. FCgContext: PcgContext;
  46. FCode: TStrings; // the Cg program itself
  47. FProgramName: String;
  48. FHandle: PCGprogram;
  49. FParams: TList;
  50. FOnApply: TCGxApplyEvent;
  51. FOnUnApply: TCgUnApplyEvent;
  52. FOnProgramChanged: TNotifyEvent;
  53. FEnabled: boolean;
  54. FDetectProfile: boolean;
  55. FPrecision: TPrecisionSetting;
  56. procedure SetPrecision(const Value: TPrecisionSetting);
  57. function GetManualNotification: boolean;
  58. procedure SetManualNotification(const Value: boolean);
  59. protected
  60. FProgramType: TCGxProgramType;
  61. FProfile: TcgProfile;
  62. procedure SetCode(const val: TStrings);
  63. procedure SetProgramName(const val: String);
  64. function GetParam(index: String): TCGxParameter;
  65. procedure AddParamsItem(const Param: PCGParameter);
  66. (* Build a list of parameters used in the shader code.
  67. Iteratively queries all parameters so that we can manage and access them
  68. easily. Currently only collects leaf parameters i.e. data structure is
  69. not retrieved. *)
  70. procedure BuildParamsList;
  71. procedure ClearParamsList;
  72. public
  73. constructor Create(AOwner: TPersistent); override;
  74. destructor Destroy; override;
  75. function GetLatestProfile: TcgProfile; virtual; abstract;
  76. procedure Initialize; virtual;
  77. procedure Finalize;
  78. procedure Apply(var rci: TgxRenderContextInfo; Sender: TObject);
  79. procedure UnApply(var rci: TgxRenderContextInfo);
  80. // ParamByName returns CgParameter; returns nil if not found.
  81. function ParamByName(const name: String): TCGxParameter;
  82. (* Use Param instead of ParamByName if you want implicit check for the
  83. existence of your requested parameter. *)
  84. property Param[index: String]: TCGxParameter read GetParam;
  85. property Params: TList read FParams;
  86. // Returns a handle to a Cg parameter
  87. function DirectParamByName(const name: String): PCGParameter;
  88. function ParamCount: Integer;
  89. function GetProfileStringA: string;
  90. procedure LoadFromFile(const fileName: String);
  91. procedure ListCompilation(Output: TStrings);
  92. procedure ListParameters(Output: TStrings);
  93. // shorthands for accessing parameters
  94. procedure SetParam(ParamName: string; SingleVal: Single); overload;
  95. procedure SetParam(ParamName: string;
  96. const Vector2fVal: TVector2f); overload;
  97. procedure SetParam(ParamName: string;
  98. const Vector3fVal: TVector3f); overload;
  99. procedure SetParam(ParamName: string;
  100. const Vector4fVal: TVector4f); overload;
  101. procedure SetStateMatrix(ParamName: string; matrix, Transform: Cardinal);
  102. procedure SetTexture(ParamName: string; TextureID: Cardinal);
  103. // retruns ShaderName.[program type].ProgramName
  104. function LongName: string;
  105. (* Direct access to the profile.
  106. Set Profile of the sub-classes to any but DetectLatest if you want to
  107. specify the profile directly. *)
  108. property DirectProfile: TcgProfile read FProfile write FProfile;
  109. // Seams, that this event is never called. Probably should be deleted...
  110. property OnProgramChanged: TNotifyEvent read FOnProgramChanged
  111. write FOnProgramChanged;
  112. // If True, that shader is not reset when TCGxProgram' parameters change.
  113. property ManualNotification: boolean read GetManualNotification
  114. write SetManualNotification default False;
  115. published
  116. property Code: TStrings read FCode write SetCode;
  117. property ProgramName: String read FProgramName write SetProgramName;
  118. property Enabled: boolean read FEnabled write FEnabled default True;
  119. (* Precision controls data precision of GPU operation.
  120. Possible options are 16-bit (psFast) or 32-bit (psFull). 16-bit operation
  121. is generally faster. *)
  122. property Precision: TPrecisionSetting read FPrecision write SetPrecision
  123. default psFull;
  124. property OnApply: TCGxApplyEvent read FOnApply write FOnApply;
  125. property OnUnApply: TCgUnApplyEvent read FOnUnApply write FOnUnApply;
  126. end;
  127. // Wrapper around a Cg parameter of the main program.
  128. TCGxParameter = class(TObject)
  129. private
  130. FOwner: TCGxProgram;
  131. FName: String;
  132. FHandle: PCGParameter;
  133. FValueType: TCGtype; // e.g. CG_FLOAT
  134. FDirection: TCGenum; // e.g. CG_INOUT
  135. FVariability: TCGenum; // e.g. CG_UNIFORM
  136. protected
  137. function TypeMismatchMessage: string;
  138. procedure CheckValueType(aType: TCGtype); overload;
  139. procedure CheckValueType(const types: array of TCGtype); overload;
  140. procedure CheckAllTextureTypes;
  141. procedure CheckAllScalarTypes;
  142. procedure CheckAllVector2fTypes;
  143. procedure CheckAllVector3fTypes;
  144. procedure CheckAllVector4fTypes;
  145. procedure SetAsVector2f(const val: TVector2f);
  146. procedure SetAsVector3f(const val: TVector3f);
  147. procedure SetAsVector4f(const val: TVector4f);
  148. public
  149. constructor Create; virtual;
  150. destructor Destroy; override;
  151. (* Procedures for setting uniform pamareters.
  152. Implicitly check for data type. *)
  153. procedure SetAsScalar(const val: Single); overload;
  154. procedure SetAsScalar(const val: boolean); overload;
  155. procedure SetAsVector(const val: TVector2f); overload;
  156. procedure SetAsVector(const val: TVector3f); overload;
  157. procedure SetAsVector(const val: TVector4f); overload;
  158. (* This overloaded SetAsVector accepts open array as input. e.g.
  159. SetAsVector([0.1, 0.2]). Array length must between 1-4. *)
  160. procedure SetAsVector(const val: array of Single); overload;
  161. procedure SetAsStateMatrix(matrix, Transform: Cardinal);
  162. procedure SetAsMatrix(const val: TMatrix4f);
  163. (* Procedures for dealing with texture pamareters. *)
  164. // SetAsTexture checks for all texture types
  165. procedure SetAsTexture(TextureID: Cardinal);
  166. // SetAsTexture* check for specific type
  167. procedure SetAsTexture1D(TextureID: Cardinal);
  168. procedure SetAsTexture2D(TextureID: Cardinal);
  169. procedure SetAsTexture3D(TextureID: Cardinal);
  170. procedure SetAsTextureCUBE(TextureID: Cardinal);
  171. procedure SetAsTextureRECT(TextureID: Cardinal);
  172. // SetToTextureOf determines texture type on-the-fly.
  173. procedure SetToTextureOf(LibMaterial: TgxLibMaterial);
  174. procedure EnableTexture;
  175. procedure DisableTexture;
  176. // Procedures for setting varying parameters with an array of values.
  177. procedure SetParameterPointer(Values: TgxVectorList); overload;
  178. procedure SetParameterPointer(Values: TgxAffineVectorList); overload;
  179. procedure EnableClientState;
  180. procedure DisableClientState;
  181. // LongName retruns ShaderName.[program type].ProgramName.ParamName.
  182. function LongName: string;
  183. property Owner: TCGxProgram read FOwner;
  184. property Name: String read FName;
  185. property ValueType: TCGtype read FValueType;
  186. property Handle: PCGParameter read FHandle write FHandle;
  187. property Direction: TCGenum read FDirection write FDirection;
  188. property Variability: TCGenum read FVariability write FVariability;
  189. // GLScene-friendly properties
  190. property AsVector: TVector4f write SetAsVector4f; // position f.i.
  191. property AsAffineVector: TAffineVector write SetAsVector3f; // normal f.i.
  192. property AsVector2f: TVector2f write SetAsVector2f; // texCoord f.i.
  193. end;
  194. TCGxVertexProgram = class(TCGxProgram)
  195. private
  196. FVPProfile: TCgVPProfile;
  197. procedure SetVPProfile(v: TCgVPProfile);
  198. public
  199. constructor Create(AOwner: TPersistent); override;
  200. function GetLatestProfile: TcgProfile; override;
  201. published
  202. property Profile: TCgVPProfile read FVPProfile write SetVPProfile
  203. default vpDetectLatest;
  204. end;
  205. TCGxFragmentProgram = class(TCGxProgram)
  206. private
  207. FFPProfile: TCgFPProfile;
  208. FManageTexture: boolean;
  209. procedure SetFPProfile(v: TCgFPProfile);
  210. procedure SetManageTexture(const Value: boolean);
  211. public
  212. constructor Create(AOwner: TPersistent); override;
  213. procedure Initialize; override;
  214. function GetLatestProfile: TcgProfile; override;
  215. published
  216. property Profile: TCgFPProfile read FFPProfile write SetFPProfile
  217. default fpDetectLatest;
  218. // Switch for auto enabling of texture parameters (Cg 1.2 feature)
  219. // With Cg 1.2.1, default is OFF
  220. property ManageTexture: boolean read FManageTexture write SetManageTexture
  221. default False;
  222. end;
  223. TCGxCustomShader = class(TgxShader)
  224. private
  225. FVertexProgram: TCGxVertexProgram;
  226. FFragmentProgram: TCGxFragmentProgram;
  227. FOnInitialize: TCGxShaderEvent;
  228. FDesignEnable: boolean;
  229. protected
  230. // Vertex Program
  231. procedure SetVertexProgram(const val: TCGxVertexProgram);
  232. procedure SetOnApplyVertexProgram(const val: TCGxApplyEvent);
  233. function GetOnApplyVertexProgram: TCGxApplyEvent;
  234. procedure SetOnUnApplyVertexProgram(const val: TCgUnApplyEvent);
  235. function GetOnUnApplyVertexProgram: TCgUnApplyEvent;
  236. // Fragment Program
  237. procedure SetFragmentProgram(const val: TCGxFragmentProgram);
  238. procedure SetOnApplyFragmentProgram(const val: TCGxApplyEvent);
  239. function GetOnApplyFragmentProgram: TCGxApplyEvent;
  240. procedure SetOnUnApplyFragmentProgram(const val: TCgUnApplyEvent);
  241. function GetOnUnApplyFragmentProgram: TCgUnApplyEvent;
  242. // OnInitialize
  243. function GetOnInitialize: TCGxShaderEvent;
  244. procedure SetOnInitialize(const val: TCGxShaderEvent);
  245. procedure DoInitialize(var rci: TgxRenderContextInfo;
  246. Sender: TObject); override;
  247. procedure DoFinalize; override;
  248. procedure DoApply(var rci: TgxRenderContextInfo; Sender: TObject); override;
  249. function DoUnApply(var rci: TgxRenderContextInfo): boolean; override;
  250. // IsProfileSupported to be obsoleted by global function IsCgProfileSupported
  251. function IsProfileSupported(Profile: TcgProfile): boolean;
  252. (* Everything is moved here from the public and protected sections
  253. because I would like to shield end-users of descendant shader
  254. classes from all this stuff. Those who want direct access
  255. to shader events and parameters should use the TCGxShader class,
  256. where everything is published. *)
  257. property OnApplyVP: TCGxApplyEvent read GetOnApplyVertexProgram
  258. write SetOnApplyVertexProgram;
  259. property OnApplyFP: TCGxApplyEvent read GetOnApplyFragmentProgram
  260. write SetOnApplyFragmentProgram;
  261. property OnUnApplyVP: TCgUnApplyEvent read GetOnUnApplyVertexProgram
  262. write SetOnUnApplyVertexProgram;
  263. property OnUnApplyFP: TCgUnApplyEvent read GetOnUnApplyFragmentProgram
  264. write SetOnUnApplyFragmentProgram;
  265. (* OnInitialize can be use to set parameters that need to be set once only.
  266. See demo "Cg Texture" for example. *)
  267. property OnInitialize: TCGxShaderEvent read GetOnInitialize
  268. write SetOnInitialize;
  269. property DesignEnable: boolean read FDesignEnable write FDesignEnable
  270. default False;
  271. property VertexProgram: TCGxVertexProgram read FVertexProgram
  272. write SetVertexProgram;
  273. property FragmentProgram: TCGxFragmentProgram read FFragmentProgram
  274. write SetFragmentProgram;
  275. public
  276. constructor Create(AOwner: TComponent); override;
  277. destructor Destroy; override;
  278. procedure LoadShaderPrograms(const VPFilename, FPFilename: string);
  279. function ShaderSupported: boolean; override;
  280. end;
  281. // Allows to use a Cadencer, which is used for noise generation in many shaders.
  282. TCGxCadencableCustomShader = class(TCGxCustomShader)
  283. private
  284. FCadencer: TgxCadencer;
  285. procedure SetCadencer(const Value: TgxCadencer);
  286. protected
  287. procedure DoInitialize(var rci: TgxRenderContextInfo;
  288. Sender: TObject); override;
  289. procedure Notification(AComponent: TComponent;
  290. Operation: TOperation); override;
  291. public
  292. property Cadencer: TgxCadencer read FCadencer write SetCadencer;
  293. end;
  294. TCGxShader = class(TCGxCustomShader)
  295. published
  296. property DesignEnable;
  297. property ShaderStyle;
  298. property FailedInitAction;
  299. property VertexProgram;
  300. property FragmentProgram;
  301. property OnApplyVP;
  302. property OnApplyFP;
  303. property OnUnApplyVP;
  304. property OnUnApplyFP;
  305. property OnInitialize;
  306. end;
  307. // global variables/functions
  308. var
  309. (* Set IncludeFilePath to indicate where to find your include file for your
  310. Cg source files. This avoids error from the Cg Compiler when the current
  311. directory is not the right path as the shader is being compiled. *)
  312. IncludeFilePath: string;
  313. {$IFDEF OutputCompilerWarnings}
  314. (* Edit the string WarningFilePath for the output filename. Default
  315. WarningFilePath is set to application path. *)
  316. WarningFilePath: string;
  317. {$ENDIF}
  318. // Misc. global functions
  319. function IsCgProfileSupported(Profile: TcgProfile): boolean;
  320. implementation // -------------------------------------------------------------
  321. const
  322. CgBoolean: array [False .. True] of TCGbool = (CG_FALSE, CG_TRUE);
  323. var
  324. vCgContextCount: Integer;
  325. CurCgProgram: TCGxProgram; // for reporting error
  326. {$IFDEF OutputCompilerWarnings}
  327. CompilerMsg: TStringList; // useful for seeing compiler warnings
  328. {$ENDIF}
  329. function IsCgProfileSupported(Profile: TcgProfile): boolean;
  330. begin
  331. result := cgGLIsProfileSupported(Profile) = CG_TRUE;
  332. end;
  333. {$IFDEF OutputCompilerWarnings}
  334. procedure RecordWarnings;
  335. begin
  336. with CurCgProgram do
  337. CompilerMsg.Add('[' + LongName + '] ' + cgGetErrorString(cgGetError) + #10 +
  338. cgGetLastListing(FCgContext));
  339. end;
  340. {$ENDIF}
  341. procedure ErrorCallBack; cdecl;
  342. var
  343. Msg: string;
  344. begin
  345. with CurCgProgram do
  346. Msg := '[' + LongName + '] ' + String(cgGetErrorString(cgGetError)) + #10 +
  347. String(cgGetLastListing(FCgContext));
  348. raise ECGxShaderException.Create(Msg);
  349. end;
  350. // ------------------
  351. // ------------------ TCGxProgram ------------------
  352. // ------------------
  353. constructor TCGxProgram.Create(AOwner: TPersistent);
  354. begin
  355. inherited;
  356. FCode := TStringList.Create;
  357. TStringList(FCode).OnChange := NotifyChange;
  358. FParams := TList.Create;
  359. FEnabled := True;
  360. FDetectProfile := True;
  361. end;
  362. destructor TCGxProgram.Destroy;
  363. begin
  364. inherited Destroy;
  365. Assert((FParams.Count = 0), '[' + LongName + ']: bug! params unbound!');
  366. ClearParamsList;
  367. FParams.Free;
  368. FCode.Free;
  369. end;
  370. procedure TCGxProgram.SetCode(const val: TStrings);
  371. begin
  372. FCode.Assign(val);
  373. end;
  374. procedure TCGxProgram.LoadFromFile(const fileName: String);
  375. begin
  376. Code.LoadFromFile(fileName);
  377. end;
  378. procedure TCGxProgram.SetProgramName(const val: String);
  379. begin
  380. if val <> FProgramName then
  381. begin
  382. FProgramName := val;
  383. if not GetManualNotification then
  384. NotifyChange(Self);
  385. end;
  386. end;
  387. procedure TCGxProgram.AddParamsItem(const Param: PCGParameter);
  388. var
  389. newParamObj: TCGxParameter;
  390. begin
  391. newParamObj := TCGxParameter.Create;
  392. with newParamObj do
  393. begin
  394. FOwner := Self;
  395. FName := { StrPas } String(cgGetParameterName(Param));
  396. FHandle := Param;
  397. FValueType := cgGetParameterType(Param);
  398. FDirection := cgGetParameterDirection(Param);
  399. FVariability := cgGetParameterVariability(Param);
  400. end;
  401. FParams.Add(newParamObj);
  402. end;
  403. procedure TCGxProgram.BuildParamsList;
  404. var
  405. CurParam: PCGParameter;
  406. begin
  407. ClearParamsList;
  408. CurParam := cgGetFirstLeafParameter(FHandle, CG_PROGRAM);
  409. // build params list
  410. while Assigned(CurParam) do
  411. begin
  412. AddParamsItem(CurParam);
  413. CurParam := cgGetNextLeafParameter(CurParam);
  414. end;
  415. end;
  416. procedure TCGxProgram.ClearParamsList;
  417. var
  418. i: Integer;
  419. begin
  420. for i := FParams.Count - 1 downto 0 do
  421. TCGxParameter(FParams[i]).Free;
  422. FParams.Clear;
  423. end;
  424. function TCGxProgram.GetParam(index: String): TCGxParameter;
  425. begin
  426. result := ParamByName(index);
  427. Assert(result <> nil, '[' + LongName + ']: Parameter "' +
  428. index + '" not found.');
  429. end;
  430. function TCGxProgram.ParamByName(const name: String): TCGxParameter;
  431. var
  432. i: Integer;
  433. begin
  434. result := nil;
  435. for i := 0 to FParams.Count - 1 do
  436. begin
  437. if TCGxParameter(FParams.Items[i]).name = name then
  438. begin
  439. result := TCGxParameter(FParams.Items[i]);
  440. Exit;
  441. end;
  442. end;
  443. end;
  444. function TCGxProgram.DirectParamByName(const name: String): PCGParameter;
  445. begin
  446. result := cgGetNamedParameter(FHandle, PCharCG(StringCG(name)));
  447. end;
  448. function TCGxProgram.ParamCount: Integer;
  449. begin
  450. result := FParams.Count;
  451. end;
  452. procedure TCGxProgram.Initialize;
  453. var
  454. buf: StringCG;
  455. Arg: array of PCharCG;
  456. PArg: PPCharCG;
  457. begin
  458. Assert(FCgContext = nil);
  459. buf := StringCG(Trim(Code.Text));
  460. if buf = '' then
  461. Exit;
  462. if Precision = psFast then
  463. begin
  464. setlength(Arg, 2);
  465. Arg[0] := PCharCG('-fastprecision');
  466. Arg[1] := nil;
  467. PArg := @Arg[0];
  468. end
  469. else
  470. PArg := nil;
  471. // To force 'if' statement, use sth. like:
  472. // setlength(Arg, 3);
  473. // Arg[0]:=PChar('-ifcvt');
  474. // Arg[1]:=PChar('none');
  475. // Arg[2]:=nil;
  476. // PArg:=@Arg[0];
  477. // get a new context
  478. FCgContext := cgCreateContext;
  479. Inc(vCgContextCount);
  480. CurCgProgram := Self;
  481. try
  482. if IncludeFilePath <> '' then
  483. SetCurrentDir(IncludeFilePath);
  484. if FDetectProfile then
  485. FProfile := GetLatestProfile;
  486. cgGLSetOptimalOptions(FProfile);
  487. if FProgramName = '' then
  488. FProgramName := 'main'; // default program name
  489. FHandle := cgCreateProgram(FCgContext, CG_SOURCE, PCharCG(buf), FProfile,
  490. PCharCG(StringCG(FProgramName)), PArg);
  491. cgGLLoadProgram(FHandle);
  492. // build parameter list for the selected program
  493. BuildParamsList;
  494. {$IFDEF OutputCompilerWarnings}
  495. RecordWarnings;
  496. {$ENDIF}
  497. except
  498. cgDestroyContext(FCgContext);
  499. FCgContext := nil;
  500. Dec(vCgContextCount);
  501. raise;
  502. end;
  503. end;
  504. procedure TCGxProgram.Finalize;
  505. begin
  506. if not Assigned(FCgContext) then
  507. Exit;
  508. FProgramName := '';
  509. ClearParamsList;
  510. cgDestroyContext(FCgContext);
  511. FCgContext := nil;
  512. FHandle := nil; // $added - 29/04/2006 - PhP
  513. Dec(vCgContextCount);
  514. end;
  515. procedure TCGxProgram.Apply(var rci: TgxRenderContextInfo; Sender: TObject);
  516. begin
  517. if not Assigned(FHandle) then
  518. Exit;
  519. if not FEnabled then
  520. Exit;
  521. CurCgProgram := Self;
  522. cgGLBindProgram(FHandle);
  523. cgGLEnableProfile(FProfile);
  524. if Assigned(FOnApply) then
  525. FOnApply(Self, Sender);
  526. end;
  527. procedure TCGxProgram.UnApply(var rci: TgxRenderContextInfo);
  528. begin
  529. if not Assigned(FHandle) then
  530. Exit;
  531. if not FEnabled then
  532. Exit;
  533. if Assigned(FOnUnApply) then
  534. FOnUnApply(Self);
  535. cgGLDisableProfile(FProfile);
  536. end;
  537. function TCGxProgram.GetProfileStringA: string;
  538. begin
  539. result := String(cgGetProfileString(FProfile));
  540. end;
  541. procedure TCGxProgram.ListParameters(Output: TStrings);
  542. var
  543. i: Integer;
  544. begin
  545. Output.Clear;
  546. for i := 0 to ParamCount - 1 do
  547. Output.Add(TCGxParameter(FParams[i]).name);
  548. end;
  549. procedure TCGxProgram.ListCompilation(Output: TStrings);
  550. procedure OutputAsTStrings(s: String);
  551. var
  552. i: Integer;
  553. begin
  554. while Length(s) > 0 do
  555. begin
  556. i := Pos(#10, s);
  557. if i = 0 then
  558. i := 255;
  559. Output.Add(Copy(s, 1, i - 1));
  560. Delete(s, 1, i);
  561. end;
  562. end;
  563. begin
  564. Output.BeginUpdate;
  565. Output.Clear;
  566. if FCgContext <> nil then
  567. OutputAsTStrings(String(cgGetProgramString(FHandle, CG_COMPILED_PROGRAM)))
  568. else
  569. Output.Add('Cg program not yet initialized');
  570. Output.EndUpdate;
  571. end;
  572. procedure TCGxProgram.SetParam(ParamName: string; const Vector3fVal: TVector3f);
  573. begin
  574. ParamByName(ParamName).SetAsVector3f(Vector3fVal);
  575. end;
  576. procedure TCGxProgram.SetParam(ParamName: string; const Vector2fVal: TVector2f);
  577. begin
  578. ParamByName(ParamName).SetAsVector2f(Vector2fVal);
  579. end;
  580. procedure TCGxProgram.SetParam(ParamName: string; SingleVal: Single);
  581. begin
  582. Param[ParamName].SetAsScalar(SingleVal);
  583. end;
  584. procedure TCGxProgram.SetParam(ParamName: string; const Vector4fVal: TVector4f);
  585. begin
  586. ParamByName(ParamName).SetAsVector4f(Vector4fVal);
  587. end;
  588. procedure TCGxProgram.SetStateMatrix(ParamName: string;
  589. matrix, Transform: Cardinal);
  590. begin
  591. ParamByName(ParamName).SetAsStateMatrix(matrix, Transform);
  592. end;
  593. procedure TCGxProgram.SetTexture(ParamName: string; TextureID: Cardinal);
  594. begin
  595. ParamByName(ParamName).SetAsTexture(TextureID);
  596. end;
  597. function TCGxProgram.LongName: string;
  598. const
  599. ProTypeStr: array [ptVertex .. ptFragment] of string = ('VP', 'FP');
  600. begin
  601. result := (Owner as TCGxShader).name + '.' + ProTypeStr[FProgramType] + '.' +
  602. ProgramName;
  603. end;
  604. procedure TCGxProgram.SetPrecision(const Value: TPrecisionSetting);
  605. begin
  606. if FPrecision <> Value then
  607. begin
  608. FPrecision := Value;
  609. if not GetManualNotification then
  610. NotifyChange(Self);
  611. end;
  612. end;
  613. function TCGxProgram.GetManualNotification: boolean;
  614. begin
  615. result := not Assigned(TStringList(FCode).OnChange);
  616. end;
  617. procedure TCGxProgram.SetManualNotification(const Value: boolean);
  618. begin
  619. if Value = GetManualNotification then
  620. Exit;
  621. if Value then
  622. TStringList(FCode).OnChange := nil
  623. else
  624. TStringList(FCode).OnChange := NotifyChange;
  625. end;
  626. // ------------------
  627. // ------------------ TCGxParameter ------------------
  628. // ------------------
  629. constructor TCGxParameter.Create;
  630. begin
  631. inherited;
  632. end;
  633. destructor TCGxParameter.Destroy;
  634. begin
  635. inherited;
  636. end;
  637. function TCGxParameter.LongName: string;
  638. begin
  639. result := Owner.LongName + '.' + FName;
  640. end;
  641. function TCGxParameter.TypeMismatchMessage: string;
  642. begin
  643. result := '[' + LongName + ']: Parameter type mismatch.';
  644. end;
  645. procedure TCGxParameter.CheckValueType(aType: TCGtype);
  646. begin
  647. Assert(aType = FValueType, TypeMismatchMessage);
  648. end;
  649. procedure TCGxParameter.CheckValueType(const types: array of TCGtype);
  650. function DoCheck: boolean;
  651. var
  652. i: Integer;
  653. begin
  654. result := False;
  655. for i := Low(types) to High(types) do
  656. if FValueType = types[i] then
  657. begin
  658. result := True;
  659. Break;
  660. end;
  661. end;
  662. begin
  663. Assert(DoCheck, TypeMismatchMessage);
  664. end;
  665. procedure TCGxParameter.CheckAllScalarTypes;
  666. begin
  667. CheckValueType([CG_FLOAT, CG_HALF, CG_FIXED, CG_BOOL]);
  668. end;
  669. procedure TCGxParameter.CheckAllTextureTypes;
  670. begin
  671. CheckValueType([CG_SAMPLER2D, CG_SAMPLER1D, CG_SAMPLERRECT, CG_SAMPLERCUBE,
  672. CG_SAMPLER3D]);
  673. end;
  674. procedure TCGxParameter.CheckAllVector2fTypes;
  675. begin
  676. CheckValueType([CG_FLOAT2, CG_HALF2, CG_FIXED2]);
  677. end;
  678. procedure TCGxParameter.CheckAllVector3fTypes;
  679. begin
  680. CheckValueType([CG_FLOAT3, CG_HALF3, CG_FIXED3]);
  681. end;
  682. procedure TCGxParameter.CheckAllVector4fTypes;
  683. begin
  684. CheckValueType([CG_FLOAT4, CG_HALF4, CG_FIXED4]);
  685. end;
  686. procedure TCGxParameter.SetAsScalar(const val: Single);
  687. begin
  688. CheckAllScalarTypes;
  689. cgGLSetParameter1f(FHandle, val);
  690. end;
  691. procedure TCGxParameter.SetAsScalar(const val: boolean);
  692. const
  693. BoolToFloat: array [False .. True] of Single = (CG_FALSE, CG_TRUE);
  694. begin
  695. SetAsScalar(BoolToFloat[val]);
  696. end;
  697. procedure TCGxParameter.SetAsVector2f(const val: TVector2f);
  698. begin
  699. CheckAllVector2fTypes;
  700. cgGLSetParameter2fv(FHandle, @val);
  701. end;
  702. procedure TCGxParameter.SetAsVector3f(const val: TVector3f);
  703. begin
  704. CheckAllVector3fTypes;
  705. cgGLSetParameter3fv(FHandle, @val);
  706. end;
  707. procedure TCGxParameter.SetAsVector4f(const val: TVector4f);
  708. begin
  709. CheckAllVector4fTypes;
  710. cgGLSetParameter4fv(FHandle, @val);
  711. end;
  712. procedure TCGxParameter.SetAsVector(const val: TVector2f);
  713. begin
  714. SetAsVector2f(val);
  715. end;
  716. procedure TCGxParameter.SetAsVector(const val: TVector3f);
  717. begin
  718. SetAsVector3f(val);
  719. end;
  720. procedure TCGxParameter.SetAsVector(const val: TVector4f);
  721. begin
  722. SetAsVector4f(val);
  723. end;
  724. procedure TCGxParameter.SetAsVector(const val: array of Single);
  725. begin
  726. case high(val) of
  727. 0:
  728. SetAsScalar(val[0]);
  729. 1:
  730. begin
  731. CheckAllVector2fTypes;
  732. cgGLSetParameter2fv(FHandle, @val);
  733. end;
  734. 2:
  735. begin
  736. CheckAllVector3fTypes;
  737. cgGLSetParameter3fv(FHandle, @val);
  738. end;
  739. 3:
  740. begin
  741. CheckAllVector4fTypes;
  742. cgGLSetParameter4fv(FHandle, @val);
  743. end;
  744. else
  745. Assert(False, 'Vector length must be between 1 to 4');
  746. end;
  747. end;
  748. procedure TCGxParameter.SetAsTexture(TextureID: Cardinal);
  749. begin
  750. CheckAllTextureTypes;
  751. cgGLSetTextureParameter(FHandle, TextureID);
  752. end;
  753. procedure TCGxParameter.SetAsTexture1D(TextureID: Cardinal);
  754. begin
  755. CheckValueType(CG_SAMPLER1D);
  756. cgGLSetTextureParameter(FHandle, TextureID);
  757. end;
  758. procedure TCGxParameter.SetAsTexture2D(TextureID: Cardinal);
  759. begin
  760. CheckValueType(CG_SAMPLER2D);
  761. cgGLSetTextureParameter(FHandle, TextureID);
  762. end;
  763. procedure TCGxParameter.SetAsTexture3D(TextureID: Cardinal);
  764. begin
  765. CheckValueType(CG_SAMPLER3D);
  766. cgGLSetTextureParameter(FHandle, TextureID);
  767. end;
  768. procedure TCGxParameter.SetAsTextureRECT(TextureID: Cardinal);
  769. begin
  770. CheckValueType(CG_SAMPLERRECT);
  771. cgGLSetTextureParameter(FHandle, TextureID);
  772. end;
  773. procedure TCGxParameter.SetAsTextureCUBE(TextureID: Cardinal);
  774. begin
  775. CheckValueType(CG_SAMPLERCUBE);
  776. cgGLSetTextureParameter(FHandle, TextureID);
  777. end;
  778. procedure TCGxParameter.SetToTextureOf(LibMaterial: TgxLibMaterial);
  779. var
  780. TexType: TCGtype;
  781. begin
  782. case LibMaterial.Material.Texture.Image.NativeTextureTarget of
  783. ttTexture2D:
  784. TexType := CG_SAMPLER2D;
  785. ttTextureCUBE:
  786. TexType := CG_SAMPLER2D;
  787. ttTextureRECT:
  788. TexType := CG_SAMPLERRECT;
  789. ttTexture1D:
  790. TexType := CG_SAMPLER1D;
  791. ttTexture3D:
  792. TexType := CG_SAMPLER3D;
  793. else
  794. begin
  795. Assert(False, 'Unknown texture target');
  796. TexType := CG_SAMPLER2D; // to subpress compilation warning
  797. end;
  798. end;
  799. CheckValueType(TexType);
  800. cgGLSetTextureParameter(FHandle, LibMaterial.Material.Texture.Handle);
  801. end;
  802. procedure TCGxParameter.DisableTexture;
  803. begin
  804. CheckAllTextureTypes;
  805. cgGLDisableTextureParameter(FHandle);
  806. end;
  807. procedure TCGxParameter.EnableTexture;
  808. begin
  809. CheckAllTextureTypes;
  810. cgGLEnableTextureParameter(FHandle);
  811. end;
  812. procedure TCGxParameter.SetAsStateMatrix(matrix, Transform: Cardinal);
  813. // Assuming values of matrix types are contiguous to simplify the type checking
  814. const
  815. MinFloatA = CG_FLOAT1x1;
  816. MaxFloatA = CG_FLOAT4x4;
  817. MinHalfA = CG_HALF1x1;
  818. MaxHalfA = CG_HALF4x4;
  819. MinFixedA = CG_FIXED1x1;
  820. MaxFixedA = CG_FIXED4x4;
  821. begin
  822. Assert(((FValueType >= MinFloatA) and (FValueType <= MaxFloatA) or
  823. (FValueType >= MinHalfA) and (FValueType <= MaxHalfA) or
  824. (FValueType >= MinFixedA) and (FValueType <= MaxFixedA)),
  825. TypeMismatchMessage);
  826. cgGLSetStateMatrixParameter(FHandle, matrix, Transform);
  827. end;
  828. procedure TCGxParameter.SetAsMatrix(const val: TMatrix4f);
  829. begin
  830. cgGLSetMatrixParameterfr(FHandle, @val);
  831. end;
  832. procedure TCGxParameter.DisableClientState;
  833. begin
  834. Assert(FVariability = CG_VARYING);
  835. cgGLDisableClientState(FHandle);
  836. end;
  837. procedure TCGxParameter.EnableClientState;
  838. begin
  839. Assert(FVariability = CG_VARYING);
  840. cgGLEnableClientState(FHandle);
  841. end;
  842. procedure TCGxParameter.SetParameterPointer(Values: TgxAffineVectorList);
  843. begin
  844. Assert(FVariability = CG_VARYING);
  845. cgGLSetParameterPointer(FHandle, 3, GL_FLOAT, 0, Values.List);
  846. end;
  847. procedure TCGxParameter.SetParameterPointer(Values: TgxVectorList);
  848. begin
  849. Assert(FVariability = CG_VARYING);
  850. cgGLSetParameterPointer(FHandle, 4, GL_FLOAT, 0, Values.List);
  851. end;
  852. // ------------------
  853. // ------------------ TCGxVertexProgram ------------------
  854. // ------------------
  855. constructor TCGxVertexProgram.Create;
  856. begin
  857. inherited;
  858. FProgramType := ptVertex;
  859. FVPProfile := vpDetectLatest;
  860. end;
  861. function TCGxVertexProgram.GetLatestProfile: TcgProfile;
  862. begin
  863. result := cgGLGetLatestProfile(CG_GL_VERTEX);
  864. end;
  865. procedure TCGxVertexProgram.SetVPProfile(v: TCgVPProfile);
  866. begin
  867. if FVPProfile = v then
  868. Exit;
  869. FVPProfile := v;
  870. case v of
  871. vp20:
  872. FProfile := CG_PROFILE_VP20;
  873. vp30:
  874. FProfile := CG_PROFILE_VP30;
  875. vp40:
  876. FProfile := CG_PROFILE_VP40;
  877. arbvp1:
  878. FProfile := CG_PROFILE_ARBVP1;
  879. end;
  880. FDetectProfile := v = vpDetectLatest;
  881. end;
  882. // ------------------
  883. // ------------------ TCGxFragmentProgram ------------------
  884. // ------------------
  885. constructor TCGxFragmentProgram.Create;
  886. begin
  887. inherited;
  888. FProgramType := ptFragment;
  889. FFPProfile := fpDetectLatest;
  890. FManageTexture := False;
  891. end;
  892. procedure TCGxFragmentProgram.SetManageTexture(const Value: boolean);
  893. begin
  894. FManageTexture := Value;
  895. if FCgContext <> nil then
  896. cgGLSetManageTextureParameters(@FCgContext, CgBoolean[FManageTexture]);
  897. // If FCgContext = nil (i.e. program not yet initialized), set it in
  898. // TCGxFragmentProgram.Initialize
  899. end;
  900. procedure TCGxFragmentProgram.Initialize;
  901. begin
  902. inherited;
  903. if FManageTexture then // ManageTexture is off by default
  904. cgGLSetManageTextureParameters(@FCgContext, CgBoolean[FManageTexture]);
  905. end;
  906. function TCGxFragmentProgram.GetLatestProfile: TcgProfile;
  907. begin
  908. result := cgGLGetLatestProfile(CG_GL_FRAGMENT);
  909. end;
  910. procedure TCGxFragmentProgram.SetFPProfile(v: TCgFPProfile);
  911. begin
  912. if FFPProfile = v then
  913. Exit;
  914. FFPProfile := v;
  915. case v of
  916. fp20:
  917. FProfile := CG_PROFILE_FP20;
  918. fp30:
  919. FProfile := CG_PROFILE_FP30;
  920. fp40:
  921. FProfile := CG_PROFILE_FP40;
  922. arbfp1:
  923. FProfile := CG_PROFILE_ARBFP1;
  924. end;
  925. FDetectProfile := v = fpDetectLatest;
  926. end;
  927. // ------------------
  928. // ------------------ TCGxCustomShader ------------------
  929. // ------------------
  930. constructor TCGxCustomShader.Create(AOwner: TComponent);
  931. begin
  932. inherited Create(AOwner);
  933. FVertexProgram := TCGxVertexProgram.Create(Self);
  934. FFragmentProgram := TCGxFragmentProgram.Create(Self);
  935. end;
  936. destructor TCGxCustomShader.Destroy;
  937. begin
  938. inherited Destroy;
  939. FVertexProgram.Free;
  940. FFragmentProgram.Free;
  941. end;
  942. procedure TCGxCustomShader.SetVertexProgram(const val: TCGxVertexProgram);
  943. begin
  944. FVertexProgram.Code := val.Code;
  945. end;
  946. procedure TCGxCustomShader.SetFragmentProgram(const val: TCGxFragmentProgram);
  947. begin
  948. FFragmentProgram.Code := val.Code;
  949. end;
  950. procedure TCGxCustomShader.SetOnApplyVertexProgram(const val: TCGxApplyEvent);
  951. begin
  952. FVertexProgram.OnApply := val;
  953. end;
  954. function TCGxCustomShader.GetOnApplyVertexProgram: TCGxApplyEvent;
  955. begin
  956. result := FVertexProgram.OnApply;
  957. end;
  958. procedure TCGxCustomShader.SetOnApplyFragmentProgram(const val: TCGxApplyEvent);
  959. begin
  960. FFragmentProgram.OnApply := val;
  961. end;
  962. function TCGxCustomShader.GetOnApplyFragmentProgram: TCGxApplyEvent;
  963. begin
  964. result := FFragmentProgram.OnApply;
  965. end;
  966. procedure TCGxCustomShader.SetOnUnApplyVertexProgram(const val: TCgUnApplyEvent);
  967. begin
  968. FVertexProgram.OnUnApply := val;
  969. end;
  970. function TCGxCustomShader.GetOnUnApplyVertexProgram: TCgUnApplyEvent;
  971. begin
  972. result := FVertexProgram.OnUnApply;
  973. end;
  974. procedure TCGxCustomShader.SetOnUnApplyFragmentProgram
  975. (const val: TCgUnApplyEvent);
  976. begin
  977. FFragmentProgram.OnUnApply := val;
  978. end;
  979. function TCGxCustomShader.GetOnUnApplyFragmentProgram: TCgUnApplyEvent;
  980. begin
  981. result := FFragmentProgram.OnUnApply;
  982. end;
  983. function TCGxCustomShader.GetOnInitialize: TCGxShaderEvent;
  984. begin
  985. result := FOnInitialize;
  986. end;
  987. procedure TCGxCustomShader.SetOnInitialize(const val: TCGxShaderEvent);
  988. begin
  989. FOnInitialize := val;
  990. end;
  991. procedure TCGxCustomShader.DoInitialize(var rci: TgxRenderContextInfo;
  992. Sender: TObject);
  993. begin
  994. if (csDesigning in ComponentState) and (not FDesignEnable) then
  995. Exit;
  996. if not ShaderSupported then
  997. begin
  998. Enabled := False;
  999. HandleFailedInitialization;
  1000. end
  1001. else
  1002. try
  1003. FVertexProgram.Initialize;
  1004. FFragmentProgram.Initialize;
  1005. if Assigned(FOnInitialize) then
  1006. FOnInitialize(Self);
  1007. except
  1008. on E: Exception do
  1009. begin
  1010. Enabled := False;
  1011. HandleFailedInitialization(E.Message);
  1012. end;
  1013. end;
  1014. end;
  1015. procedure TCGxCustomShader.DoApply(var rci: TgxRenderContextInfo;
  1016. Sender: TObject);
  1017. begin
  1018. if (csDesigning in ComponentState) and (not FDesignEnable) then
  1019. Exit;
  1020. FVertexProgram.Apply(rci, Sender);
  1021. FFragmentProgram.Apply(rci, Sender);
  1022. end;
  1023. function TCGxCustomShader.DoUnApply(var rci: TgxRenderContextInfo): boolean;
  1024. begin
  1025. if (not(csDesigning in ComponentState)) or FDesignEnable then
  1026. begin
  1027. FVertexProgram.UnApply(rci);
  1028. FFragmentProgram.UnApply(rci);
  1029. end;
  1030. result := False;
  1031. end;
  1032. procedure TCGxCustomShader.DoFinalize;
  1033. begin
  1034. FVertexProgram.Finalize;
  1035. FFragmentProgram.Finalize;
  1036. end;
  1037. procedure TCGxCustomShader.LoadShaderPrograms(const VPFilename,
  1038. FPFilename: string);
  1039. begin
  1040. VertexProgram.LoadFromFile(VPFilename);
  1041. FragmentProgram.LoadFromFile(FPFilename);
  1042. end;
  1043. function TCGxCustomShader.IsProfileSupported(Profile: TcgProfile): boolean;
  1044. begin
  1045. result := cgGLIsProfileSupported(Profile) = CG_TRUE;
  1046. end;
  1047. function TCGxCustomShader.ShaderSupported: boolean;
  1048. begin
  1049. result := True; (*(GL_ARB_shader_objects and GL_ARB_vertex_program and
  1050. GL_ARB_vertex_shader and GL_ARB_fragment_shader);*)
  1051. end;
  1052. // ------------------
  1053. // ------------------ TCGxCadencableCustomShader ------------------
  1054. // ------------------
  1055. procedure TCGxCadencableCustomShader.DoInitialize(var rci: TgxRenderContextInfo;
  1056. Sender: TObject);
  1057. begin
  1058. if FCadencer = nil then
  1059. begin
  1060. Enabled := False;
  1061. raise ECGxShaderException.CreateFmt(strErrorEx + strCadencerNotDefinedEx,
  1062. [ClassName]);
  1063. end
  1064. else
  1065. inherited;
  1066. end;
  1067. procedure TCGxCadencableCustomShader.Notification(AComponent: TComponent;
  1068. Operation: TOperation);
  1069. begin
  1070. inherited;
  1071. if (AComponent is TgxCadencer) and (Operation = opRemove) then
  1072. begin
  1073. FCadencer := nil;
  1074. Enabled := False;
  1075. end;
  1076. end;
  1077. procedure TCGxCadencableCustomShader.SetCadencer(const Value: TgxCadencer);
  1078. begin
  1079. if Value = FCadencer then
  1080. Exit;
  1081. if Value = nil then
  1082. if Enabled then
  1083. Enabled := False;
  1084. if FCadencer <> nil then
  1085. FCadencer.RemoveFreeNotification(Self);
  1086. FCadencer := Value;
  1087. if FCadencer <> nil then
  1088. FCadencer.FreeNotification(Self);
  1089. end;
  1090. initialization // ------------------------------------------------------------
  1091. // class registrations
  1092. RegisterClasses([TCGxShader, TCGxCustomShader, TCGxCadencableCustomShader,
  1093. TCGxFragmentProgram, TCGxVertexProgram, TCGxProgram]);
  1094. cgSetErrorCallBack(ErrorCallBack);
  1095. {$IFDEF OutputCompilerWarnings}
  1096. CompilerMsg := TStringList.Create;
  1097. // default WarningFilePath is set to app. path
  1098. WarningFilePath := extractfilepath(ParamStr(0));
  1099. {$ENDIF}
  1100. finalization
  1101. {$IFDEF OutputCompilerWarnings}
  1102. CompilerMsg.SaveToFile(WarningFilePath + 'CG_Warnings.txt');
  1103. CompilerMsg.Free;
  1104. {$ENDIF}
  1105. end.