GLS.LinePFX.pas 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. //
  2. // The graphics engine GLScene
  3. //
  4. unit GLS.LinePFX;
  5. (* A PFX whose particles are lines *)
  6. interface
  7. {$I Stage.Defines.inc}
  8. uses
  9. Winapi.OpenGL,
  10. System.Classes,
  11. System.SysUtils,
  12. Stage.OpenGLTokens,
  13. GLS.PersistentClasses,
  14. Stage.VectorGeometry,
  15. GLS.ParticleFX,
  16. GLS.Texture,
  17. GLS.Color,
  18. GLS.RenderContextInfo,
  19. GLS.Context,
  20. Stage.VectorTypes;
  21. type
  22. // Linear particle.
  23. TGLLineParticle = class(TGLParticle)
  24. private
  25. FDirection: TAffineVector;
  26. FLength: Single;
  27. protected
  28. public
  29. procedure WriteToFiler(writer: TGLVirtualWriter); override;
  30. procedure ReadFromFiler(reader: TGLVirtualReader); override;
  31. // Direction of the line.
  32. property Direction: TAffineVector read FDirection write FDirection;
  33. // Length of the line
  34. property Length: Single read FLength write FLength;
  35. end;
  36. (* Polygonal particles FX manager.
  37. The particles of this manager are made of N-face regular polygon with
  38. a core and edge color. No texturing is available.
  39. If you render large particles and don't have T&L acceleration, consider
  40. using TGLPointLightPFXManager. *)
  41. TGLLinePFXManager = class(TGLLifeColoredPFXManager)
  42. private
  43. Fvx, Fvy: TAffineVector; // NOT persistent
  44. FNvx, FNvy: TAffineVector; // NOT persistent
  45. FDefaultLength: Single;
  46. protected
  47. function StoreDefaultLength: Boolean;
  48. function TexturingMode: Cardinal; override;
  49. procedure InitializeRendering(var rci: TGLRenderContextInfo); override;
  50. procedure BeginParticles(var rci: TGLRenderContextInfo); override;
  51. procedure RenderParticle(var rci: TGLRenderContextInfo;
  52. aParticle: TGLParticle); override;
  53. procedure EndParticles(var rci: TGLRenderContextInfo); override;
  54. procedure FinalizeRendering(var rci: TGLRenderContextInfo); override;
  55. public
  56. constructor Create(aOwner: TComponent); override;
  57. destructor Destroy; override;
  58. class function ParticlesClass: TGLParticleClass; override;
  59. function CreateParticle: TGLParticle; override;
  60. published
  61. property DefaultLength: Single read FDefaultLength write FDefaultLength
  62. stored StoreDefaultLength;
  63. property ParticleSize;
  64. property ColorInner;
  65. property ColorOuter;
  66. property LifeColors;
  67. end;
  68. // ------------------------------------------------------------------
  69. implementation
  70. // ------------------------------------------------------------------
  71. // ------------------
  72. // ------------------ TGLLinePFXManager ------------------
  73. // ------------------
  74. constructor TGLLinePFXManager.Create(aOwner: TComponent);
  75. begin
  76. inherited;
  77. FDefaultLength := 1;
  78. end;
  79. destructor TGLLinePFXManager.Destroy;
  80. begin
  81. inherited Destroy;
  82. end;
  83. class function TGLLinePFXManager.ParticlesClass: TGLParticleClass;
  84. begin
  85. Result := TGLLineParticle;
  86. end;
  87. function TGLLinePFXManager.CreateParticle: TGLParticle;
  88. begin
  89. Result := inherited CreateParticle;
  90. TGLLineParticle(Result).FLength := DefaultLength;
  91. end;
  92. function TGLLinePFXManager.TexturingMode: Cardinal;
  93. begin
  94. Result := 0;
  95. end;
  96. procedure TGLLinePFXManager.InitializeRendering(var rci: TGLRenderContextInfo);
  97. var
  98. i: Integer;
  99. matrix: TGLMatrix;
  100. begin
  101. inherited;
  102. gl.GetFloatv(GL_MODELVIEW_MATRIX, @matrix);
  103. for i := 0 to 2 do
  104. begin
  105. Fvx.V[i] := matrix.V[i].X;
  106. Fvy.V[i] := matrix.V[i].Y;
  107. end;
  108. FNvx := VectorNormalize(Fvx);
  109. FNvy := VectorNormalize(Fvy);
  110. end;
  111. procedure TGLLinePFXManager.BeginParticles(var rci: TGLRenderContextInfo);
  112. begin
  113. ApplyBlendingMode(rci);
  114. end;
  115. procedure TGLLinePFXManager.RenderParticle(var rci: TGLRenderContextInfo;
  116. aParticle: TGLParticle);
  117. var
  118. lifeTime, sizeScale, fx, fy, f: Single;
  119. inner, outer: TGLColorVector;
  120. pos, dir, start, stop, dv: TAffineVector;
  121. begin
  122. lifeTime := CurrentTime - aParticle.CreationTime;
  123. ComputeColors(lifeTime, inner, outer);
  124. if ComputeSizeScale(lifeTime, sizeScale) then
  125. sizeScale := sizeScale * ParticleSize
  126. else
  127. sizeScale := ParticleSize;
  128. pos := aParticle.Position;
  129. with TGLLineParticle(aParticle) do
  130. begin
  131. dir := VectorNormalize(aParticle.Velocity);
  132. f := Length * 0.5;
  133. end;
  134. start := VectorCombine(pos, dir, 1, f);
  135. stop := VectorCombine(pos, dir, 1, -f);
  136. fx := VectorDotProduct(dir, FNvy) * sizeScale;
  137. fy := -VectorDotProduct(dir, FNvx) * sizeScale;
  138. dv := VectorCombine(Fvx, Fvy, fx, fy);
  139. gl.Begin_(GL_TRIANGLE_FAN);
  140. gl.Color4fv(@inner);
  141. gl.Vertex3fv(@start);
  142. gl.Color4fv(@outer);
  143. gl.Vertex3f(start.X + dv.X, start.Y + dv.Y, start.Z + dv.Z);
  144. gl.Vertex3f(stop.X + dv.X, stop.Y + dv.Y, stop.Z + dv.Z);
  145. gl.Color4fv(@inner);
  146. gl.Vertex3fv(@stop);
  147. gl.Color4fv(@outer);
  148. gl.Vertex3f(stop.X - dv.X, stop.Y - dv.Y, stop.Z - dv.Z);
  149. gl.Vertex3f(start.X - dv.X, start.Y - dv.Y, start.Z - dv.Z);
  150. gl.End_;
  151. end;
  152. procedure TGLLinePFXManager.EndParticles(var rci: TGLRenderContextInfo);
  153. begin
  154. UnapplyBlendingMode(rci);
  155. end;
  156. procedure TGLLinePFXManager.FinalizeRendering(var rci: TGLRenderContextInfo);
  157. begin
  158. inherited;
  159. end;
  160. function TGLLinePFXManager.StoreDefaultLength: Boolean;
  161. begin
  162. Result := (FDefaultLength <> 1);
  163. end;
  164. // ------------------
  165. // ------------------ TGLLineParticle ------------------
  166. // ------------------
  167. procedure TGLLineParticle.WriteToFiler(writer: TGLVirtualWriter);
  168. begin
  169. inherited WriteToFiler(writer);
  170. with writer do
  171. begin
  172. WriteInteger(0); // Archive Version 0
  173. Write(FDirection, SizeOf(FDirection));
  174. WriteFloat(FLength);
  175. end;
  176. end;
  177. procedure TGLLineParticle.ReadFromFiler(reader: TGLVirtualReader);
  178. var
  179. archiveVersion: Integer;
  180. begin
  181. inherited ReadFromFiler(reader);
  182. archiveVersion := reader.ReadInteger;
  183. if archiveVersion = 0 then
  184. with reader do
  185. begin
  186. Read(FDirection, SizeOf(FDirection));
  187. FLength := ReadFloat;
  188. end
  189. else
  190. RaiseFilerException(archiveVersion);
  191. end;
  192. // ------------------------------------------------------------------
  193. initialization
  194. // ------------------------------------------------------------------
  195. RegisterClasses([TGLLineParticle, TGLLinePFXManager]);
  196. end.