Unit Unit1;
{$mode objfpc}{$H+}
{$DEFINE USE_ASM}
{.$DEFINE USE_SSE_ASM}
{$DEFINE USE_AVX_ASM}
{$MODESWITCH ADVANCEDRECORDS}
Interface
Uses
Classes, Sysutils, Fileutil, Forms, Controls, Graphics, Dialogs, StdCtrls;
Type
{ Tform1 }
Tform1 = Class(Tform)
Button1 : Tbutton;
Memo1 : Tmemo;
Procedure Button1click(Sender : Tobject);
Private
Public
End;
type
TGLZVector3fType = array[0..2] of Single;
TGLZVector4fType = array[0..3] of Single;
TGLZVector3f = record
case Byte of
0: (X, Y, Z: Single);
1: (V: TGLZVector3fType);
End;
TGLZVector4f = record
public
procedure Create(Const aX,aY,aZ,aW : Single);
function ToString : String;
class operator +(constref A, B: TGLZVector4f): TGLZVector4f; overload;
class operator -(constref A, B: TGLZVector4f): TGLZVector4f; overload;
class operator *(constref A, B: TGLZVector4f): TGLZVector4f; overload;
class operator /(constref A, B: TGLZVector4f): TGLZVector4f; overload;
class operator +(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; overload;
class operator -(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; overload;
class operator *(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; overload;
class operator /(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; overload;
case Byte of
0: (X, Y, Z, W: Single);
1: (V: TGLZVector4fType);
2: (AsVector3f : TGLZVector3f);
end;
Var
Form1 : Tform1;
Implementation
{$R *.lfm}
{ Tform1 }
Procedure Tform1.Button1click(Sender : Tobject);
Var
V1, V2, V3 : TGLZVector4f;
Float : Single;
Begin
Float := 1.5;
v1.Create(5.0,5.0,5.0,0.5);
v2.Create(2.5,2.5,2.5,0.5);
Memo1.Lines.Add('V1 = '+v1.ToString);
Memo1.Lines.Add('V2 = '+v2.ToString);
Memo1.Lines.Add('Float = 1.5');
Memo1.Lines.Add('');
Memo1.Lines.Add('Operations : ');
Memo1.Lines.Add('----------------------------------------');
V3 := V1 + V2;
Memo1.Lines.Add('V3 = V1 + V2 = '+v3.ToString);
V3 := V1 - V2;
Memo1.Lines.Add('V3 = V1 - V2 = '+v3.ToString);
V3 := V1 * V2;
Memo1.Lines.Add('V3 = V1 * V2 = '+v3.ToString);
V3 := V1 / V2;
Memo1.Lines.Add('V3 = V1 / V2 = '+v3.ToString);
Memo1.Lines.Add('----------------------------------------');
V3 := V1 + Float;
Memo1.Lines.Add('V3 = V1 + Float = '+v3.ToString);
V3 := V1 - Float;
Memo1.Lines.Add('V3 = V1 - Float = '+v3.ToString);
V3 := V1 * Float;
Memo1.Lines.Add('V3 = V1 * Float = '+v3.ToString);
V3 := V1 / Float;
Memo1.Lines.Add('V3 = V1 / Float = '+v3.ToString);
End;
procedure TGLZVector4f.Create(Const aX,aY,aZ,aW : Single);
begin
Self.X := AX;
Self.Y := AY;
Self.Z := AZ;
Self.W := AW;
end;
function TGLZVector4f.ToString : String;
begin
Result := '(X: '+FloattoStrF(Self.X,fffixed,5,5)+
' ,Y: '+FloattoStrF(Self.Y,fffixed,5,5)+
' ,Z: '+FloattoStrF(Self.Z,fffixed,5,5)+
' ,W: '+FloattoStrF(Self.W,fffixed,5,5)+')';
End;
{$IFDEF USE_ASM}
{$IFDEF USE_AVX_ASM}
class operator TGLZVector4f.+(constref A, B: TGLZVector4f): TGLZVector4f; assembler;
asm
VMOVUPS XMM0,[A]
VMOVUPS XMM1,[B]
VADDPS XMM0,XMM1, XMM0
VMOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f.-(constref A, B: TGLZVector4f): TGLZVector4f; assembler;
asm
VMOVUPS XMM0,[A]
VMOVUPS XMM1,[B]
VSUBPS XMM0,XMM1, XMM0
VMOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f.*(constref A, B: TGLZVector4f): TGLZVector4f; assembler;
asm
VMOVUPS XMM0,[A]
VMOVUPS XMM1,[B]
VMULPS XMM0,XMM1, XMM0
VMOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f./(constref A, B: TGLZVector4f): TGLZVector4f; assembler;
asm
VMOVUPS XMM0,[A]
VMOVUPS XMM1,[B]
VDIVPS XMM0,XMM1, XMM0
VMOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f.+(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; assembler;
asm
VMOVUPS XMM0,[A]
VMOVSS XMM1,[B]
VSHUFPS XMM1, XMM1, XMM1,0
VADDPS XMM0,XMM1, XMM0
VMOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f.-(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; assembler;
asm
VMOVUPS XMM0,[A]
VMOVSS XMM1,[B]
VSHUFPS XMM1, XMM1, XMM1,0
VSUBPS XMM0,XMM1, XMM0
VMOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f.*(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; assembler;
asm
VMOVUPS XMM0,[A]
VMOVSS XMM1,[B]
VSHUFPS XMM1, XMM1, XMM1,0
VMULPS XMM0,XMM1, XMM0
VMOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f./(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; assembler;
asm
VMOVUPS XMM0,[A]
VMOVSS XMM1,[B]
VSHUFPS XMM1, XMM1, XMM1,0
VDIVPS XMM0,XMM1, XMM0
VMOVUPS [RESULT], XMM0
end;
{$ENDIF}
{$IFDEF USE_SSE_ASM}
class operator TGLZVector4f.+(constref A, B: TGLZVector4f): TGLZVector4f; assembler;
asm
MOVUPS XMM0,[A]
MOVUPS XMM1,[B]
ADDPS XMM0,XMM1
MOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f.-(constref A, B: TGLZVector4f): TGLZVector4f; assembler;
asm
MOVUPS XMM0,[A]
MOVUPS XMM1,[B]
SUBPS XMM0,XMM1
MOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f.*(constref A, B: TGLZVector4f): TGLZVector4f; assembler;
asm
MOVUPS XMM0,[A]
MOVUPS XMM1,[B]
MULPS XMM0,XMM1
MOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f./(constref A, B: TGLZVector4f): TGLZVector4f; assembler;
asm
MOVUPS XMM0,[A]
MOVUPS XMM1,[B]
DIVPS XMM0,XMM1
MOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f.+(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; assembler;
asm
MOVUPS XMM0,[A]
MOVSS XMM1,[B]
SHUFPS XMM1, XMM1,0
ADDPS XMM0,XMM1
MOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f.-(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; assembler;
asm
MOVUPS XMM0,[A]
MOVSS XMM1,[B]
SHUFPS XMM1, XMM1,0
SUBPS XMM0,XMM1
MOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f.*(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; assembler;
asm
MOVUPS XMM0,[A]
MOVSS XMM1,[B]
SHUFPS XMM1, XMM1,0
MULPS XMM0,XMM1
MOVUPS [RESULT], XMM0
end;
class operator TGLZVector4f./(constref A: TGLZVector4f; constref B:Single): TGLZVector4f; assembler;
asm
MOVUPS XMM0,[A]
MOVSS XMM1,[B]
SHUFPS XMM1, XMM1,0
DIVPS XMM0,XMM1
MOVUPS [RESULT], XMM0
end;
{$ENDIF}
{$ELSE}
class operator TGLZVector4f.+(constref A, B: TGLZVector4f): TGLZVector4f;
begin
Result.X := A.X + B.X;
Result.X := A.Y + B.Y;
Result.X := A.Z + B.Z;
Result.X := A.W + B.W;
end;
{$ENDIF}