uFountainD.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. unit uFountainD;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. Winapi.Messages,
  6. Winapi.OpenGL,
  7. Winapi.OpenGLext,
  8. System.SysUtils,
  9. System.Variants,
  10. System.Classes,
  11. Vcl.Graphics,
  12. Vcl.Controls,
  13. Vcl.Forms,
  14. Vcl.Dialogs,
  15. Vcl.StdCtrls,
  16. Vcl.ComCtrls,
  17. Vcl.ExtCtrls,
  18. Vcl.Imaging.Jpeg,
  19. GLS.PersistentClasses,
  20. GLS.Scene,
  21. GLS.Objects,
  22. GLScene.VectorGeometry,
  23. GLS.Texture,
  24. GLScene.VectorTypes,
  25. GLS.RenderContextInfo;
  26. const
  27. F_GRAVITY = 9.81;
  28. // ---------------------------------------------------------------------
  29. // TFctCondition
  30. // ---------------------------------------------------------------------
  31. type
  32. TFctCondition = function(const ptCondition: Pointer): Boolean;
  33. TpNode = ^TNode;
  34. TNode = record
  35. Info: Pointer;
  36. Next: TpNode;
  37. end;
  38. const
  39. SIZE_NODE = SizeOf(TNode);
  40. // ---------------------------------------------------------------------
  41. // TListSPTR
  42. // ---------------------------------------------------------------------
  43. type
  44. TListSPTR = class
  45. private
  46. Head: TpNode;
  47. Final: TpNode;
  48. Current: TpNode;
  49. Count: Cardinal;
  50. SizeInfo: Cardinal;
  51. public
  52. constructor Create(_SizeInfo: Cardinal);
  53. destructor Destroy; override;
  54. function Add(New: Pointer): Boolean;
  55. function CurrentModify(Modification: Pointer): Boolean;
  56. function DeleteIf(FctCondition: TFctCondition): integer;
  57. function DeleteCurrent: Boolean;
  58. procedure Clear;
  59. function GetNbCount: Cardinal;
  60. function GetCurrent(Information: Pointer): Boolean;
  61. function GetFirst(Information: Pointer): Boolean;
  62. function GetLast(Information: Pointer): Boolean;
  63. function GetNext(Information: Pointer): Boolean;
  64. end;
  65. // ---------------------------------------------------------------------
  66. // TParticle
  67. // ---------------------------------------------------------------------
  68. type
  69. pParticle = ^TParticle;
  70. TParticle = record
  71. Pos: TAffineVector;
  72. Accel: TAffineVector;
  73. Velocity: single;
  74. Times: double;
  75. Life: single;
  76. AngleStart: single;
  77. Bounding: integer;
  78. Width: single;
  79. Color: TAffineVector;
  80. ColorDiff: TAffineVector;
  81. end;
  82. const
  83. SIZE_STR_PARTICLE = SizeOf(TParticle);
  84. // ---------------------------------------------------------------------
  85. // TGLFountainDummy
  86. // ---------------------------------------------------------------------
  87. type
  88. TGLFountainDummy = class(TGLImmaterialSceneObject)
  89. protected
  90. FActived: Boolean;
  91. FNbParticles: integer;
  92. FMaxParticles: integer;
  93. FVelocityMax: integer;
  94. FVelocityMin: integer;
  95. FAngleStart: integer;
  96. FFloor: single;
  97. FFountainSize: single;
  98. FParticlesSizeMax: integer;
  99. FParticlesSizeMin: integer;
  100. FBoundingFactor: single;
  101. FParticleMass: single;
  102. FTimesFactor: double;
  103. FLifeFactor: single;
  104. FBounding: Boolean;
  105. FColorStart: longint;
  106. FColorEnd: longint;
  107. FNewTime: double;
  108. FDeltaTime: double;
  109. function GetActived: Boolean;
  110. procedure SetActived(const Activ: Boolean);
  111. function GetNbParticles: integer;
  112. function GetMaxParticles: integer;
  113. procedure SetMaxParticles(const Max: integer);
  114. function GetVelocityMax: integer;
  115. procedure SetVelocityMax(const VeloMax: integer);
  116. function GetVelocityMin: integer;
  117. procedure SetVelocityMin(const VeloMin: integer);
  118. function GetAngleStart: integer;
  119. procedure SetAngleStart(const AngleS: integer);
  120. function GetFloor: single;
  121. procedure SetFloor(const TheFloor: single);
  122. function GetFountainSize: single;
  123. procedure SetFountainSize(const FountainSize: single);
  124. function GetParticlesSizeMax: integer;
  125. procedure SetParticlesSizeMax(const PartMax: integer);
  126. function GetParticlesSizeMin: integer;
  127. procedure SetParticlesSizeMin(const PartMin: integer);
  128. function GetBoundingFact: single;
  129. procedure SetBoundingFact(const BoundSize: single);
  130. function GetParticlesMass: single;
  131. procedure SetParticlesMass(const Mass: single);
  132. function GetTimesFactor: double;
  133. procedure SetTimesFactor(const TimesFact: double);
  134. function GetLifeFactor: single;
  135. procedure SetLifeFactor(const LifeFact: single);
  136. function GetBounding: Boolean;
  137. procedure SetBounding(const Bound: Boolean);
  138. function GetColorStart: longint;
  139. procedure SetColorStart(const ColStart: longint);
  140. function GetColorEnd: longint;
  141. procedure SetColorEnd(const ColEnd: longint);
  142. private
  143. LsParticles: TListSPTR;
  144. TabCos, TabSin: array [0 .. 360] of double;
  145. RD, GD, BD, RF, GF, BF: Byte;
  146. procedure initFountain;
  147. function AddParticle: Boolean;
  148. procedure DeleteParticle;
  149. procedure CalculBoundPosParticles;
  150. procedure CalculPosParticles;
  151. procedure DrawParticles(rci: TGLRenderContextInfo);
  152. procedure Animation(rci: TGLRenderContextInfo);
  153. procedure UpdateFountain;
  154. public
  155. procedure DoRender(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean);
  156. override;
  157. // procedure DoProgress( const progressTime : TGLProgressTimes ); override;
  158. constructor Create(AOwner: TComponent); override;
  159. destructor Destroy; override;
  160. published
  161. property Actived: Boolean read FActived write SetActived;
  162. property NbParticles: integer read GetNbParticles;
  163. property MaxParticles: integer read GetMaxParticles write SetMaxParticles;
  164. property VelocityMax: integer read GetVelocityMax write SetVelocityMax;
  165. property VelocityMin: integer read GetVelocityMin write SetVelocityMin;
  166. property AngleInit: integer read GetAngleStart write SetAngleStart;
  167. property Floor: single read GetFloor write SetFloor;
  168. property ParticlesSizeMax: integer read GetParticlesSizeMax write SetParticlesSizeMax;
  169. property ParticlesSizeMin: integer read GetParticlesSizeMin write SetParticlesSizeMin;
  170. property BoundingFactor: single read GetBoundingFact write SetBoundingFact;
  171. property ParticleMass: single read GetParticlesMass write SetParticlesMass;
  172. property TimesFactor: double read GetTimesFactor write SetTimesFactor;
  173. property LifeFactor: single read GetLifeFactor write SetLifeFactor;
  174. property Bounding: Boolean read GetBounding write SetBounding;
  175. property ColorStart: longint read GetColorStart write SetColorStart;
  176. property ColorEnd: longint read GetColorEnd write SetColorEnd;
  177. end;
  178. // ================================================================
  179. implementation
  180. // ================================================================
  181. // ---------------------------------------------------------------
  182. // TListSPTR
  183. // ---------------------------------------------------------------
  184. constructor TListSPTR.Create(_SizeInfo: Cardinal);
  185. begin
  186. inherited Create;
  187. Clear;
  188. SizeInfo := _SizeInfo;
  189. end;
  190. destructor TListSPTR.Destroy;
  191. begin
  192. inherited Destroy;
  193. Clear;
  194. end;
  195. function TListSPTR.Add(New: Pointer): Boolean;
  196. var
  197. p: TpNode;
  198. begin
  199. GetMem(p, SIZE_NODE);
  200. FillChar(p^, SIZE_NODE, 0);
  201. Result := p <> Nil;
  202. if (Result) then
  203. begin
  204. GetMem(p^.Info, SizeInfo);
  205. FillChar(p^.Info^, SizeInfo, 0);
  206. Result := (p^.Info <> nil);
  207. if (Result) then
  208. begin
  209. p^.Next := Head;
  210. Head := p;
  211. Current := p;
  212. Move(New^, p^.Info^, SizeInfo);
  213. Inc(Count);
  214. end;
  215. end
  216. end;
  217. function TListSPTR.CurrentModify(Modification: Pointer): Boolean;
  218. begin
  219. Result := (Current <> nil) and (Modification <> nil);
  220. if Result then
  221. Move(Modification^, Current^.Info^, SizeInfo);
  222. end;
  223. function TListSPTR.DeleteCurrent: Boolean;
  224. var
  225. p: TpNode;
  226. pContinue: TpNode;
  227. Begin
  228. Result := (Current <> nil) and (Count > 0);
  229. if Result then
  230. begin
  231. p := Current;
  232. if (p = Head) then
  233. begin
  234. Head := p^.Next;
  235. Current := Current^.Next;
  236. FreeMem(p^.Info, SizeInfo);
  237. FreeMem(p, SIZE_NODE);
  238. Dec(Count);
  239. end
  240. else
  241. begin
  242. pContinue := Head;
  243. while (pContinue <> nil) and (pContinue^.Next <> p) do
  244. pContinue := pContinue^.Next;
  245. if (pContinue <> nil) then
  246. begin
  247. pContinue^.Next := p^.Next;
  248. Current := Current^.Next;
  249. FreeMem(p^.Info, SizeInfo);
  250. FreeMem(p, SIZE_NODE);
  251. Dec(Count);
  252. end;
  253. end;
  254. end;
  255. end;
  256. function TListSPTR.DeleteIf(FctCondition: TFctCondition): integer;
  257. var
  258. p, GCurrent: TpNode;
  259. begin
  260. Result := 0;
  261. GCurrent := Current;
  262. p := Head;
  263. while (p <> nil) do
  264. begin
  265. if FctCondition(p^.Info) then
  266. begin
  267. Current := p;
  268. DeleteCurrent;
  269. p := Current;
  270. Inc(Result);
  271. end
  272. else
  273. p := p^.Next;
  274. end;
  275. Current := GCurrent;
  276. end;
  277. procedure TListSPTR.Clear;
  278. var
  279. pAClean: TpNode;
  280. begin
  281. if (Head <> nil) then
  282. begin
  283. while (Head <> nil) do
  284. begin
  285. pAClean := Head;
  286. Head := pAClean^.Next;
  287. FreeMem(pAClean^.Info, SizeInfo);
  288. FreeMem(pAClean, SIZE_NODE);
  289. end;
  290. end;
  291. Head := nil;
  292. Final := nil;
  293. Current := nil;
  294. Count := 0;
  295. end;
  296. function TListSPTR.GetNbCount: Cardinal;
  297. begin
  298. Result := Count;
  299. end;
  300. function TListSPTR.GetCurrent(Information: Pointer): Boolean;
  301. Begin
  302. Result := (Head <> nil) and (Information <> nil) and (Current <> nil);
  303. if Result then
  304. Move(Current^.Info^, Information^, SizeInfo);
  305. end;
  306. function TListSPTR.GetFirst(Information: Pointer): Boolean;
  307. begin
  308. Result := (Head <> nil) and (Information <> nil);
  309. if Result then
  310. begin
  311. Move(Head^.Info^, Information^, SizeInfo);
  312. Current := Head;
  313. end;
  314. end;
  315. function TListSPTR.GetLast(Information: Pointer): Boolean;
  316. begin
  317. Result := (Final <> nil) and (Information <> nil);
  318. if Result then
  319. begin
  320. Move(Final^.Info^, Information^, SizeInfo);
  321. Current := Final;
  322. end;
  323. end;
  324. function TListSPTR.GetNext(Information: Pointer): Boolean;
  325. begin
  326. Result := (Count > 0) and (Current^.Next <> nil) and (Information <> nil);
  327. if Result then
  328. begin
  329. Move(Current^.Next^.Info^, Information^, SizeInfo);
  330. Current := Current^.Next;
  331. end;
  332. end;
  333. // -------------------------------------------------
  334. // TGLFountainDummy
  335. // -------------------------------------------------
  336. constructor TGLFountainDummy.Create(AOwner: TComponent);
  337. begin
  338. inherited Create(AOwner);
  339. FNewTime := 0.0;
  340. FDeltaTime := 0.0;
  341. FActived := True;
  342. FNbParticles := 0;
  343. FMaxParticles := 500;
  344. FVelocityMin := 14;
  345. FVelocityMax := 15;
  346. FAngleStart := 360;
  347. FFloor := 0.0;
  348. FFountainSize := 0.2;
  349. FParticlesSizeMin := 20;
  350. FParticlesSizeMax := 40;
  351. FBoundingFactor := 55;
  352. FParticleMass := 5.0;
  353. FTimesFactor := 0.005;
  354. FLifeFactor := 0.005;
  355. FBounding := False;
  356. SetColorStart($FF0000);
  357. SetColorEnd($FF0000);
  358. initFountain;
  359. end;
  360. procedure TGLFountainDummy.initFountain;
  361. var
  362. i: integer;
  363. begin
  364. for i := 0 to 360 do
  365. begin
  366. TabCos[i] := Cos(i);
  367. TabSin[i] := Sin(i);
  368. end;
  369. Randomize;
  370. LsParticles := TListSPTR.Create(SIZE_STR_PARTICLE);
  371. end;
  372. procedure TGLFountainDummy.UpdateFountain;
  373. begin
  374. FNbParticles := 0;
  375. if assigned(LsParticles) then
  376. LsParticles.Free;
  377. initFountain;
  378. NotifyChange(self);
  379. end;
  380. function TGLFountainDummy.AddParticle: Boolean;
  381. var
  382. PTime: TParticle;
  383. begin
  384. Result := (FActived) and (NbParticles < FMaxParticles);
  385. if Result then
  386. begin
  387. with PTime do
  388. begin
  389. Pos.X := 0.0;
  390. Pos.Y := FFloor;
  391. Pos.Z := 0.0;
  392. AngleStart := Random(FAngleStart);
  393. Velocity := (Random(FVelocityMax - FVelocityMin) + FVelocityMin) * 0.1;
  394. Accel.X := TabCos[Round(AngleStart)] * Velocity * FFountainSize;
  395. Accel.Y := 0.0;
  396. Accel.Z := TabSin[Round(AngleStart)] * Velocity * FFountainSize;
  397. Times := 0.0;
  398. Life := 1.0;
  399. if FBounding then
  400. Bounding := 0
  401. else
  402. Bounding := 1;
  403. Width := (Random(FParticlesSizeMax - FParticlesSizeMin) + FParticlesSizeMin) * 0.1;
  404. Color := AffineVectorMake(RD Div 255, GD Div 255, BD Div 255);
  405. ColorDiff := AffineVectorMake((RF - RD) / (1 / FLifeFactor) / 255,
  406. (GF - GD) / (1 / FLifeFactor) / 255, (BF - BD) / (1 / FLifeFactor) / 255);
  407. end;
  408. Result := LsParticles.Add(@PTime);
  409. if Result then
  410. Inc(FNbParticles);
  411. end;
  412. end;
  413. procedure TGLFountainDummy.DeleteParticle;
  414. function LifeCheckParticle(const Particle: Pointer): Boolean;
  415. begin
  416. Result := (TParticle(Particle^).Bounding > 0) and (TParticle(Particle^).Life <= 0)
  417. end;
  418. begin
  419. if (FActived) then
  420. FNbParticles := FNbParticles - LsParticles.DeleteIf(@LifeCheckParticle);
  421. end;
  422. procedure TGLFountainDummy.CalculBoundPosParticles;
  423. var
  424. RoadParticle: TParticle;
  425. BoundFactor: single;
  426. begin
  427. if (FActived) then
  428. begin
  429. if LsParticles.GetFirst(@RoadParticle) then
  430. repeat
  431. with RoadParticle do
  432. begin
  433. if (Pos.Y < FFloor) then
  434. begin
  435. if (Life > 0) then
  436. begin
  437. Times := 0.0;
  438. BoundFactor := (Velocity * FBoundingFactor * 0.01);
  439. Velocity := Velocity - BoundFactor;
  440. Pos.X := Pos.X + Accel.X - BoundFactor;
  441. Pos.Z := Pos.Z + Accel.Z - BoundFactor;
  442. Pos.Y := FFloor;
  443. Inc(Bounding);
  444. end
  445. end
  446. else
  447. begin
  448. if Bounding > 0 then
  449. Life := Life - FLifeFactor;
  450. Pos.X := Pos.X + Accel.X;
  451. Pos.Y := (Pos.Y + Times + Velocity) - (F_GRAVITY + FParticleMass) * Sqr(Times);
  452. Pos.Z := Pos.Z + Accel.Z;
  453. end;
  454. Color := VectorAdd(Color, ColorDiff);
  455. Times := Times + FTimesFactor;
  456. end;
  457. LsParticles.CurrentModify(@RoadParticle);
  458. until not LsParticles.GetNext(@RoadParticle);
  459. end;
  460. end;
  461. procedure TGLFountainDummy.CalculPosParticles;
  462. var
  463. RoadParticle: TParticle;
  464. begin
  465. if (FActived) then
  466. begin
  467. if LsParticles.GetFirst(@RoadParticle) then
  468. repeat
  469. with RoadParticle do
  470. begin
  471. if (Pos.Y >= FFloor) then
  472. begin
  473. Life := Life - FLifeFactor;
  474. Pos.X := Pos.X + Accel.X;
  475. Pos.Y := (Pos.Y + Times + Velocity) - (F_GRAVITY + FParticleMass) * Sqr(Times);
  476. Pos.Z := Pos.Z + Accel.Z;
  477. end
  478. else
  479. Life := Life - FLifeFactor;
  480. Color := VectorAdd(Color, ColorDiff);
  481. Times := Times + FTimesFactor;
  482. end;
  483. LsParticles.CurrentModify(@RoadParticle);
  484. Until Not LsParticles.GetNext(@RoadParticle);
  485. end;
  486. end;
  487. procedure TGLFountainDummy.DrawParticles(rci: TGLRenderContextInfo);
  488. var
  489. RoadParticle: TParticle;
  490. GMatrix: array [0 .. 15] of GlFloat;
  491. VRight, VUp: TVector3f;
  492. begin
  493. if LsParticles.GetFirst(@RoadParticle) then
  494. repeat
  495. with RoadParticle do
  496. begin
  497. glGetFloatv(GL_MODELVIEW_MATRIX, @GMatrix);
  498. VRight := AffineVectorMake(GMatrix[00], GMatrix[04], GMatrix[08]);
  499. VUp := AffineVectorMake(GMatrix[01], GMatrix[05], GMatrix[09]);
  500. NormalizeVector(VRight);
  501. NormalizeVector(VUp);
  502. ScaleVector(VRight, Width / 2);
  503. ScaleVector(VUp, Width / 2);
  504. glColor4f(Color.X, Color.Y, Color.Z, Life);
  505. glbegin(GL_QUADS);
  506. glTexCoord2f(0, 0);
  507. glVertex3d(Pos.X - (VRight.X + VUp.X), Pos.Y - (VRight.Y + VUp.Y),
  508. Pos.Z - (VRight.Z + VUp.Z));
  509. glTexCoord2f(1, 0);
  510. glVertex3d(Pos.X + (VRight.X - VUp.X), Pos.Y + (VRight.Y - VUp.Y),
  511. Pos.Z + (VRight.Z - VUp.Z));
  512. glTexCoord2f(1, 1);
  513. glVertex3d(Pos.X + (VRight.X + VUp.X), Pos.Y + (VRight.Y + VUp.Y),
  514. Pos.Z + (VRight.Z + VUp.Z));
  515. glTexCoord2f(0, 1);
  516. glVertex3d(Pos.X - (VRight.X - VUp.X), Pos.Y - (VRight.Y - VUp.Y),
  517. Pos.Z - (VRight.Z - VUp.Z));
  518. glend();
  519. end;
  520. LsParticles.CurrentModify(@RoadParticle);
  521. Until Not LsParticles.GetNext(@RoadParticle);
  522. end;
  523. procedure TGLFountainDummy.Animation(rci: TGLRenderContextInfo);
  524. begin
  525. AddParticle;
  526. DeleteParticle;
  527. if FBounding then
  528. CalculBoundPosParticles
  529. else
  530. CalculPosParticles;
  531. glPushMatrix;
  532. glEnable(GL_TEXTURE_2D);
  533. glBindTexture(GL_TEXTURE_2D, Material.Texture.Handle);
  534. glDepthMask(0); // false
  535. glEnable(GL_BLEND);
  536. glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  537. glCullFace(GL_BACK);
  538. glEnable(GL_CULL_FACE);
  539. glDisable(GL_LIGHTING);
  540. DrawParticles(rci);
  541. glDisable(GL_TEXTURE_2D);
  542. glDisable(GL_BLEND);
  543. glDepthMask(1); // true
  544. glEnable(GL_LIGHTING);
  545. glDisable(GL_CULL_FACE);
  546. glPopMatrix;
  547. end;
  548. function TGLFountainDummy.GetActived: Boolean;
  549. begin
  550. Result := FActived;
  551. end;
  552. procedure TGLFountainDummy.SetActived(const Activ: Boolean);
  553. begin
  554. FActived := Activ;
  555. UpdateFountain;
  556. end;
  557. function TGLFountainDummy.GetNbParticles: integer;
  558. begin
  559. Result := FNbParticles;
  560. end;
  561. function TGLFountainDummy.GetMaxParticles: integer;
  562. begin
  563. Result := FMaxParticles;
  564. end;
  565. procedure TGLFountainDummy.SetMaxParticles(const Max: integer);
  566. begin
  567. FMaxParticles := Max;
  568. UpdateFountain;
  569. end;
  570. function TGLFountainDummy.GetVelocityMax: integer;
  571. begin
  572. Result := FVelocityMax;
  573. end;
  574. procedure TGLFountainDummy.SetVelocityMax(const VeloMax: integer);
  575. begin
  576. if (VeloMax > FVelocityMin) then
  577. FVelocityMax := VeloMax
  578. else
  579. FVelocityMax := FVelocityMin + 1;
  580. UpdateFountain;
  581. end;
  582. function TGLFountainDummy.GetVelocityMin: integer;
  583. begin
  584. Result := FVelocityMin;
  585. end;
  586. procedure TGLFountainDummy.SetVelocityMin(const VeloMin: integer);
  587. begin
  588. if (VeloMin < FVelocityMax) then
  589. FVelocityMin := VeloMin
  590. else
  591. FVelocityMin := FVelocityMax - 1;
  592. UpdateFountain;
  593. end;
  594. function TGLFountainDummy.GetAngleStart: integer;
  595. begin
  596. Result := FVelocityMin;
  597. end;
  598. procedure TGLFountainDummy.SetAngleStart(const AngleS: integer);
  599. begin
  600. if (AngleS >= 0) and (AngleS <= 360) then
  601. FAngleStart := AngleS
  602. else
  603. FAngleStart := 360;
  604. UpdateFountain;
  605. end;
  606. function TGLFountainDummy.GetFloor: single;
  607. begin
  608. Result := FFloor;
  609. end;
  610. procedure TGLFountainDummy.SetFloor(const TheFloor: single);
  611. begin
  612. FFloor := TheFloor;
  613. UpdateFountain;
  614. end;
  615. function TGLFountainDummy.GetFountainSize: single;
  616. begin
  617. Result := FFountainSize;
  618. end;
  619. procedure TGLFountainDummy.SetFountainSize(const FountainSize: single);
  620. begin
  621. FFountainSize := FountainSize;
  622. UpdateFountain;
  623. end;
  624. function TGLFountainDummy.GetParticlesSizeMax: integer;
  625. begin
  626. Result := FParticlesSizeMax;
  627. end;
  628. procedure TGLFountainDummy.SetParticlesSizeMax(const PartMax: integer);
  629. begin
  630. if (PartMax > FParticlesSizeMin) then
  631. FParticlesSizeMax := PartMax
  632. else
  633. FParticlesSizeMax := FParticlesSizeMin + 1;
  634. UpdateFountain;
  635. end;
  636. function TGLFountainDummy.GetParticlesSizeMin: integer;
  637. begin
  638. Result := FParticlesSizeMin;
  639. end;
  640. procedure TGLFountainDummy.SetParticlesSizeMin(const PartMin: integer);
  641. begin
  642. if (PartMin < FParticlesSizeMax) then
  643. FParticlesSizeMin := PartMin
  644. else
  645. FParticlesSizeMin := FParticlesSizeMax - 1;
  646. UpdateFountain;
  647. end;
  648. function TGLFountainDummy.GetBoundingFact: single;
  649. begin
  650. Result := FBoundingFactor;
  651. end;
  652. procedure TGLFountainDummy.SetBoundingFact(const BoundSize: single);
  653. begin
  654. if (BoundSize >= 0) and (BoundSize <= 100) then
  655. FBoundingFactor := BoundSize
  656. else
  657. FBoundingFactor := 100;
  658. UpdateFountain;
  659. end;
  660. function TGLFountainDummy.GetParticlesMass: single;
  661. begin
  662. Result := FParticleMass;
  663. end;
  664. procedure TGLFountainDummy.SetParticlesMass(const Mass: single);
  665. begin
  666. FParticleMass := Mass;
  667. UpdateFountain;
  668. end;
  669. function TGLFountainDummy.GetTimesFactor: double;
  670. begin
  671. Result := FTimesFactor;
  672. end;
  673. procedure TGLFountainDummy.SetTimesFactor(const TimesFact: double);
  674. begin
  675. FTimesFactor := TimesFact;
  676. UpdateFountain;
  677. end;
  678. function TGLFountainDummy.GetLifeFactor: single;
  679. begin
  680. Result := FLifeFactor;
  681. end;
  682. procedure TGLFountainDummy.SetLifeFactor(const LifeFact: single);
  683. begin
  684. if LifeFact > 0 then
  685. FLifeFactor := LifeFact
  686. else
  687. FLifeFactor := 0.005;
  688. UpdateFountain;
  689. end;
  690. function TGLFountainDummy.GetBounding: Boolean;
  691. begin
  692. Result := FBounding;
  693. end;
  694. procedure TGLFountainDummy.SetBounding(const Bound: Boolean);
  695. begin
  696. FBounding := Bound;
  697. UpdateFountain;
  698. end;
  699. function TGLFountainDummy.GetColorStart: longint;
  700. begin
  701. Result := FColorStart;
  702. end;
  703. procedure TGLFountainDummy.SetColorStart(const ColStart: longint);
  704. begin
  705. FColorStart := ColStart;
  706. RD := FColorStart;
  707. GD := FColorStart Shr 8;
  708. BD := FColorStart Shr 16;
  709. UpdateFountain;
  710. end;
  711. function TGLFountainDummy.GetColorEnd: longint;
  712. begin
  713. Result := FColorEnd;
  714. end;
  715. procedure TGLFountainDummy.SetColorEnd(const ColEnd: longint);
  716. begin
  717. FColorEnd := ColEnd;
  718. RF := FColorEnd;
  719. GF := FColorEnd Shr 8;
  720. BF := FColorEnd Shr 16;
  721. UpdateFountain;
  722. end;
  723. procedure TGLFountainDummy.DoRender(var rci: TGLRenderContextInfo;
  724. renderSelf, renderChildren: Boolean);
  725. begin
  726. Animation(rci);
  727. if renderChildren then
  728. self.renderChildren(0, Count - 1, rci);
  729. end;
  730. destructor TGLFountainDummy.Destroy;
  731. begin
  732. FNbParticles := 0;
  733. LsParticles.Free;
  734. DeleteChildren;
  735. inherited Destroy;
  736. end;
  737. // -----------------------------------------------------------------------------
  738. initialization
  739. // ---------------------------------------------------------------------
  740. RegisterClass(TGLFountainDummy);
  741. end.