GXS.MaterialScript.pas 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  1. //
  2. // The graphics engine GXScene https://github.com/glscene
  3. //
  4. unit GXS.MaterialScript;
  5. (* Material Script Batch loader for TgxMaterialLibrary for runtime *)
  6. interface
  7. {$I Stage.Defines.inc}
  8. uses
  9. System.SysUtils,
  10. System.Classes,
  11. FMX.StdCtrls,
  12. FMX.Memo,
  13. Stage.VectorTypes,
  14. Stage.Utils,
  15. GXS.Texture,
  16. Stage.TextureFormat,
  17. GXS.Graphics,
  18. GXS.ImageUtils,
  19. GXS.Color,
  20. GXS.Coordinates,
  21. GXS.Material,
  22. GXS.State;
  23. type
  24. TgxShaderItem = class(TCollectionItem)
  25. private
  26. FShader: TgxShader;
  27. FName: string;
  28. procedure SetShader(const Value: TgxShader);
  29. procedure SetName(const Value: string);
  30. protected
  31. function GetDisplayName: string; override;
  32. public
  33. constructor Create(Collection: TCollection); override;
  34. destructor Destroy; override;
  35. procedure Assign(Source: TPersistent); override;
  36. published
  37. property Shader: TgxShader read FShader write SetShader;
  38. property Name: string read FName write SetName;
  39. end;
  40. TgxShaderItems = class(TOwnedCollection)
  41. private
  42. procedure SetItems(Index: Integer; const Val: TgxShaderItem);
  43. function GetItems(Index: Integer): TgxShaderItem;
  44. public
  45. constructor Create(AOwner: TPersistent);
  46. property Items[Index: Integer]: TgxShaderItem read GetItems write SetItems; default;
  47. end;
  48. TgxMaterialLibraryItem = class(TCollectionItem)
  49. private
  50. FMaterialLibrary: TgxMaterialLibrary;
  51. FName: string;
  52. procedure SetMaterialLibrary(const Value: TgxMaterialLibrary);
  53. procedure SetName(const Value: string);
  54. protected
  55. function GetDisplayName: string; override;
  56. public
  57. constructor Create(Collection: TCollection); override;
  58. destructor Destroy; override;
  59. procedure Assign(Source: TPersistent); override;
  60. published
  61. property MaterialLibrary: TgxMaterialLibrary read FMaterialLibrary write SetMaterialLibrary;
  62. property Name: string read FName write SetName;
  63. end;
  64. TgxMaterialLibraryItems = class(TOwnedCollection)
  65. private
  66. procedure SetItems(Index: Integer; const Val: TgxMaterialLibraryItem);
  67. function GetItems(Index: Integer): TgxMaterialLibraryItem;
  68. public
  69. constructor Create(AOwner: TPersistent);
  70. property Items[Index: Integer]: TgxMaterialLibraryItem read GetItems write SetItems; default;
  71. end;
  72. TgxMaterialScripter = class(TComponent)
  73. private
  74. FShaderItems: TgxShaderItems;
  75. FMaterialLibraryItems: TgxMaterialLibraryItems;
  76. FAppend: Boolean;
  77. FOverwrite: Boolean;
  78. FScript: TStrings;
  79. FMemo: TMemo;
  80. FMaterialLibrary: TgxMaterialLibrary;
  81. Count: Longint;
  82. infini: Longint;
  83. done: Boolean;
  84. NewMat: TgxLibMaterial;
  85. tmpcoords: TgxCoordinates;
  86. tmpcolor: TgxColor;
  87. tmpcoords4: TgxCoordinates4;
  88. tmpstr: string;
  89. procedure SeTgxShaderItems(const Value: TgxShaderItems);
  90. procedure SeTgxMaterialLibraryItems(const Value: TgxMaterialLibraryItems);
  91. procedure SetAppend(const Value: Boolean);
  92. procedure SetOverwrite(const Value: Boolean);
  93. procedure SetScript(const Value: TStrings);
  94. procedure SetMaterialLibrary(const Value: TgxMaterialLibrary);
  95. procedure SetMemo(const Value: TMemo);
  96. // error checking
  97. procedure CheckError;
  98. function ClassExists(arguement: string): Boolean;
  99. function CheckRepeatDone: Boolean;
  100. // extraction functions
  101. function ExtractValue: string;
  102. procedure ExtractCoords3;
  103. procedure ExtractCoords4;
  104. procedure ExtractColors;
  105. function DeleteSpaces(Value: string): string;
  106. function SubstrExists(substr: string): Boolean;
  107. function ValueExists(Value: string): Boolean;
  108. // these are our viable scripts
  109. procedure ZMaterial;
  110. // internally called scripts for value extraction
  111. procedure XMaterial;
  112. procedure XName;
  113. procedure XShader;
  114. procedure XTexture2Name;
  115. procedure XTextureOffset;
  116. procedure XTextureScale;
  117. procedure XTexture;
  118. procedure XCompression;
  119. procedure XEnvColor;
  120. procedure XFilteringQuality;
  121. procedure XImageAlpha;
  122. procedure XImageBrightness;
  123. procedure XImageClass;
  124. procedure XImageGamma;
  125. procedure XMagFilter;
  126. procedure XMappingMode;
  127. procedure XMappingSCoordinates;
  128. procedure XMappingTCoordinates;
  129. procedure XMinFilter;
  130. procedure XNormalMapScale;
  131. procedure XTextureFormat;
  132. procedure XTextureMode;
  133. procedure XTextureWrap;
  134. procedure XBlendingMode;
  135. procedure XPolygonMode;
  136. procedure XFacingCulling;
  137. procedure XLibMaterialName;
  138. procedure XMaterialOptions;
  139. procedure XMaterialLibrary;
  140. procedure XBackProperties;
  141. procedure XBackAmbient;
  142. procedure XBackDiffuse;
  143. procedure XBackEmission;
  144. procedure XBackShininess;
  145. procedure XBackSpecular;
  146. procedure XFrontProperties;
  147. procedure XFrontAmbient;
  148. procedure XFrontDiffuse;
  149. procedure XFrontEmission;
  150. procedure XFrontShininess;
  151. procedure XFrontSpecular;
  152. procedure XPersistantImage;
  153. procedure XBlankImage;
  154. procedure XPictureFileName;
  155. procedure XPicturePX;
  156. procedure XPictureNX;
  157. procedure XPicturePY;
  158. procedure XPictureNY;
  159. procedure XPicturePZ;
  160. procedure XPictureNZ;
  161. protected
  162. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  163. public
  164. property DebugMemo: TMemo read FMemo write SetMemo;
  165. constructor Create(AOwner: TComponent); override;
  166. destructor Destroy; override;
  167. procedure CompileScript;
  168. published
  169. property Script: TStrings read FScript write SetScript;
  170. property MaterialLibrary: TgxMaterialLibrary read FMaterialLibrary write SetMaterialLibrary;
  171. property Shaders: TgxShaderItems read FShaderItems write SeTgxShaderItems;
  172. property MaterialLibraries: TgxMaterialLibraryItems read FMaterialLibraryItems write SeTgxMaterialLibraryItems;
  173. property AppendToMaterialLibrary: Boolean read FAppend write SetAppend;
  174. property OverwriteToMaterialLibrary: Boolean read FOverwrite write SetOverwrite;
  175. end;
  176. //-----------------------------------------------------------
  177. implementation
  178. //-----------------------------------------------------------
  179. procedure TgxShaderItem.SetShader(const Value: TgxShader);
  180. begin
  181. if assigned(Value) then
  182. begin
  183. FShader := Value;
  184. FName := FShader.Name;
  185. end;
  186. end;
  187. procedure TgxShaderItem.Assign(Source: TPersistent);
  188. begin
  189. if Source is TgxShaderItem then
  190. begin
  191. FShader := TgxShaderItem(Source).FShader;
  192. end;
  193. inherited Destroy;
  194. end;
  195. constructor TgxShaderItem.Create(Collection: TCollection);
  196. begin
  197. inherited Create(Collection);
  198. FName := 'Shader';
  199. end;
  200. destructor TgxShaderItem.Destroy;
  201. begin
  202. inherited Destroy;
  203. end;
  204. function TgxShaderItem.GetDisplayName : String;
  205. begin
  206. if FName = '' then
  207. Result:='Shader'
  208. else
  209. Result := FName;
  210. end;
  211. { TgxShaderItems }
  212. constructor TgxShaderItems.Create(AOwner: TPersistent);
  213. begin
  214. inherited Create(AOwner, TgxShaderItem);
  215. end;
  216. function TgxShaderItems.GetItems(index: Integer): TgxShaderItem;
  217. begin
  218. Result:=TgxShaderItem(inherited Items[index]);
  219. end;
  220. procedure TgxShaderItems.SetItems(index: Integer; const val: TgxShaderItem);
  221. begin
  222. inherited Items[index]:=val;
  223. end;
  224. procedure TgxMaterialScripter.SeTgxShaderItems(const Value: TgxShaderItems);
  225. begin
  226. FShaderItems.Assign(Value);
  227. end;
  228. procedure TgxShaderItem.SetName(const Value: String);
  229. begin
  230. FName := Value;
  231. end;
  232. procedure TgxMaterialScripter.CompileScript;
  233. begin
  234. done := false;
  235. NewMat := nil;
  236. count := 0;
  237. infini := 0;
  238. tmpcoords := nil;
  239. tmpcoords4 := nil;
  240. tmpcolor := nil;
  241. tmpstr := '';
  242. repeat
  243. inc(count);
  244. if pos('{',FScript.Strings[count]) > 0 then
  245. begin
  246. if substrexists('material') then ZMaterial;
  247. end;
  248. checkerror;
  249. until checkrepeatdone;
  250. end;
  251. procedure TgxMaterialScripter.SetMaterialLibrary(
  252. const Value: TgxMaterialLibrary);
  253. begin
  254. if FMaterialLibrary <> nil then FMaterialLibrary.RemoveFreeNotification(Self);
  255. FMaterialLibrary := Value;
  256. if FMaterialLibrary <> nil then FMaterialLibrary.FreeNotification(Self);
  257. end;
  258. procedure TgxMaterialScripter.SetMemo(const Value: TMemo);
  259. begin
  260. if FMemo <> nil then FMemo.RemoveFreeNotification(Self);
  261. FMemo := Value;
  262. if FMemo <> nil then FMemo.FreeNotification(Self);
  263. end;
  264. procedure TgxMaterialScripter.SetScript(const Value: TStrings);
  265. begin
  266. if assigned(value) then
  267. FScript.Assign(Value);
  268. end;
  269. procedure TgxMaterialScripter.CheckError;
  270. begin
  271. if count >= FScript.Count then done := true;
  272. if done then raise exception.Create('User Error : No closing "}"');
  273. inc(infini);
  274. if infini > 1280000 then
  275. begin
  276. raise exception.Create('Internal Error : Infinate Loop');
  277. done := true;
  278. exit;
  279. end;
  280. end;
  281. function TgxMaterialScripter.CheckRepeatDone: boolean;
  282. begin
  283. checkrepeatdone := false;
  284. if pos('}',FScript.Strings[count]) > 0 then
  285. begin
  286. checkrepeatdone := true;
  287. inc(count);
  288. end;
  289. if done then checkrepeatdone := true;
  290. end;
  291. function TgxMaterialScripter.ClassExists(arguement: string): boolean;
  292. var temp : string;
  293. i : word;
  294. begin
  295. classexists := false;
  296. if (pos(uppercase(arguement), uppercase(FScript.Strings[count])) > 0) and // check if there is an arguement
  297. (pos('=', FScript.Strings[count]) > pos(uppercase(arguement), uppercase(FScript.Strings[count])))and // check if it is before '='
  298. (pos('=', FScript.Strings[count]) > 0) then // check if there even is a '='
  299. begin
  300. temp := FScript.Strings[count];
  301. for i := 0 to length(temp) do
  302. if pos(' ', temp) = 1 then
  303. delete(temp,1,1);
  304. if pos(uppercase(arguement),uppercase(temp)) = 1 then
  305. if (temp[length(arguement) + 1] = ' ') or (temp[length(arguement) + 1] = '=') then
  306. begin
  307. classexists := true;
  308. if assigned(FMemo) then Fmemo.Lines.Add('Stage is at : ' + arguement);
  309. end;
  310. end;
  311. end;
  312. function TgxMaterialScripter.SubstrExists(substr: string): boolean;
  313. begin
  314. if pos(uppercase(substr),uppercase(FScript.Strings[count])) > 0 then result := true
  315. else
  316. result := false;
  317. end;
  318. constructor TgxMaterialScripter.Create(AOwner: TComponent);
  319. begin
  320. inherited Create(AOwner);
  321. FScript := TStringList.Create;
  322. FShaderItems:=TgxShaderItems.Create(Self);
  323. FMaterialLibraryItems:=TgxMaterialLibraryItems.Create(Self);
  324. FAppend := true;
  325. FOverwrite := false;
  326. end;
  327. function TgxMaterialScripter.DeleteSpaces(value: string): string;
  328. var i : byte;
  329. begin
  330. result := value;
  331. for i := 0 to length(result) do
  332. if pos(' ',result) > 0 then
  333. delete(result,pos(' ',result), 1);
  334. end;
  335. destructor TgxMaterialScripter.Destroy;
  336. begin
  337. FShaderItems.Free;
  338. FMaterialLibraryItems.Free;
  339. FScript.Free;
  340. inherited Destroy;
  341. end;
  342. procedure TgxMaterialScripter.ExtractColors;
  343. var val : string;
  344. begin
  345. val := Extractvalue;
  346. if pos('(',val) > 0 then
  347. begin
  348. tmpcolor.Alpha := StrToFloatDef(copy(val, pos('(',val) + 1, pos(';',val) - 2));
  349. delete(val,1,pos(';',val));
  350. tmpcolor.Red := StrToFloatDef(copy(val, 1, pos(';',val) - 1));
  351. delete(val,1,pos(';',val));
  352. tmpcolor.Green := StrToFloatDef(copy(val, 1, pos(';',val) - 1));
  353. delete(val,1,pos(';',val));
  354. tmpcolor.Blue := StrToFloatDef(copy(val, 1, pos(')',val) - 1));
  355. end;
  356. end;
  357. procedure TgxMaterialScripter.ExtractCoords3;
  358. var val : string;
  359. begin
  360. val := Extractvalue;
  361. if pos('(',val) > 0 then
  362. begin
  363. tmpcoords.X := StrToFloatDef(copy(val, pos('(',val) + 1, pos(';',val) - 2));
  364. delete(val,1,pos(';',val));
  365. tmpcoords.Y := StrToFloatDef(copy(val, 1, pos(';',val) - 1));
  366. delete(val,1,pos(';',val));
  367. tmpcoords.Z := StrToFloatDef(copy(val, 1, pos(')',val) - 1));
  368. end;
  369. end;
  370. procedure TgxMaterialScripter.ExtractCoords4;
  371. var val : string;
  372. begin
  373. val := Extractvalue;
  374. if pos('(',val) > 0 then
  375. begin
  376. tmpcoords4.W := StrToFloatDef(copy(val, pos('(',val) + 1, pos(';',val) - 2));
  377. delete(val,1,pos(';',val));
  378. tmpcoords4.X := StrToFloatDef(copy(val, 1, pos(';',val) - 1));
  379. delete(val,1,pos(';',val));
  380. tmpcoords4.Y := StrToFloatDef(copy(val, 1, pos(';',val) - 1));
  381. delete(val,1,pos(';',val));
  382. tmpcoords4.Z := StrToFloatDef(copy(val, 1, pos(')',val) - 1));
  383. end;
  384. end;
  385. function TgxMaterialScripter.ExtractValue: string;
  386. begin
  387. extractvalue := copy(FScript.Strings[count], pos('=',FScript.Strings[count]) + 1, length(FScript.Strings[count]) - pos('=',FScript.Strings[count]));
  388. end;
  389. procedure TgxMaterialScripter.XPersistantImage;
  390. begin
  391. if classexists('file') then
  392. begin
  393. if (extractvalue <> '') and (fileexists(extractvalue)) then
  394. begin
  395. with NewMat.Material.Texture.Image as TgxPersistentImage do
  396. LoadFromFile(extractvalue);
  397. NewMat.Material.Texture.Disabled := false;
  398. if assigned(FMemo) then FMemo.Lines.Add('File loaded : ' + extractvalue);
  399. end;
  400. end;
  401. end;
  402. procedure TgxMaterialScripter.XBlankImage;
  403. begin
  404. if classexists('file') then
  405. begin
  406. if (extractvalue <> '') and (fileexists(extractvalue)) then
  407. begin
  408. with NewMat.Material.Texture.Image as TgxBlankImage do // heres the difference
  409. LoadFromFile(extractvalue);
  410. NewMat.Material.Texture.Disabled := false;
  411. if assigned(FMemo) then FMemo.Lines.Add('File loaded : ' + extractvalue);
  412. end;
  413. end;
  414. end;
  415. procedure TgxMaterialScripter.XPictureFileName;
  416. begin
  417. if classexists('picturefilename') then
  418. with NewMat.Material.Texture.Image as TgxPicFileImage do
  419. if fileexists(extractvalue) then
  420. begin
  421. picturefilename := extractvalue;
  422. NewMat.Material.Texture.Disabled := false;
  423. end;
  424. end;
  425. procedure TgxMaterialScripter.XPictureNX;
  426. begin
  427. if classexists('picturenx') then
  428. if fileexists(extractvalue) then
  429. with NewMat.Material.Texture.Image as TgxCubeMapImage do
  430. Picture[cmtNX].Bitmap.LoadFromFile(extractvalue);
  431. end;
  432. procedure TgxMaterialScripter.XPictureNY;
  433. begin
  434. if classexists('pictureny') then
  435. if fileexists(extractvalue) then
  436. with NewMat.Material.Texture.Image as TgxCubeMapImage do
  437. Picture[cmtNY].Bitmap.LoadFromFile(extractvalue);
  438. end;
  439. procedure TgxMaterialScripter.XPictureNZ;
  440. begin
  441. if classexists('picturenz') then
  442. if fileexists(extractvalue) then
  443. with NewMat.Material.Texture.Image as TgxCubeMapImage do
  444. Picture[cmtNZ].Bitmap.LoadFromFile(extractvalue);
  445. end;
  446. procedure TgxMaterialScripter.XPicturePX;
  447. begin
  448. if classexists('picturepx') then
  449. if fileexists(extractvalue) then
  450. with NewMat.Material.Texture.Image as TgxCubeMapImage do
  451. Picture[cmtPX].Bitmap.LoadFromFile(extractvalue);
  452. end;
  453. procedure TgxMaterialScripter.XPicturePY;
  454. begin
  455. if classexists('picturepy') then
  456. if fileexists(extractvalue) then
  457. with NewMat.Material.Texture.Image as TgxCubeMapImage do
  458. Picture[cmtPY].Bitmap.LoadFromFile(extractvalue);
  459. end;
  460. procedure TgxMaterialScripter.XPicturePZ;
  461. begin
  462. if classexists('picturepz') then
  463. if fileexists(extractvalue) then
  464. with NewMat.Material.Texture.Image as TgxCubeMapImage do
  465. Picture[cmtPZ].Bitmap.LoadFromFile(extractvalue);
  466. end;
  467. function TgxMaterialScripter.ValueExists(value: string): boolean;
  468. begin
  469. if uppercase(tmpstr) = uppercase(value) then result := true
  470. else
  471. result := false;
  472. end;
  473. procedure TgxMaterialScripter.XMaterialLibrary;
  474. var i : word;
  475. begin
  476. if classexists('materiallibrary') then
  477. if MaterialLibraries.count > 0 then
  478. for i := 0 to MaterialLibraries.Count - 1 do
  479. if assigned(MaterialLibraries.Items[i].MaterialLibrary) then
  480. if uppercase(MaterialLibraries.Items[i].MaterialLibrary.Name) = uppercase(extractvalue) then
  481. NewMat.Material.MaterialLibrary := MaterialLibraries.Items[i].MaterialLibrary;
  482. end;
  483. procedure TgxMaterialScripter.XShader;
  484. var i : word;
  485. begin
  486. if classexists('shader') then
  487. if Shaders.count > 0 then
  488. for i := 0 to Shaders.Count - 1 do
  489. if assigned(Shaders.Items[i].Shader) then
  490. if uppercase(Shaders.Items[i].Shader.Name) = uppercase(extractvalue) then
  491. NewMat.Shader := Shaders.Items[i].Shader;
  492. end;
  493. procedure TgxMaterialScripter.ZMaterial;
  494. var i : byte;
  495. exists : boolean;
  496. begin
  497. if assigned(FMaterialLibrary) then
  498. begin
  499. NewMat := FMaterialLibrary.Materials.Add;
  500. repeat
  501. inc(count);
  502. XMaterial;
  503. if pos('{',FScript.Strings[count]) > 0 then
  504. for i := 0 to 2 do // need repair : something went wrong, and now we have to check 3 times over :/
  505. begin
  506. XTexture;
  507. XBackProperties;
  508. XFrontProperties;
  509. end;
  510. checkerror;
  511. until checkrepeatdone;
  512. // now we use append and overwrite settings to find out what is what
  513. tmpstr := NewMat.Name;
  514. delete(tmpstr,1,3); // removes the "TAG" not to confuse the system
  515. exists := false;
  516. if FMaterialLibrary.Materials.Count > 0 then
  517. for i := 0 to FMaterialLibrary.Materials.Count - 1 do
  518. if tmpstr = FMaterialLibrary.Materials.Items[i].Name then
  519. exists := true;
  520. if Exists then // does exist
  521. begin
  522. if FOverwrite then
  523. begin
  524. FMaterialLibrary.Materials.Delete(FMaterialLibrary.LibMaterialByName(tmpstr).Index);
  525. NewMat.Name := tmpstr;
  526. end
  527. else
  528. if FAppend then
  529. begin
  530. NewMat.Free;
  531. end;
  532. end
  533. else // doesn't exist
  534. begin
  535. NewMat.Name := tmpstr;
  536. if not FAppend then
  537. NewMat.Free;
  538. end;
  539. end;
  540. end;
  541. ///////////////////////////
  542. // extraction procedures //
  543. ///////////////////////////
  544. procedure TgxMaterialScripter.XBackAmbient;
  545. begin
  546. if classexists('ambient') then
  547. begin
  548. tmpcolor := NewMat.Material.BackProperties.Ambient;
  549. extractcolors;
  550. NewMat.Material.BackProperties.Ambient := tmpcolor;
  551. end;
  552. end;
  553. procedure TgxMaterialScripter.XBackDiffuse;
  554. begin
  555. if classexists('diffuse') then
  556. begin
  557. tmpcolor := NewMat.Material.BackProperties.Diffuse;
  558. extractcolors;
  559. NewMat.Material.BackProperties.Diffuse := tmpcolor;
  560. end;
  561. end;
  562. procedure TgxMaterialScripter.XBackEmission;
  563. begin
  564. if classexists('emission') then
  565. begin
  566. tmpcolor := NewMat.Material.BackProperties.Emission;
  567. extractcolors;
  568. NewMat.Material.BackProperties.Emission := tmpcolor;
  569. end;
  570. end;
  571. procedure TgxMaterialScripter.XBackShininess;
  572. begin
  573. if classexists('shininess') then
  574. if extractvalue <> '' then
  575. NewMat.Material.BackProperties.Shininess := strtoint(extractvalue);
  576. end;
  577. procedure TgxMaterialScripter.XBackSpecular;
  578. begin
  579. if classexists('specular') then
  580. begin
  581. tmpcolor := NewMat.Material.BackProperties.Specular;
  582. extractcolors;
  583. NewMat.Material.BackProperties.Specular := tmpcolor;
  584. end;
  585. end;
  586. procedure TgxMaterialScripter.XBlendingMode;
  587. begin
  588. if classexists('blendingmode') then
  589. begin
  590. tmpstr := extractvalue;
  591. if valueexists('bmOpaque') then Newmat.Material.BlendingMode := bmOpaque;
  592. if valueexists('bmTransparency') then Newmat.Material.BlendingMode := bmTransparency;
  593. if valueexists('bmAdditive') then Newmat.Material.BlendingMode := bmAdditive;
  594. if valueexists('bmAlphaTest100') then Newmat.Material.BlendingMode := bmAlphaTest100;
  595. if valueexists('bmAlphaTest50') then Newmat.Material.BlendingMode := bmAlphaTest50;
  596. end;
  597. end;
  598. procedure TgxMaterialScripter.XPolygonMode;
  599. begin
  600. if classexists('polygonmode') then
  601. begin
  602. tmpstr := extractvalue;
  603. if valueexists('pmFill') then Newmat.Material.PolygonMode := pmFill;
  604. if valueexists('pmLines') then Newmat.Material.PolygonMode := pmLines;
  605. if valueexists('pmPoints') then Newmat.Material.PolygonMode := pmPoints;
  606. end;
  607. end;
  608. procedure TgxMaterialScripter.XCompression;
  609. begin
  610. if classexists('compression') then
  611. begin
  612. tmpstr := extractvalue;
  613. if valueexists('tcDefault') then Newmat.Material.Texture.Compression := tcDefault;
  614. if valueexists('tcHighQuality') then Newmat.Material.Texture.Compression := tcHighQuality;
  615. if valueexists('tcHighSpeed') then Newmat.Material.Texture.Compression := tcHighSpeed;
  616. if valueexists('tcNone') then Newmat.Material.Texture.Compression := tcNone;
  617. if valueexists('tcStandard') then Newmat.Material.Texture.Compression := tcStandard;
  618. end;
  619. end;
  620. procedure TgxMaterialScripter.XEnvColor;
  621. begin
  622. if classexists('envcolor') then
  623. begin
  624. tmpcolor := NewMat.Material.Texture.EnvColor;
  625. extractcolors;
  626. NewMat.Material.Texture.EnvColor := tmpcolor;
  627. end;
  628. end;
  629. procedure TgxMaterialScripter.XFacingCulling;
  630. begin
  631. if classexists('faceculling') then
  632. begin
  633. tmpstr := extractvalue;
  634. if valueexists('fcBufferDefault') then Newmat.Material.FaceCulling := fcBufferDefault;
  635. if valueexists('fcCull') then Newmat.Material.FaceCulling := fcCull;
  636. if valueexists('fcNoCull') then Newmat.Material.FaceCulling := fcNoCull;
  637. end;
  638. end;
  639. procedure TgxMaterialScripter.XFilteringQuality;
  640. begin
  641. if classexists('filteringquality') then
  642. begin
  643. tmpstr := extractvalue;
  644. if valueexists('tfIsotropic') then Newmat.Material.Texture.FilteringQuality := tfIsotropic;
  645. if valueexists('tfAnisotropic') then Newmat.Material.Texture.FilteringQuality := tfAnisotropic;
  646. end;
  647. end;
  648. procedure TgxMaterialScripter.XfrontAmbient;
  649. begin
  650. if classexists('ambient') then
  651. begin
  652. tmpcolor := NewMat.Material.frontProperties.Ambient;
  653. extractcolors;
  654. NewMat.Material.frontProperties.Ambient := tmpcolor;
  655. end;
  656. end;
  657. procedure TgxMaterialScripter.XfrontDiffuse;
  658. begin
  659. if classexists('diffuse') then
  660. begin
  661. tmpcolor := NewMat.Material.frontProperties.Diffuse;
  662. extractcolors;
  663. NewMat.Material.frontProperties.Diffuse := tmpcolor;
  664. end;
  665. end;
  666. procedure TgxMaterialScripter.XfrontEmission;
  667. begin
  668. if classexists('emission') then
  669. begin
  670. tmpcolor := NewMat.Material.frontProperties.Emission;
  671. extractcolors;
  672. NewMat.Material.frontProperties.Emission := tmpcolor;
  673. end;
  674. end;
  675. procedure TgxMaterialScripter.XfrontShininess;
  676. begin
  677. if classexists('shininess') then
  678. if extractvalue <> '' then
  679. NewMat.Material.frontProperties.Shininess := strtoint(extractvalue);
  680. end;
  681. procedure TgxMaterialScripter.XfrontSpecular;
  682. begin
  683. if classexists('specular') then
  684. begin
  685. tmpcolor := NewMat.Material.frontProperties.Specular;
  686. extractcolors;
  687. NewMat.Material.frontProperties.Specular := tmpcolor;
  688. end;
  689. end;
  690. procedure TgxMaterialScripter.XImageAlpha;
  691. begin
  692. if classexists('imagealpha') then
  693. begin
  694. tmpstr := extractvalue;
  695. if valueexists('tiaDefault') then Newmat.Material.Texture.ImageAlpha := tiaDefault;
  696. if valueexists('tiaInverseLuminance') then Newmat.Material.Texture.ImageAlpha := tiaInverseLuminance;
  697. if valueexists('tiaInverseLuminanceSqrt') then Newmat.Material.Texture.ImageAlpha := tiaInverseLuminanceSqrt;
  698. if valueexists('tiaLuminance') then Newmat.Material.Texture.ImageAlpha := tiaLuminance;
  699. if valueexists('tiaLuminanceSqrt') then Newmat.Material.Texture.ImageAlpha := tiaLuminanceSqrt;
  700. if valueexists('tiaOpaque') then Newmat.Material.Texture.ImageAlpha := tiaOpaque;
  701. if valueexists('tiaSuperBlackTransparent') then Newmat.Material.Texture.ImageAlpha := tiaSuperBlackTransparent;
  702. if valueexists('tiaTopLeftPointColorTransparent') then Newmat.Material.Texture.ImageAlpha := tiaTopLeftPointColorTransparent;
  703. if valueexists('tiaAlphaFromIntensity') then Newmat.Material.Texture.ImageAlpha := tiaAlphaFromIntensity;
  704. end;
  705. end;
  706. procedure TgxMaterialScripter.XImageBrightness;
  707. begin
  708. if classexists('imagebrightness') then
  709. if extractvalue <> '' then
  710. NewMat.Material.Texture.ImageBrightness := StrToFloatDef(extractvalue);
  711. end;
  712. procedure TgxMaterialScripter.XImageGamma;
  713. begin
  714. if classexists('imagegamma') then
  715. if extractvalue <> '' then
  716. NewMat.Material.Texture.ImageGamma := StrToFloatDef(extractvalue);
  717. end;
  718. procedure TgxMaterialScripter.XLibMaterialName;
  719. begin
  720. if classexists('libmaterialname') then NewMat.Material.LibMaterialName := extractvalue;
  721. end;
  722. procedure TgxMaterialScripter.XMagFilter;
  723. begin
  724. if classexists('magfilter') then
  725. begin
  726. tmpstr := extractvalue;
  727. if valueexists('maLinear') then Newmat.Material.Texture.MagFilter := maLinear;
  728. if valueexists('maNearest') then Newmat.Material.Texture.MagFilter := maNearest;
  729. end;
  730. end;
  731. procedure TgxMaterialScripter.XMappingMode;
  732. begin
  733. if classexists('mappingmode') then
  734. begin
  735. tmpstr := extractvalue;
  736. if valueexists('tmmUser') then Newmat.Material.Texture.MappingMode := tmmUser;
  737. if valueexists('tmmCubeMapCamera') then Newmat.Material.Texture.MappingMode := tmmCubeMapCamera;
  738. if valueexists('tmmCubeMapLight0') then Newmat.Material.Texture.MappingMode := tmmCubeMapLight0;
  739. if valueexists('tmmCubeMapNormal') then Newmat.Material.Texture.MappingMode := tmmCubeMapNormal;
  740. if valueexists('tmmCubeMapReflection') then Newmat.Material.Texture.MappingMode := tmmCubeMapReflection;
  741. if valueexists('tmmEyeLinear') then Newmat.Material.Texture.MappingMode := tmmEyeLinear;
  742. if valueexists('tmmObjectLinear') then Newmat.Material.Texture.MappingMode := tmmObjectLinear;
  743. if valueexists('tmmSphere') then Newmat.Material.Texture.MappingMode := tmmSphere;
  744. end;
  745. end;
  746. procedure TgxMaterialScripter.XMappingSCoordinates;
  747. begin
  748. if classexists('mappingscoordinates') then
  749. begin
  750. tmpcoords4 := NewMat.Material.Texture.MappingSCoordinates;
  751. extractcoords4;
  752. NewMat.Material.Texture.MappingSCoordinates := tmpcoords4;
  753. end;
  754. end;
  755. procedure TgxMaterialScripter.XMappingTCoordinates;
  756. begin
  757. if classexists('mappingtcoordinates') then
  758. begin
  759. tmpcoords4 := NewMat.Material.Texture.MappingTCoordinates;
  760. extractcoords4;
  761. NewMat.Material.Texture.MappingTCoordinates := tmpcoords4;
  762. end;
  763. end;
  764. procedure TgxMaterialScripter.XMaterialOptions;
  765. var a,b : boolean;
  766. begin
  767. if classexists('materialoptions') then
  768. begin
  769. a := false;
  770. b := false;
  771. tmpstr := extractvalue;
  772. if uppercase(copy(tmpstr, pos('[',tmpstr) + 1, pos(',',tmpstr) - 2)) = uppercase('true') then a := true
  773. else
  774. if uppercase(copy(tmpstr, pos('[',tmpstr) + 1, pos(',',tmpstr) - 2)) = uppercase('false') then a := false;
  775. delete(tmpstr,1,pos(',',tmpstr));
  776. if uppercase(copy(tmpstr, 1, pos(']',tmpstr) - 1)) = uppercase('true') then b := true
  777. else
  778. if uppercase(copy(tmpstr, 1, pos(']',tmpstr) - 1)) = uppercase('false') then b := false;
  779. if a then NewMat.Material.MaterialOptions := NewMat.Material.MaterialOptions + [moIgnoreFog];
  780. if b then NewMat.Material.MaterialOptions := NewMat.Material.MaterialOptions + [moNoLighting];
  781. end;
  782. end;
  783. procedure TgxMaterialScripter.XMinFilter;
  784. begin
  785. if classexists('minfilter') then
  786. begin
  787. tmpstr := extractvalue;
  788. if valueexists('miLinearMipmapLinear') then Newmat.Material.Texture.MinFilter := miLinearMipmapLinear;
  789. if valueexists('miLinearMipmapNearest') then Newmat.Material.Texture.MinFilter := miLinearMipmapNearest;
  790. if valueexists('miNearest') then Newmat.Material.Texture.MinFilter := miNearest;
  791. if valueexists('miNearestMipmapLinear') then Newmat.Material.Texture.MinFilter := miNearestMipmapLinear;
  792. if valueexists('miNearestMipmapNearest') then Newmat.Material.Texture.MinFilter := miNearestMipmapNearest;
  793. if valueexists('miLinear') then Newmat.Material.Texture.MinFilter := miLinear;
  794. end;
  795. end;
  796. procedure TgxMaterialScripter.XName;
  797. begin
  798. if classexists('name') then NewMat.Name := 'TAG' + Extractvalue; // we gonna use for appending and such, quick fix style
  799. end;
  800. procedure TgxMaterialScripter.XNormalMapScale;
  801. begin
  802. if classexists('normalmapscale') then
  803. if extractvalue <> '' then
  804. NewMat.Material.Texture.NormalMapScale := StrToFloatDef(extractvalue);
  805. end;
  806. procedure TgxMaterialScripter.XTexture2Name;
  807. begin
  808. if classexists('texture2name') then NewMat.Texture2Name := ExtractValue;
  809. end;
  810. procedure TgxMaterialScripter.XTextureFormat;
  811. begin
  812. if classexists('textureformat') then
  813. begin
  814. tmpstr := extractvalue;
  815. if valueexists('tfDefault') then Newmat.Material.Texture.TextureFormat := tfDefault;
  816. if valueexists('tfIntensity') then Newmat.Material.Texture.TextureFormat := tfIntensity;
  817. if valueexists('tfLuminance') then Newmat.Material.Texture.TextureFormat := tfLuminance;
  818. if valueexists('tfLuminanceAlpha') then Newmat.Material.Texture.TextureFormat := tfLuminanceAlpha;
  819. if valueexists('tfNormalMap') then Newmat.Material.Texture.TextureFormat := tfNormalMap;
  820. if valueexists('tfRGB') then Newmat.Material.Texture.TextureFormat := tfRGB;
  821. if valueexists('tfRGB16') then Newmat.Material.Texture.TextureFormat := tfRGB16;
  822. if valueexists('tfRGBA') then Newmat.Material.Texture.TextureFormat := tfRGBA;
  823. if valueexists('tfRGBA16') then Newmat.Material.Texture.TextureFormat := tfRGBA16;
  824. if valueexists('tfAlpha') then Newmat.Material.Texture.TextureFormat := tfAlpha;
  825. end;
  826. end;
  827. procedure TgxMaterialScripter.XTextureMode;
  828. begin
  829. if classexists('texturemode') then
  830. begin
  831. tmpstr := extractvalue;
  832. if valueexists('tmDecal') then Newmat.Material.Texture.TextureMode := tmDecal;
  833. if valueexists('tmModulate') then Newmat.Material.Texture.TextureMode := tmModulate;
  834. if valueexists('tmReplace') then Newmat.Material.Texture.TextureMode := tmReplace;
  835. if valueexists('tmBlend') then Newmat.Material.Texture.TextureMode := tmBlend;
  836. end;
  837. end;
  838. procedure TgxMaterialScripter.XTextureOffset;
  839. begin
  840. if classexists('textureoffset') then // i hate this, delphi doesn't allow var object reference for procs
  841. begin
  842. tmpcoords := Newmat.TextureOffset;
  843. extractcoords3;
  844. Newmat.TextureOffset := tmpcoords;
  845. end;
  846. end;
  847. procedure TgxMaterialScripter.XTextureScale;
  848. begin
  849. if classexists('texturescale') then
  850. begin
  851. tmpcoords := Newmat.TextureScale;
  852. extractcoords3;
  853. NewMat.TextureScale := tmpcoords;
  854. end;
  855. end;
  856. procedure TgxMaterialScripter.XTextureWrap;
  857. begin
  858. if classexists('texturewrap') then
  859. begin
  860. tmpstr := extractvalue;
  861. if valueexists('twBoth') then Newmat.Material.Texture.TextureWrap := twBoth;
  862. if valueexists('twHorizontal') then Newmat.Material.Texture.TextureWrap := twHorizontal;
  863. if valueexists('twNone') then Newmat.Material.Texture.TextureWrap := twNone;
  864. if valueexists('twVertical') then Newmat.Material.Texture.TextureWrap := twVertical;
  865. end;
  866. end;
  867. ///////////////////////////////////////
  868. // sub routines : substr{arguements} //
  869. ///////////////////////////////////////
  870. procedure TgxMaterialScripter.XTexture;
  871. begin
  872. if substrexists('texture') then
  873. begin
  874. if assigned(FMemo) then FMemo.Lines.Add('texture');
  875. repeat
  876. inc(count);
  877. XCompression;
  878. XEnvColor;
  879. XFilteringQuality;
  880. XImageAlpha;
  881. XImageBrightness;
  882. XImageClass;
  883. XImageGamma;
  884. XMagFilter;
  885. XMappingMode;
  886. XMappingSCoordinates;
  887. XMappingTCoordinates;
  888. XMinFilter;
  889. XNormalMapScale;
  890. XTextureFormat;
  891. XTextureMode;
  892. XTextureWrap;
  893. checkerror;
  894. until checkrepeatdone;
  895. end;
  896. end;
  897. procedure TgxMaterialScripter.XMaterial;
  898. begin
  899. XName;
  900. XShader;
  901. XTexture2Name;
  902. XTextureOffset;
  903. XTextureScale;
  904. XMaterialOptions;
  905. XLibMaterialName;
  906. XBlendingMode;
  907. XPolygonMode;
  908. XFacingCulling;
  909. XMaterialLibrary;
  910. end;
  911. procedure TgxMaterialScripter.XfrontProperties;
  912. begin
  913. if substrexists('frontProperties') then
  914. begin
  915. if assigned(FMemo) then FMemo.Lines.Add('frontproperties');
  916. repeat
  917. inc(count);
  918. XfrontAmbient;
  919. XfrontDiffuse;
  920. XfrontEmission;
  921. XfrontShininess;
  922. XfrontSpecular;
  923. checkerror;
  924. until checkrepeatdone;
  925. end;
  926. end;
  927. procedure TgxMaterialScripter.XImageClass; // reckon this will be most difficult to get right
  928. begin
  929. if classexists('imageclassname') then
  930. begin
  931. tmpstr := extractvalue;
  932. tmpstr := deletespaces(tmpstr);
  933. if valueexists('persistentimage{') then // loadfromfile
  934. repeat
  935. inc(count);
  936. Newmat.Material.Texture.ImageClassName := TgxPersistentImage.ClassName;
  937. XPersistantImage;
  938. checkerror;
  939. until checkrepeatdone;
  940. if valueexists('blankimage{') then // loadfromfile
  941. repeat
  942. inc(count);
  943. Newmat.Material.Texture.ImageClassName := TgxBlankImage.ClassName;
  944. XBlankImage;
  945. checkerror;
  946. until checkrepeatdone;
  947. if valueexists('picfileimage{') then //picturefilename
  948. repeat
  949. inc(count);
  950. Newmat.Material.Texture.ImageClassName := TgxPicFileImage.ClassName;
  951. XPictureFilename;
  952. checkerror;
  953. until checkrepeatdone;
  954. if valueexists('cubemapimage{') then // px, nx, py, ny, pz, nz
  955. repeat
  956. inc(count);
  957. Newmat.Material.Texture.ImageClassName := TgxCubeMapImage.ClassName;
  958. XPicturePX;
  959. XPictureNX;
  960. XPicturePY;
  961. XPictureNY;
  962. XPicturePZ;
  963. XPictureNZ;
  964. NewMat.Material.Texture.Disabled := false;
  965. checkerror;
  966. until checkrepeatdone;
  967. // procedural noise not supported by GXS.Texture yet
  968. end;
  969. end;
  970. procedure TgxMaterialScripter.XBackProperties;
  971. begin
  972. if substrexists('BackProperties') then
  973. begin
  974. if assigned(FMemo) then FMemo.Lines.Add('backproperties');
  975. repeat
  976. inc(count);
  977. XBackAmbient;
  978. XBackDiffuse;
  979. XBackEmission;
  980. XBackShininess;
  981. XBackSpecular;
  982. checkerror;
  983. until checkrepeatdone;
  984. end;
  985. end;
  986. { TgxMaterialLibraryItems }
  987. constructor TgxMaterialLibraryItems.Create(AOwner: TPersistent);
  988. begin
  989. inherited Create(AOwner, TgxMaterialLibraryItem);
  990. end;
  991. function TgxMaterialLibraryItems.GetItems(index: Integer): TgxMaterialLibraryItem;
  992. begin
  993. Result:=TgxMaterialLibraryItem(inherited Items[index]);
  994. end;
  995. procedure TgxMaterialLibraryItems.SetItems(index: Integer;
  996. const val: TgxMaterialLibraryItem);
  997. begin
  998. inherited Items[index]:=val;
  999. end;
  1000. { TgxMaterialLibraryItem }
  1001. procedure TgxMaterialLibraryItem.Assign(Source: TPersistent);
  1002. begin
  1003. if Source is TgxMaterialLibraryItem then
  1004. begin
  1005. FMaterialLibrary := TgxMaterialLibraryItem(Source).FMaterialLibrary;
  1006. end;
  1007. inherited Destroy;
  1008. end;
  1009. constructor TgxMaterialLibraryItem.Create(Collection: TCollection);
  1010. begin
  1011. inherited Create(Collection);
  1012. FName := 'MaterialLibrary';
  1013. end;
  1014. destructor TgxMaterialLibraryItem.Destroy;
  1015. begin
  1016. inherited Destroy;
  1017. end;
  1018. function TgxMaterialLibraryItem.GetDisplayName: String;
  1019. begin
  1020. if FName = '' then
  1021. Result:='MaterialLibrary'
  1022. else
  1023. Result := FName;
  1024. end;
  1025. procedure TgxMaterialLibraryItem.SetMaterialLibrary(
  1026. const Value: TgxMaterialLibrary);
  1027. begin
  1028. if assigned(Value) then
  1029. begin
  1030. FMaterialLibrary := Value;
  1031. FName := FMaterialLibrary.Name;
  1032. end;
  1033. end;
  1034. procedure TgxMaterialLibraryItem.SetName(const Value: String);
  1035. begin
  1036. FName := Value;
  1037. end;
  1038. procedure TgxMaterialScripter.SeTgxMaterialLibraryItems(
  1039. const Value: TgxMaterialLibraryItems);
  1040. begin
  1041. FMaterialLibraryItems.Assign(Value);
  1042. end;
  1043. procedure TgxMaterialScripter.SetAppend(const Value: boolean);
  1044. begin
  1045. FAppend := Value;
  1046. end;
  1047. procedure TgxMaterialScripter.SetOverwrite(const Value: boolean);
  1048. begin
  1049. FOverwrite := Value;
  1050. end;
  1051. procedure TgxMaterialScripter.Notification(AComponent: TComponent;
  1052. Operation: TOperation);
  1053. begin
  1054. inherited;
  1055. if Operation = opRemove then
  1056. begin
  1057. if AComponent = FMaterialLibrary then
  1058. FMaterialLibrary := nil
  1059. else if AComponent = FMemo then
  1060. FMemo := nil;
  1061. end;
  1062. end;
  1063. end.