unit typeParticle; interface uses typeVector, typeColor, typeRendrer; type TParticle = class(TObject) private FCreated: int64; FLastFrame: int64; FPosition: T3DVector; FVelocity: T3DVector; FUp: T3DVector; FTimeToLive: int64; FColor: TColorFA; public constructor Create(const CurrentFrame: int64); procedure Update(const CurrentFrame: int64); function IsDead(const Frame: int64): boolean; function Age(const Frame: int64): int64; function RelativeAge(const Frame: int64): double; property Position: T3DVector read FPosition write FPosition; property Velocity: T3DVector read FVelocity write FVelocity; property Up: T3DVector read FUp write FUp; property Color: TColorFA read FColor write FColor; property TimeToLive: int64 read FTimeToLive write FTimeToLive; end; TVisualParticle = class(TParticle, IRenderItem) protected function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; public procedure Render; end; implementation uses windows, dglOpenGL, Math; { TParticle } function TParticle.Age(const Frame: int64): int64; begin Result := Frame - FCreated; end; constructor TParticle.Create(const CurrentFrame: int64); begin FPosition := T3DVector.Create(0, 0, 0); FVelocity := T3DVector.Create(0, 0, 0); FUp := T3DVector.Create(0, 1, 0); FColor := TColorFA.Create(0, 0, 0); FCreated := CurrentFrame; FLastFrame := FCreated; FTimeToLive := 20 * 1000; end; function TParticle.IsDead(const Frame: int64): boolean; begin result := (Frame - FCreated) > FTimeToLive; end; function TParticle.RelativeAge(const Frame: int64): double; begin result := Age(Frame) / TimeToLive; end; procedure TParticle.Update(const CurrentFrame: int64); var delta: Single; begin delta := CurrentFrame - FLastFrame; FPosition := FPosition + (FVelocity * delta); FColor.Alpha := 1 - RelativeAge(CurrentFrame); FLastFrame := CurrentFrame; end; { TVisualParticle } function TVisualParticle.QueryInterface(const IID: TGUID; out Obj): HResult; begin if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE; end; procedure TVisualParticle.Render; begin glPushMatrix(); glTranslatef(Position.x, Position.y, Position.z); glBegin(GL_TRIANGLES); glColor4f(Color.Red, Color.Green, Color.Blue, Color.Alpha); glVertex3f(-0.1,-0.1, 0); glVertex3f( 0.1,-0.1, 0); glVertex3f( 0.0, 0.1, 0); glEnd; glPopMatrix; end; function TVisualParticle._AddRef: Integer; begin result := 1; end; function TVisualParticle._Release: Integer; begin result := 1; end; end.