Ignore:
Timestamp:
Apr 9, 2015, 9:58:36 PM (9 years ago)
Author:
chronos
Message:
  • Fixed: Use csOpaque control style also to Image, PaintBox and OpenGLControl.
  • Modified: Change size of test frame with SpinEdits as delayed using timer.
  • Updated: BRGABitmap package to version 8.1.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • GraphicTest/Packages/bgrabitmap/bgracoordpool3d.pas

    r452 r472  
    66
    77uses
    8   Classes, SysUtils, BGRABitmapTypes, BGRASSE;
     8  Classes, SysUtils, BGRABitmapTypes, BGRASSE, BGRAMatrix3D;
    99
    1010type
     
    1515    {32} projectedCoord: TPointF;
    1616    {40} InvZ: single;
    17     {44} used: longbool;
     17    {44} used: wordbool; customNormalUsed: wordbool;
    1818    {48} viewNormal: TPoint3D_128;
    19   end; {64}
    20 
    21   { TBGRACoordPool3D }
    22 
    23   TBGRACoordPool3D = class
     19    {64} customNormal: TPoint3D_128;
     20  end; {80}
     21
     22  PBGRANormalData3D = ^TBGRANormalData3D;
     23  TBGRANormalData3D = packed record
     24    {0} customNormal: TPoint3D_128;
     25    {16} viewNormal: TPoint3D_128;
     26    {32} used: longbool;
     27    {36} filler1,filler2,filler3: longword;
     28  end; {48}
     29
     30  { TBGRAGenericPool }
     31
     32  TBGRAGenericPool = class
    2433  private
    2534    FFirstFree: integer;
    26     FNbCoord,FCapacity: integer;
     35    FNbElements,FCapacity: integer;
     36    FElementSize: PtrInt;
     37    FUsedCapacity : integer;
     38    function GetElement(AIndex: integer): Pointer;
     39    procedure SetCapacity(ACapacity: integer);
     40  protected
    2741    FPoolData: TMemoryBlockAlign128;
    28     FUsedCapacity : integer;
    29     function GetCoordData(AIndex: integer): PBGRACoordData3D;
    30     procedure SetCapacity(ACapacity: integer);
     42    function GetUsed({%H-}AElement: integer): boolean; virtual;
     43    procedure SetUsed({%H-}AElement: integer; {%H-}AUsed: boolean); virtual;
     44    procedure Remove(AIndex: integer); //does not work if GetUsed/SetUsed are not implemented
    3145  public
    32     constructor Create(ACapacity: integer);
     46    constructor Create(ACapacity: integer; AElementSize: integer);
    3347    destructor Destroy; override;
    34     procedure Remove(AIndex: integer);
    3548    function Add: integer;
    36     property CoordData[AIndex: integer]: PBGRACoordData3D read GetCoordData;
     49    property Element[AIndex: integer]: Pointer read GetElement;
    3750    property Capacity: integer read FCapacity;
    3851    property UsedCapacity: integer read FUsedCapacity;
    3952  end;
    4053
     54  { TBGRACoordPool3D }
     55
     56  TBGRACoordPool3D = class(TBGRAGenericPool)
     57  private
     58    function GetCoordData(AIndex: integer): PBGRACoordData3D;
     59  protected
     60    function GetUsed(AElement: integer): boolean; override;
     61    procedure SetUsed(AElement: integer; AUsed: boolean); override;
     62  public
     63    procedure Remove(AIndex: integer);
     64    constructor Create(ACapacity: integer);
     65    procedure ComputeWithMatrix(const AMatrix: TMatrix3D; const AProjection: TProjection3D);
     66    property CoordData[AIndex: integer]: PBGRACoordData3D read GetCoordData;
     67  end;
     68
     69  { TBGRANormalPool3D }
     70
     71  TBGRANormalPool3D = class(TBGRAGenericPool)
     72  private
     73    function GetNormalData(AIndex: integer): PBGRANormalData3D;
     74  protected
     75    function GetUsed(AElement: integer): boolean; override;
     76    procedure SetUsed(AElement: integer; AUsed: boolean); override;
     77  public
     78    procedure Remove(AIndex: integer);
     79    constructor Create(ACapacity: integer);
     80    procedure ComputeWithMatrix(const AMatrix: TMatrix3D);
     81    property NormalData[AIndex: integer]: PBGRANormalData3D read GetNormalData;
     82  end;
     83
    4184implementation
    4285
    43 { TBGRACoordPool3D }
    44 
    45 procedure TBGRACoordPool3D.SetCapacity(ACapacity: integer);
     86{ TBGRAGenericPool }
     87
     88function TBGRAGenericPool.GetElement(AIndex: integer): Pointer;
     89begin
     90  result := Pointer(PByte(FPoolData.Data)+AIndex*FElementSize);
     91end;
     92
     93procedure TBGRAGenericPool.SetCapacity(ACapacity: integer);
    4694var NewPoolData: TMemoryBlockAlign128;
    4795begin
     
    52100    else
    53101    begin
    54       NewPoolData := TMemoryBlockAlign128.Create(ACapacity*sizeof(TBGRACoordData3D));
     102      NewPoolData := TMemoryBlockAlign128.Create(ACapacity*FElementSize);
    55103      if FCapacity <> 0 then
    56104      begin
     
    58106        if FCapacity < ACapacity then
    59107        begin
    60           move(FPoolData.Data^, NewPoolData.Data^, FCapacity*sizeof(TBGRACoordData3D));
     108          move(FPoolData.Data^, NewPoolData.Data^, FCapacity*FElementSize);
    61109          //pad with zeros
    62           fillchar((pbyte(NewPoolData.Data)+FCapacity*sizeof(TBGRACoordData3D))^,(ACapacity-FCapacity)*sizeof(TBGRACoordData3D),0);
     110          fillchar((pbyte(NewPoolData.Data)+FCapacity*FElementSize)^,(ACapacity-FCapacity)*FElementSize,0);
    63111        end
    64112        else //previous block is greater or equal
    65           move(FPoolData.Data^, NewPoolData.Data^, ACapacity*sizeof(TBGRACoordData3D));
     113          move(FPoolData.Data^, NewPoolData.Data^, ACapacity*FElementSize);
    66114        FreeAndNil(FPoolData);
    67115      end else
    68116       //clear new block
    69         fillchar(pbyte(NewPoolData.Data)^,ACapacity*sizeof(TBGRACoordData3D),0);
     117        fillchar(pbyte(NewPoolData.Data)^,ACapacity*FElementSize,0);
    70118
    71119      FPoolData := NewPoolData;
     
    75123end;
    76124
    77 constructor TBGRACoordPool3D.Create(ACapacity: integer);
     125function TBGRAGenericPool.GetUsed(AElement: integer): boolean;
     126begin
     127  result := false;
     128end;
     129
     130procedure TBGRAGenericPool.SetUsed(AElement: integer; AUsed: boolean);
     131begin
     132  //nothing
     133end;
     134
     135constructor TBGRAGenericPool.Create(ACapacity: integer; AElementSize: integer);
    78136begin
    79137  FCapacity := 0;
    80138  FPoolData := nil;
    81   FNbCoord:= 0;
     139  FNbElements:= 0;
    82140  FFirstFree := 0;
    83141  FUsedCapacity := 0;
     142  FElementSize:= AElementSize;
    84143  SetCapacity(ACapacity);
    85144end;
    86145
    87 destructor TBGRACoordPool3D.Destroy;
    88 begin
    89   FPoolData.Free;
     146destructor TBGRAGenericPool.Destroy;
     147begin
     148  FreeAndNil(FPoolData);
     149  FCapacity := 0;
     150  FNbElements:= 0;
     151  FFirstFree := 0;
     152  FUsedCapacity := 0;
    90153  inherited Destroy;
    91154end;
    92155
    93 procedure TBGRACoordPool3D.Remove(AIndex: integer);
    94 begin
    95   if CoordData[AIndex]^.used then
    96   begin
    97     CoordData[AIndex]^.used := false;
     156procedure TBGRAGenericPool.Remove(AIndex: integer);
     157begin
     158  if (AIndex < 0) or (AIndex >= FUsedCapacity) then
     159    raise ERangeError.Create('Index out of bounds');
     160  if GetUsed(AIndex) then
     161  begin
     162    SetUsed(AIndex, false);
    98163    if AIndex < FFirstFree then FFirstFree := AIndex;
    99164    if AIndex = FUsedCapacity-1 then
    100165    begin
    101       while (FUsedCapacity > 0) and not CoordData[FUsedCapacity-1]^.used do
     166      while (FUsedCapacity > 0) and not GetUsed(FUsedCapacity-1) do
    102167        dec(FUsedCapacity);
    103168    end;
     
    105170end;
    106171
    107 function TBGRACoordPool3D.Add: integer;
     172function TBGRAGenericPool.Add: integer;
    108173begin
    109174  //check for free space
    110175  while FFirstFree < FCapacity do
    111176  begin
    112     if not CoordData[FFirstFree]^.used then
    113     begin
    114       CoordData[FFirstFree]^.used := false;
     177    if not GetUsed(FFirstFree) then
     178    begin
     179      SetUsed(FFirstFree,True);
    115180      result := FFirstFree;
    116181      inc(FFirstFree);
     
    124189  //no free space
    125190  SetCapacity(FCapacity*2+8);
    126   CoordData[FFirstFree]^.used := false;
     191  SetUsed(FFirstFree, true);
    127192  result := FFirstFree;
    128193  inc(FFirstFree);
     
    131196end;
    132197
     198{ TBGRACoordPool3D }
     199
     200constructor TBGRACoordPool3D.Create(ACapacity: integer);
     201begin
     202  inherited Create(ACapacity,SizeOf(TBGRACoordData3D));
     203end;
     204
     205procedure TBGRACoordPool3D.ComputeWithMatrix(const AMatrix: TMatrix3D;
     206  const AProjection: TProjection3D);
     207var
     208  P: PBGRACoordData3D;
     209  I: NativeInt;
     210begin
     211  if UsedCapacity = 0 then exit;
     212  P := PBGRACoordData3D(FPoolData.Data);
     213  {$IFDEF CPUI386}
     214  {$asmmode intel}
     215  if UseSSE then
     216  begin
     217    Matrix3D_SSE_Load(AMatrix);
     218    asm
     219      mov eax,[AProjection]
     220      movups xmm4,[eax]
     221      xorps xmm1,xmm1
     222    end;
     223    i := UsedCapacity;
     224    if UseSSE3 then
     225    begin
     226      while i > 0 do
     227      with P^ do
     228      begin
     229        if used then
     230        begin
     231          MatrixMultiplyVect3D_SSE3_Aligned(sceneCoord,viewCoord);
     232          if viewCoord.z > 0 then
     233          begin
     234            asm
     235              mov eax, P
     236              movaps xmm3, [eax+16] //viewCoord
     237              movaps xmm2,xmm3
     238              shufps xmm2,xmm3,2+8+32+128
     239              rcpps xmm2,xmm2  //xmm2 = InvZ
     240              movss [eax+40],xmm2 //-> InvZ
     241
     242              mulps xmm3,xmm4  //xmm3 *= Projection.Zoom
     243              mulps xmm3,xmm2  //xmm3 *= InvZ
     244
     245              movhlps xmm0,xmm4  //xmm0 = Projection.Center
     246              addps xmm3,xmm0  //xmm3 += Projection.Center
     247
     248              movlps [eax+32],xmm3 //->projectedCoord
     249              movaps [eax+48],xmm1 //->normal
     250            end;
     251          end else
     252          asm
     253            mov eax, P
     254            movlps [eax+32],xmm1  //0->projectedCoord
     255            movaps [eax+48],xmm1 //->normal
     256          end;
     257          if customNormalUsed then
     258            MatrixMultiplyVect3DWithoutTranslation_SSE3_Aligned(customNormal,viewNormal);
     259        end;
     260        dec(i);
     261        inc(p);
     262      end;
     263    end else
     264    begin
     265      while i > 0 do
     266      with P^ do
     267      begin
     268        if used then
     269        begin
     270          MatrixMultiplyVect3D_SSE_Aligned(sceneCoord,viewCoord);
     271          if viewCoord.z > 0 then
     272          begin
     273            asm
     274              mov eax, P
     275              movaps xmm3, [eax+16] //viewCoord
     276              movaps xmm2,xmm3
     277              shufps xmm2,xmm3,2+8+32+128
     278              rcpps xmm2,xmm2  //xmm2 = InvZ
     279              movss [eax+40],xmm2 //-> InvZ
     280
     281              mulps xmm3,xmm4  //xmm3 *= Projection.Zoom
     282              mulps xmm3,xmm2  //xmm3 *= InvZ
     283
     284              movhlps xmm0,xmm4  //xmm0 = Projection.Center
     285              addps xmm3,xmm0  //xmm3 += Projection.Center
     286
     287              movlps [eax+32],xmm3 //->projectedCoord
     288              movaps [eax+48],xmm1 //->normal
     289            end;
     290          end else
     291          asm
     292            mov eax, P
     293            movlps [eax+32],xmm1  //0 ->projectedCoord
     294            movaps [eax+48],xmm1 //->normal
     295          end;
     296          if customNormalUsed then
     297            MatrixMultiplyVect3DWithoutTranslation_SSE_Aligned(customNormal,viewNormal);
     298        end;
     299        dec(i);
     300        inc(p);
     301      end;
     302    end;
     303  end
     304  else
     305  {$ENDIF}
     306  begin
     307    i := UsedCapacity;
     308    while i > 0 do
     309    with P^ do
     310    begin
     311      if used then
     312      begin
     313        viewCoord := AMatrix*sceneCoord;
     314        if customNormalUsed then
     315          viewNormal := MultiplyVect3DWithoutTranslation(AMatrix,customNormal)
     316        else
     317          ClearPoint3D_128(viewNormal);
     318        if viewCoord.z > 0 then
     319        begin
     320          InvZ := 1/viewCoord.z;
     321          projectedCoord := PointF(viewCoord.x*InvZ*AProjection.Zoom.x + AProjection.Center.x,
     322                                   viewCoord.y*InvZ*AProjection.Zoom.Y + AProjection.Center.y);
     323        end else
     324          projectedCoord := PointF(0,0);
     325      end;
     326      dec(i);
     327      inc(p);
     328    end;
     329  end;
     330end;
     331
    133332function TBGRACoordPool3D.GetCoordData(AIndex: integer): PBGRACoordData3D;
    134333begin
     
    136335end;
    137336
     337function TBGRACoordPool3D.GetUsed(AElement: integer): boolean;
     338begin
     339  Result:= CoordData[AElement]^.used;
     340end;
     341
     342procedure TBGRACoordPool3D.SetUsed(AElement: integer; AUsed: boolean);
     343begin
     344  CoordData[AElement]^.used := AUsed;
     345end;
     346
     347procedure TBGRACoordPool3D.Remove(AIndex: integer);
     348begin
     349  inherited Remove(AIndex);
     350end;
     351
     352{ TBGRANormalPool3D }
     353
     354function TBGRANormalPool3D.GetNormalData(AIndex: integer): PBGRANormalData3D;
     355begin
     356  result := PBGRANormalData3D(FPoolData.Data)+AIndex;
     357end;
     358
     359function TBGRANormalPool3D.GetUsed(AElement: integer): boolean;
     360begin
     361  Result:= NormalData[AElement]^.used;
     362end;
     363
     364procedure TBGRANormalPool3D.SetUsed(AElement: integer; AUsed: boolean);
     365begin
     366  NormalData[AElement]^.used := AUsed;
     367end;
     368
     369procedure TBGRANormalPool3D.Remove(AIndex: integer);
     370begin
     371  inherited Remove(AIndex);
     372end;
     373
     374constructor TBGRANormalPool3D.Create(ACapacity: integer);
     375begin
     376  inherited Create(ACapacity,SizeOf(TBGRANormalData3D));
     377end;
     378
     379procedure TBGRANormalPool3D.ComputeWithMatrix(const AMatrix: TMatrix3D);
     380var
     381  P: PBGRANormalData3D;
     382  I: NativeInt;
     383begin
     384  if UsedCapacity = 0 then exit;
     385  P := PBGRANormalData3D(FPoolData.Data);
     386  {$IFDEF CPUI386}
     387  {$asmmode intel}
     388  if UseSSE then
     389  begin
     390    Matrix3D_SSE_Load(AMatrix);
     391    i := UsedCapacity;
     392    if UseSSE3 then
     393    begin
     394      while i > 0 do
     395      with P^ do
     396      begin
     397        if used then
     398          MatrixMultiplyVect3DWithoutTranslation_SSE3_Aligned(customNormal,viewNormal);
     399        dec(i);
     400        inc(p);
     401      end;
     402    end else
     403    begin
     404      while i > 0 do
     405      with P^ do
     406      begin
     407        if used then
     408          MatrixMultiplyVect3DWithoutTranslation_SSE_Aligned(customNormal,viewNormal);
     409        dec(i);
     410        inc(p);
     411      end;
     412    end;
     413  end
     414  else
     415  {$ENDIF}
     416  begin
     417    i := UsedCapacity;
     418    while i > 0 do
     419    with P^ do
     420    begin
     421      if used then
     422        viewNormal := MultiplyVect3DWithoutTranslation(AMatrix,customNormal);
     423      dec(i);
     424      inc(p);
     425    end;
     426  end;
     427end;
     428
    138429end.
    139430
Note: See TracChangeset for help on using the changeset viewer.