GLMaterialScript.pas 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit GLMaterialScript;
  5. (* Material Script Batch loader for TGLMaterialLibrary for runtime. *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. System.SysUtils,
  10. System.Classes,
  11. VCL.StdCtrls,
  12. GLVectorTypes,
  13. GLTexture,
  14. GLTextureFormat,
  15. GLGraphics,
  16. GLS.Utils,
  17. GLColor,
  18. GLCoordinates,
  19. GLMaterial,
  20. GLState;
  21. type
  22. TGLShaderItem = class(TCollectionItem)
  23. private
  24. FShader: TGLShader;
  25. FName: string;
  26. procedure SetShader(const Value: TGLShader);
  27. procedure SetName(const Value: string);
  28. protected
  29. function GetDisplayName: string; override;
  30. public
  31. constructor Create(Collection: TCollection); override;
  32. destructor Destroy; override;
  33. procedure Assign(Source: TPersistent); override;
  34. published
  35. property Shader: TGLShader read FShader write SetShader;
  36. property Name: string read FName write SetName;
  37. end;
  38. TGLShaderItems = class(TOwnedCollection)
  39. private
  40. procedure SetItems(Index: Integer; const Val: TGLShaderItem);
  41. function GetItems(Index: Integer): TGLShaderItem;
  42. public
  43. constructor Create(AOwner: TPersistent);
  44. property Items[Index: Integer]: TGLShaderItem read GetItems write SetItems; default;
  45. end;
  46. TGLMaterialLibraryItem = class(TCollectionItem)
  47. private
  48. FMaterialLibrary: TGLMaterialLibrary;
  49. FName: string;
  50. procedure SetMaterialLibrary(const Value: TGLMaterialLibrary);
  51. procedure SetName(const Value: string);
  52. protected
  53. function GetDisplayName: string; override;
  54. public
  55. constructor Create(Collection: TCollection); override;
  56. destructor Destroy; override;
  57. procedure Assign(Source: TPersistent); override;
  58. published
  59. property MaterialLibrary: TGLMaterialLibrary read FMaterialLibrary write SetMaterialLibrary;
  60. property Name: string read FName write SetName;
  61. end;
  62. TGLMaterialLibraryItems = class(TOwnedCollection)
  63. private
  64. procedure SetItems(Index: Integer; const Val: TGLMaterialLibraryItem);
  65. function GetItems(Index: Integer): TGLMaterialLibraryItem;
  66. public
  67. constructor Create(AOwner: TPersistent);
  68. property Items[Index: Integer]: TGLMaterialLibraryItem read GetItems write SetItems; default;
  69. end;
  70. TGLMaterialScripter = class(TComponent)
  71. private
  72. FShaderItems: TGLShaderItems;
  73. FMaterialLibraryItems: TGLMaterialLibraryItems;
  74. FAppend: Boolean;
  75. FOverwrite: Boolean;
  76. FScript: TStrings;
  77. FMemo: TMemo;
  78. FMaterialLibrary: TGLMaterialLibrary;
  79. Count: Longint;
  80. infini: Longint;
  81. done: Boolean;
  82. NewMat: TGLLibMaterial;
  83. tmpcoords: TGLCoordinates;
  84. tmpcolor: TGLColor;
  85. tmpcoords4: TGLCoordinates4;
  86. tmpstr: string;
  87. procedure SeTGLShaderItems(const Value: TGLShaderItems);
  88. procedure SeTGLMaterialLibraryItems(const Value: TGLMaterialLibraryItems);
  89. procedure SetAppend(const Value: Boolean);
  90. procedure SetOverwrite(const Value: Boolean);
  91. procedure SetScript(const Value: TStrings);
  92. procedure SetMaterialLibrary(const Value: TGLMaterialLibrary);
  93. procedure SetMemo(const Value: TMemo);
  94. // error checking
  95. procedure CheckError;
  96. function ClassExists(arguement: string): Boolean;
  97. function CheckRepeatDone: Boolean;
  98. // extraction functions
  99. function ExtractValue: string;
  100. procedure ExtractCoords3;
  101. procedure ExtractCoords4;
  102. procedure ExtractColors;
  103. function DeleteSpaces(Value: string): string;
  104. function SubstrExists(substr: string): Boolean;
  105. function ValueExists(Value: string): Boolean;
  106. // these are our viable scripts
  107. procedure ZMaterial;
  108. // internally called scripts for value extraction
  109. procedure XMaterial;
  110. procedure XName;
  111. procedure XShader;
  112. procedure XTexture2Name;
  113. procedure XTextureOffset;
  114. procedure XTextureScale;
  115. procedure XTexture;
  116. procedure XCompression;
  117. procedure XEnvColor;
  118. procedure XFilteringQuality;
  119. procedure XImageAlpha;
  120. procedure XImageBrightness;
  121. procedure XImageClass;
  122. procedure XImageGamma;
  123. procedure XMagFilter;
  124. procedure XMappingMode;
  125. procedure XMappingSCoordinates;
  126. procedure XMappingTCoordinates;
  127. procedure XMinFilter;
  128. procedure XNormalMapScale;
  129. procedure XTextureFormat;
  130. procedure XTextureMode;
  131. procedure XTextureWrap;
  132. procedure XBlendingMode;
  133. procedure XPolygonMode;
  134. procedure XFacingCulling;
  135. procedure XLibMaterialName;
  136. procedure XMaterialOptions;
  137. procedure XMaterialLibrary;
  138. procedure XBackProperties;
  139. procedure XBackAmbient;
  140. procedure XBackDiffuse;
  141. procedure XBackEmission;
  142. procedure XBackShininess;
  143. procedure XBackSpecular;
  144. procedure XFrontProperties;
  145. procedure XFrontAmbient;
  146. procedure XFrontDiffuse;
  147. procedure XFrontEmission;
  148. procedure XFrontShininess;
  149. procedure XFrontSpecular;
  150. procedure XPersistantImage;
  151. procedure XBlankImage;
  152. procedure XPictureFileName;
  153. procedure XPicturePX;
  154. procedure XPictureNX;
  155. procedure XPicturePY;
  156. procedure XPictureNY;
  157. procedure XPicturePZ;
  158. procedure XPictureNZ;
  159. protected
  160. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  161. public
  162. property DebugMemo: TMemo read FMemo write SetMemo;
  163. constructor Create(AOwner: TComponent); override;
  164. destructor Destroy; override;
  165. procedure CompileScript;
  166. published
  167. property Script: TStrings read FScript write SetScript;
  168. property MaterialLibrary: TGLMaterialLibrary read FMaterialLibrary write SetMaterialLibrary;
  169. property Shaders: TGLShaderItems read FShaderItems write SeTGLShaderItems;
  170. property MaterialLibraries: TGLMaterialLibraryItems read FMaterialLibraryItems write SeTGLMaterialLibraryItems;
  171. property AppendToMaterialLibrary: Boolean read FAppend write SetAppend;
  172. property OverwriteToMaterialLibrary: Boolean read FOverwrite write SetOverwrite;
  173. end;
  174. //----------------------------------------------------------------------
  175. implementation
  176. //----------------------------------------------------------------------
  177. procedure TGLShaderItem.SetShader(const Value: TGLShader);
  178. begin
  179. if assigned(Value) then
  180. begin
  181. FShader := Value;
  182. FName := FShader.Name;
  183. end;
  184. end;
  185. procedure TGLShaderItem.Assign(Source: TPersistent);
  186. begin
  187. if Source is TGLShaderItem then
  188. begin
  189. FShader := TGLShaderItem(Source).FShader;
  190. end;
  191. inherited Destroy;
  192. end;
  193. constructor TGLShaderItem.Create(Collection: TCollection);
  194. begin
  195. inherited Create(Collection);
  196. FName := 'Shader';
  197. end;
  198. destructor TGLShaderItem.Destroy;
  199. begin
  200. inherited Destroy;
  201. end;
  202. function TGLShaderItem.GetDisplayName : String;
  203. begin
  204. if FName = '' then
  205. Result:='Shader'
  206. else
  207. Result := FName;
  208. end;
  209. //------------------------
  210. { TGLShaderItems }
  211. //------------------------
  212. constructor TGLShaderItems.Create(AOwner: TPersistent);
  213. begin
  214. inherited Create(AOwner, TGLShaderItem);
  215. end;
  216. function TGLShaderItems.GetItems(index: Integer): TGLShaderItem;
  217. begin
  218. Result:=TGLShaderItem(inherited Items[index]);
  219. end;
  220. procedure TGLShaderItems.SetItems(index: Integer; const val: TGLShaderItem);
  221. begin
  222. inherited Items[index]:=val;
  223. end;
  224. procedure TGLMaterialScripter.SeTGLShaderItems(const Value: TGLShaderItems);
  225. begin
  226. FShaderItems.Assign(Value);
  227. end;
  228. procedure TGLShaderItem.SetName(const Value: String);
  229. begin
  230. FName := Value;
  231. end;
  232. procedure TGLMaterialScripter.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 TGLMaterialScripter.SetMaterialLibrary(
  252. const Value: TGLMaterialLibrary);
  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 TGLMaterialScripter.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 TGLMaterialScripter.SetScript(const Value: TStrings);
  265. begin
  266. if assigned(value) then
  267. FScript.Assign(Value);
  268. end;
  269. procedure TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.Create(AOwner: TComponent);
  319. begin
  320. inherited Create(AOwner);
  321. FScript := TStringList.Create;
  322. FShaderItems:=TGLShaderItems.Create(Self);
  323. FMaterialLibraryItems:=TGLMaterialLibraryItems.Create(Self);
  324. FAppend := true;
  325. FOverwrite := false;
  326. end;
  327. function TGLMaterialScripter.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 TGLMaterialScripter.Destroy;
  336. begin
  337. FShaderItems.Free;
  338. FMaterialLibraryItems.Free;
  339. FScript.Free;
  340. inherited Destroy;
  341. end;
  342. procedure TGLMaterialScripter.ExtractColors;
  343. var val : string;
  344. begin
  345. val := Extractvalue;
  346. if pos('(',val) > 0 then
  347. begin
  348. tmpcolor.Alpha := GLS.Utils.StrToFloatDef(copy(val, pos('(',val) + 1, pos(';',val) - 2));
  349. delete(val,1,pos(';',val));
  350. tmpcolor.Red := GLS.Utils.StrToFloatDef(copy(val, 1, pos(';',val) - 1));
  351. delete(val,1,pos(';',val));
  352. tmpcolor.Green := GLS.Utils.StrToFloatDef(copy(val, 1, pos(';',val) - 1));
  353. delete(val,1,pos(';',val));
  354. tmpcolor.Blue := GLS.Utils.StrToFloatDef(copy(val, 1, pos(')',val) - 1));
  355. end;
  356. end;
  357. procedure TGLMaterialScripter.ExtractCoords3;
  358. var val : string;
  359. begin
  360. val := Extractvalue;
  361. if pos('(',val) > 0 then
  362. begin
  363. tmpcoords.X := GLS.Utils.StrToFloatDef(copy(val, pos('(',val) + 1, pos(';',val) - 2));
  364. delete(val,1,pos(';',val));
  365. tmpcoords.Y := GLS.Utils.StrToFloatDef(copy(val, 1, pos(';',val) - 1));
  366. delete(val,1,pos(';',val));
  367. tmpcoords.Z := GLS.Utils.StrToFloatDef(copy(val, 1, pos(')',val) - 1));
  368. end;
  369. end;
  370. procedure TGLMaterialScripter.ExtractCoords4;
  371. var val : string;
  372. begin
  373. val := Extractvalue;
  374. if pos('(',val) > 0 then
  375. begin
  376. tmpcoords4.W := GLS.Utils.StrToFloatDef(copy(val, pos('(',val) + 1, pos(';',val) - 2));
  377. delete(val,1,pos(';',val));
  378. tmpcoords4.X := GLS.Utils.StrToFloatDef(copy(val, 1, pos(';',val) - 1));
  379. delete(val,1,pos(';',val));
  380. tmpcoords4.Y := GLS.Utils.StrToFloatDef(copy(val, 1, pos(';',val) - 1));
  381. delete(val,1,pos(';',val));
  382. tmpcoords4.Z := GLS.Utils.StrToFloatDef(copy(val, 1, pos(')',val) - 1));
  383. end;
  384. end;
  385. function TGLMaterialScripter.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 TGLMaterialScripter.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 TGLPersistentImage 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 TGLMaterialScripter.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 TGLBlankImage 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 TGLMaterialScripter.XPictureFileName;
  416. begin
  417. if classexists('picturefilename') then
  418. with NewMat.Material.Texture.Image as TGLPicFileImage do
  419. if fileexists(extractvalue) then
  420. begin
  421. picturefilename := extractvalue;
  422. NewMat.Material.Texture.Disabled := false;
  423. end;
  424. end;
  425. procedure TGLMaterialScripter.XPictureNX;
  426. begin
  427. if classexists('picturenx') then
  428. if fileexists(extractvalue) then
  429. with NewMat.Material.Texture.Image as TGLCubeMapImage do
  430. Picture[cmtNX].LoadFromFile(extractvalue);
  431. end;
  432. procedure TGLMaterialScripter.XPictureNY;
  433. begin
  434. if classexists('pictureny') then
  435. if fileexists(extractvalue) then
  436. with NewMat.Material.Texture.Image as TGLCubeMapImage do
  437. Picture[cmtNY].LoadFromFile(extractvalue);
  438. end;
  439. procedure TGLMaterialScripter.XPictureNZ;
  440. begin
  441. if classexists('picturenz') then
  442. if fileexists(extractvalue) then
  443. with NewMat.Material.Texture.Image as TGLCubeMapImage do
  444. Picture[cmtNZ].LoadFromFile(extractvalue);
  445. end;
  446. procedure TGLMaterialScripter.XPicturePX;
  447. begin
  448. if classexists('picturepx') then
  449. if fileexists(extractvalue) then
  450. with NewMat.Material.Texture.Image as TGLCubeMapImage do
  451. Picture[cmtPX].LoadFromFile(extractvalue);
  452. end;
  453. procedure TGLMaterialScripter.XPicturePY;
  454. begin
  455. if classexists('picturepy') then
  456. if fileexists(extractvalue) then
  457. with NewMat.Material.Texture.Image as TGLCubeMapImage do
  458. Picture[cmtPY].LoadFromFile(extractvalue);
  459. end;
  460. procedure TGLMaterialScripter.XPicturePZ;
  461. begin
  462. if classexists('picturepz') then
  463. if fileexists(extractvalue) then
  464. with NewMat.Material.Texture.Image as TGLCubeMapImage do
  465. Picture[cmtPZ].LoadFromFile(extractvalue);
  466. end;
  467. function TGLMaterialScripter.ValueExists(value: string): boolean;
  468. begin
  469. if uppercase(tmpstr) = uppercase(value) then result := true
  470. else
  471. result := false;
  472. end;
  473. procedure TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.XBackShininess;
  572. begin
  573. if classexists('shininess') then
  574. if extractvalue <> '' then
  575. NewMat.Material.BackProperties.Shininess := strtoint(extractvalue);
  576. end;
  577. procedure TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.XfrontShininess;
  676. begin
  677. if classexists('shininess') then
  678. if extractvalue <> '' then
  679. NewMat.Material.frontProperties.Shininess := strtoint(extractvalue);
  680. end;
  681. procedure TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.XImageBrightness;
  707. begin
  708. if classexists('imagebrightness') then
  709. if extractvalue <> '' then
  710. NewMat.Material.Texture.ImageBrightness := GLS.Utils.StrToFloatDef(extractvalue);
  711. end;
  712. procedure TGLMaterialScripter.XImageGamma;
  713. begin
  714. if classexists('imagegamma') then
  715. if extractvalue <> '' then
  716. NewMat.Material.Texture.ImageGamma := GLS.Utils.StrToFloatDef(extractvalue);
  717. end;
  718. procedure TGLMaterialScripter.XLibMaterialName;
  719. begin
  720. if classexists('libmaterialname') then NewMat.Material.LibMaterialName := extractvalue;
  721. end;
  722. procedure TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.XNormalMapScale;
  801. begin
  802. if classexists('normalmapscale') then
  803. if extractvalue <> '' then
  804. NewMat.Material.Texture.NormalMapScale := GLS.Utils.StrToFloatDef(extractvalue);
  805. end;
  806. procedure TGLMaterialScripter.XTexture2Name;
  807. begin
  808. if classexists('texture2name') then NewMat.Texture2Name := ExtractValue;
  809. end;
  810. procedure TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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 TGLMaterialScripter.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
  934. repeat
  935. inc(count);
  936. Newmat.Material.Texture.ImageClassName := TGLPersistentImage.ClassName;
  937. XPersistantImage;
  938. checkerror;
  939. until checkrepeatdone;
  940. if valueexists('blankimage{') then
  941. repeat
  942. inc(count);
  943. Newmat.Material.Texture.ImageClassName := TGLBlankImage.ClassName;
  944. XBlankImage;
  945. checkerror;
  946. until checkrepeatdone;
  947. if valueexists('picfileimage{') then //picturefilename
  948. repeat
  949. inc(count);
  950. Newmat.Material.Texture.ImageClassName := TGLPicFileImage.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 := TGLCubeMapImage.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 GLTexture yet
  968. end;
  969. end;
  970. procedure TGLMaterialScripter.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. { TGLMaterialLibraryItems }
  987. constructor TGLMaterialLibraryItems.Create(AOwner: TPersistent);
  988. begin
  989. inherited Create(AOwner, TGLMaterialLibraryItem);
  990. end;
  991. function TGLMaterialLibraryItems.GetItems(index: Integer): TGLMaterialLibraryItem;
  992. begin
  993. Result:=TGLMaterialLibraryItem(inherited Items[index]);
  994. end;
  995. procedure TGLMaterialLibraryItems.SetItems(index: Integer;
  996. const val: TGLMaterialLibraryItem);
  997. begin
  998. inherited Items[index]:=val;
  999. end;
  1000. { TGLMaterialLibraryItem }
  1001. procedure TGLMaterialLibraryItem.Assign(Source: TPersistent);
  1002. begin
  1003. if Source is TGLMaterialLibraryItem then
  1004. begin
  1005. FMaterialLibrary := TGLMaterialLibraryItem(Source).FMaterialLibrary;
  1006. end;
  1007. inherited Destroy;
  1008. end;
  1009. constructor TGLMaterialLibraryItem.Create(Collection: TCollection);
  1010. begin
  1011. inherited Create(Collection);
  1012. FName := 'MaterialLibrary';
  1013. end;
  1014. destructor TGLMaterialLibraryItem.Destroy;
  1015. begin
  1016. inherited Destroy;
  1017. end;
  1018. function TGLMaterialLibraryItem.GetDisplayName: String;
  1019. begin
  1020. if FName = '' then
  1021. Result:='MaterialLibrary'
  1022. else
  1023. Result := FName;
  1024. end;
  1025. procedure TGLMaterialLibraryItem.SetMaterialLibrary(
  1026. const Value: TGLMaterialLibrary);
  1027. begin
  1028. if assigned(Value) then
  1029. begin
  1030. FMaterialLibrary := Value;
  1031. FName := FMaterialLibrary.Name;
  1032. end;
  1033. end;
  1034. procedure TGLMaterialLibraryItem.SetName(const Value: String);
  1035. begin
  1036. FName := Value;
  1037. end;
  1038. procedure TGLMaterialScripter.SeTGLMaterialLibraryItems(
  1039. const Value: TGLMaterialLibraryItems);
  1040. begin
  1041. FMaterialLibraryItems.Assign(Value);
  1042. end;
  1043. procedure TGLMaterialScripter.SetAppend(const Value: boolean);
  1044. begin
  1045. FAppend := Value;
  1046. end;
  1047. procedure TGLMaterialScripter.SetOverwrite(const Value: boolean);
  1048. begin
  1049. FOverwrite := Value;
  1050. end;
  1051. procedure TGLMaterialScripter.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.