123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- //
- // The graphics engine GLScene
- //
- unit GLS.LinePFX;
- (* A PFX whose particles are lines *)
- interface
- {$I Stage.Defines.inc}
- uses
- Winapi.OpenGL,
- System.Classes,
- System.SysUtils,
- Stage.OpenGLTokens,
- GLS.PersistentClasses,
- Stage.VectorGeometry,
- GLS.ParticleFX,
- GLS.Texture,
- GLS.Color,
- GLS.RenderContextInfo,
- GLS.Context,
- Stage.VectorTypes;
- type
- // Linear particle.
- TGLLineParticle = class(TGLParticle)
- private
- FDirection: TAffineVector;
- FLength: Single;
- protected
- public
- procedure WriteToFiler(writer: TGLVirtualWriter); override;
- procedure ReadFromFiler(reader: TGLVirtualReader); override;
- // Direction of the line.
- property Direction: TAffineVector read FDirection write FDirection;
- // Length of the line
- property Length: Single read FLength write FLength;
- end;
- (* Polygonal particles FX manager.
- The particles of this manager are made of N-face regular polygon with
- a core and edge color. No texturing is available.
- If you render large particles and don't have T&L acceleration, consider
- using TGLPointLightPFXManager. *)
- TGLLinePFXManager = class(TGLLifeColoredPFXManager)
- private
- Fvx, Fvy: TAffineVector; // NOT persistent
- FNvx, FNvy: TAffineVector; // NOT persistent
- FDefaultLength: Single;
- protected
- function StoreDefaultLength: Boolean;
- function TexturingMode: Cardinal; override;
- procedure InitializeRendering(var rci: TGLRenderContextInfo); override;
- procedure BeginParticles(var rci: TGLRenderContextInfo); override;
- procedure RenderParticle(var rci: TGLRenderContextInfo;
- aParticle: TGLParticle); override;
- procedure EndParticles(var rci: TGLRenderContextInfo); override;
- procedure FinalizeRendering(var rci: TGLRenderContextInfo); override;
- public
- constructor Create(aOwner: TComponent); override;
- destructor Destroy; override;
- class function ParticlesClass: TGLParticleClass; override;
- function CreateParticle: TGLParticle; override;
- published
- property DefaultLength: Single read FDefaultLength write FDefaultLength
- stored StoreDefaultLength;
- property ParticleSize;
- property ColorInner;
- property ColorOuter;
- property LifeColors;
- end;
- // ------------------------------------------------------------------
- implementation
- // ------------------------------------------------------------------
- // ------------------
- // ------------------ TGLLinePFXManager ------------------
- // ------------------
- constructor TGLLinePFXManager.Create(aOwner: TComponent);
- begin
- inherited;
- FDefaultLength := 1;
- end;
- destructor TGLLinePFXManager.Destroy;
- begin
- inherited Destroy;
- end;
- class function TGLLinePFXManager.ParticlesClass: TGLParticleClass;
- begin
- Result := TGLLineParticle;
- end;
- function TGLLinePFXManager.CreateParticle: TGLParticle;
- begin
- Result := inherited CreateParticle;
- TGLLineParticle(Result).FLength := DefaultLength;
- end;
- function TGLLinePFXManager.TexturingMode: Cardinal;
- begin
- Result := 0;
- end;
- procedure TGLLinePFXManager.InitializeRendering(var rci: TGLRenderContextInfo);
- var
- i: Integer;
- matrix: TGLMatrix;
- begin
- inherited;
- gl.GetFloatv(GL_MODELVIEW_MATRIX, @matrix);
- for i := 0 to 2 do
- begin
- Fvx.V[i] := matrix.V[i].X;
- Fvy.V[i] := matrix.V[i].Y;
- end;
- FNvx := VectorNormalize(Fvx);
- FNvy := VectorNormalize(Fvy);
- end;
- procedure TGLLinePFXManager.BeginParticles(var rci: TGLRenderContextInfo);
- begin
- ApplyBlendingMode(rci);
- end;
- procedure TGLLinePFXManager.RenderParticle(var rci: TGLRenderContextInfo;
- aParticle: TGLParticle);
- var
- lifeTime, sizeScale, fx, fy, f: Single;
- inner, outer: TGLColorVector;
- pos, dir, start, stop, dv: TAffineVector;
- begin
- lifeTime := CurrentTime - aParticle.CreationTime;
- ComputeColors(lifeTime, inner, outer);
- if ComputeSizeScale(lifeTime, sizeScale) then
- sizeScale := sizeScale * ParticleSize
- else
- sizeScale := ParticleSize;
- pos := aParticle.Position;
- with TGLLineParticle(aParticle) do
- begin
- dir := VectorNormalize(aParticle.Velocity);
- f := Length * 0.5;
- end;
- start := VectorCombine(pos, dir, 1, f);
- stop := VectorCombine(pos, dir, 1, -f);
- fx := VectorDotProduct(dir, FNvy) * sizeScale;
- fy := -VectorDotProduct(dir, FNvx) * sizeScale;
- dv := VectorCombine(Fvx, Fvy, fx, fy);
- gl.Begin_(GL_TRIANGLE_FAN);
- gl.Color4fv(@inner);
- gl.Vertex3fv(@start);
- gl.Color4fv(@outer);
- gl.Vertex3f(start.X + dv.X, start.Y + dv.Y, start.Z + dv.Z);
- gl.Vertex3f(stop.X + dv.X, stop.Y + dv.Y, stop.Z + dv.Z);
- gl.Color4fv(@inner);
- gl.Vertex3fv(@stop);
- gl.Color4fv(@outer);
- gl.Vertex3f(stop.X - dv.X, stop.Y - dv.Y, stop.Z - dv.Z);
- gl.Vertex3f(start.X - dv.X, start.Y - dv.Y, start.Z - dv.Z);
- gl.End_;
- end;
- procedure TGLLinePFXManager.EndParticles(var rci: TGLRenderContextInfo);
- begin
- UnapplyBlendingMode(rci);
- end;
- procedure TGLLinePFXManager.FinalizeRendering(var rci: TGLRenderContextInfo);
- begin
- inherited;
- end;
- function TGLLinePFXManager.StoreDefaultLength: Boolean;
- begin
- Result := (FDefaultLength <> 1);
- end;
- // ------------------
- // ------------------ TGLLineParticle ------------------
- // ------------------
- procedure TGLLineParticle.WriteToFiler(writer: TGLVirtualWriter);
- begin
- inherited WriteToFiler(writer);
- with writer do
- begin
- WriteInteger(0); // Archive Version 0
- Write(FDirection, SizeOf(FDirection));
- WriteFloat(FLength);
- end;
- end;
- procedure TGLLineParticle.ReadFromFiler(reader: TGLVirtualReader);
- var
- archiveVersion: Integer;
- begin
- inherited ReadFromFiler(reader);
- archiveVersion := reader.ReadInteger;
- if archiveVersion = 0 then
- with reader do
- begin
- Read(FDirection, SizeOf(FDirection));
- FLength := ReadFloat;
- end
- else
- RaiseFilerException(archiveVersion);
- end;
- // ------------------------------------------------------------------
- initialization
- // ------------------------------------------------------------------
- RegisterClasses([TGLLineParticle, TGLLinePFXManager]);
- end.
|