Das ist eine einfache Ausführung, kann aber als Fundament für erweiterte Programmierung genutzt werden.
Geprüft werden die FPS-Beschleunigung, Windows LineTo Api und der Algorithmus der Grafikberechnung.
Es wird benötigt : 3xImage, 3xButton, 1xTimer
Der Timer sollte auf 1 (ms) gestellt werden und die Images müssen dementsprechend umbenannt werden, um den Code anzuwenden.
Die Image "ImgScene" prüft die FPS und sollte ein Bitmap mit 24 oder 32 Bitpixel beinhalten.
Unit uBmpLine.pas
unit uBmpLine;
INTERFACE
uses Windows, Graphics, Dialogs, Types;
type
TColorRec = record
case integer of
0 : ( Color : TColor );
1 : ( R,G,B,A : Byte );
end;
TBmpMemInfos = record
BpP,
BpL,
Scan0,
W,
H : Integer;
HDC : THandle;
end;
TBmp24Line = Array of pRGBTriple;
TBmp32Line = Array of pRGBQuad;
TBmp24LineCol = Array of TRGBTriple;
TBmp32LineCol = Array of TRGBQuad;
var
gBmpCol : TColorRec;
function BmpGetMemInfos(BMP: TBitmap; var Infos: TBmpMemInfos): Boolean;
procedure BmpMoveTo (Infos: TBmpMemInfos; X,Y: Integer);
procedure Bmp24LineTo(Infos: TBmpMemInfos; x2,y2: Integer);
procedure Bmp32LineTo(Infos: TBmpMemInfos; x2,y2: Integer);
procedure BmpGetLine (Infos: TBmpMemInfos; var LineArray: TBmp24Line; x1,y1,x2,y2: Integer; DrawLastPt: Boolean = true); overload;
procedure BmpGetLine (Infos: TBmpMemInfos; var LineArray: TBmp32Line; x1,y1,x2,y2: Integer; DrawLastPt: Boolean = true); overload;
procedure BmpGetCol (InfosDest, InfosSrc: TBmpMemInfos; LineArray: TBmp24Line; var ColArray: TBmp24LineCol); overload;
procedure BmpGetCol (InfosDest, InfosSrc: TBmpMemInfos; LineArray: TBmp32Line; var ColArray: TBmp32LineCol); overload;
IMPLEMENTATION
function ClipLine(var x1,y1,x2,y2: Integer; BmpXmax,BmpYmax: Integer; var DrawLastPt: Boolean): Boolean;
const
W : Integer = 1;
E : Integer = 2;
S : Integer = 4;
N : Integer = 8;
var
Region1, Region2 : Integer;
fx1,fy1,fx2,fy2 : Double;
begin
Result := false;
if y1<0 then Region1 := N else if y1>BmpYmax then Region1 := S else Region1 := 0;
if x1<0 then Region1 := (Region1 or W) else if x1>BmpXmax then Region1 := (Region1 or E);
if y2<0 then Region2 := N else if y2>BmpYmax then Region2 := S else Region2 := 0;
if x2<0 then Region2 := (Region2 or W) else if x2>BmpXmax then Region2 := (Region2 or E);
if (Region1 and Region2)<>0 then Exit;
DrawLastPt := Region2<>0;
if (Region1 or Region2)<>0 then begin
fx1 := x1;
fy1 := y1;
fx2 := x2;
fy2 := y2;
repeat
if (Region1 or Region2)=0 then begin
x1 := Round(fx1);
y1 := Round(fy1);
x2 := Round(fx2);
y2 := Round(fy2);
Break;
end;
if (Region1 and Region2)<>0 then Exit
else begin
if Region1<>0 then begin
if (Region1 and N)=N then begin
fx1:= fx1 + (fx1-fx2)*fy1/(fy2-fy1);
fy1:= 0; end
else if (Region1 and S)=S then begin
fx1:= fx1 + (fx2-fx1)*(BmpYmax-fy1)/(fy2-fy1);
fy1:= BmpYmax; end
else if (Region1 and E)=E then begin
fy1:= fy1 + (fy2-fy1)*(BmpXmax-fx1)/(fx2-fx1);
fx1:= BmpXmax; end
else begin
fy1:= fy1 + (fy1-fy2)*fx1/(fx2-fx1);
fx1:= 0; end;
if fy1<0 then Region1 := N else if fy1>BmpYmax then Region1 := S else Region1 := 0;
if fx1<0 then Region1 := (Region1 or W) else if fx1>BmpXmax then Region1 := (Region1 or E);
end
else begin
if (Region2 and N)= N then begin
fx2 := fx1 + (fx1-fx2)*fy1/(fy2-fy1);
fy2 := 0; end
else if (Region2 and S)=S then begin
fx2 := fx1 + (fx2-fx1)*(BmpYmax-fy1)/(fy2-fy1);
fy2 := BmpYmax; end
else if (Region2 and E)=E then begin
fy2 := fy1 + (fy2-fy1)*(BmpXmax-fx1)/(fx2-fx1);
fx2 := BmpXmax; end
else begin
fy2 := fy1 + (fy1-fy2)*fx1/(fx2-fx1);
fx2 := 0; end;
if fy2<0 then Region2 := N else if fy2>BmpYmax then Region2 := S else Region2 := 0;
if fx2<0 then Region2 := (Region2 or W) else if fx2>BmpXmax then Region2 := (Region2 or E);
end;
end;
until false;
end;
Result := true;
end;
function BmpGetMemInfos(BMP: TBitmap; var Infos: TBmpMemInfos): Boolean;
begin
Result := true;
case BMP.PixelFormat of
pf24bit : Infos.BpP := 3;
pf32bit : Infos.BpP := 4;
else begin
ShowMessage('Bitmap format not supported !'#10#10'(pf24bit or pf32bit only)');
Result := false;
Exit;
end;
end;
Infos.W := BMP.Width;
Infos.H := BMP.Height;
if (Infos.W<>0) and (Infos.H<>0) and (BMP<>nil) then begin
Infos.Scan0 := Integer(BMP.ScanLine[0]);
Infos.BpL := (((BMP.Width * Infos.BpP shl 3) + 31) and -31) shr 3; end
else begin
ShowMessage('One or two dimensions of the Bitmap are zero !');
Result := false;
Exit;
end;
if (BMP.Height>1) and (Integer(BMP.ScanLine[1])-Infos.Scan0>0) then begin
ShowMessage('Top-Down DIB not supported !'#10#10'(Bottom-Up DIB only)');
Result := false;
Exit;
end;
Infos.HDC := BMP.Canvas.Handle;
end;
procedure BmpMoveTo(Infos: TBmpMemInfos; X,Y: Integer);
begin
MoveToEx(Infos.HDC,X,Y,nil);
end;
procedure Bmp24LineTo(Infos: TBmpMemInfos; x2,y2: Integer);
var
DrawLastPt : Boolean;
de,dx,dy : Integer;
x1,y1 : Integer;
Pt1 : TPoint;
Col3 : TRGBTriple;
pPix3 : pRGBTriple;
MemLineSize: Integer;
MemPixSize : Integer;
PixelNbr : Integer;
begin
MoveToEx(Infos.HDC,x2,y2,@Pt1);
x1 := Pt1.X;
y1 := Pt1.Y;
if not ClipLine(x1,y1,x2,y2,Infos.W-1,Infos.H-1,DrawLastPt) then Exit;
if x2<x1 then begin
dx := x1-x2;
MemPixSize := -Infos.BpP end
else begin
dx := x2-x1;
MemPixSize := Infos.BpP;
end;
if y2<y1 then begin
dy := y1-y2;
MemLineSize := -Infos.BpL; end
else begin
dy := y2-y1;
MemLineSize := Infos.BpL
end;
Col3.rgbtRed := gBmpCol.R;
Col3.rgbtGreen:= gBmpCol.G;
Col3.rgbtBlue := gBmpCol.B;
pPix3 := pRGBTriple(Infos.Scan0 - y1*Infos.BpL + x1*3);
if dx>=dy then begin
de := dx;
dx := dx shl 1;
dy := dy shl 1;
for PixelNbr := 1 to de do begin
pPix3^ := Col3;
Inc(Integer(pPix3),MemPixSize);
Dec(de,dy);
if de<0 then begin
Dec(Integer(pPix3),MemLineSize);
Inc(de,dx);
end;
end; end
else begin
de := dy;
dy := dy shl 1;
dx := dx shl 1;
for PixelNbr := 1 to de do begin
pPix3^ := Col3;
Dec(Integer(pPix3),MemLineSize);
Dec(de,dx);
if de<0 then begin
Inc(Integer(pPix3),MemPixSize);
Inc(de,dy);
end;
end;
end;
if DrawLastPt then pPix3^ := Col3;
end;
procedure Bmp32LineTo(Infos: TBmpMemInfos; x2,y2: Integer);
var
DrawLastPt : Boolean;
de,dx,dy : Integer;
x1,y1 : Integer;
Pt1 : TPoint;
Col4 : TRGBQuad;
pPix4 : pRGBQuad;
MemLineSize: Integer;
MemPixSize : Integer;
PixelNbr : Integer;
begin
MoveToEx(Infos.HDC,x2,y2,@Pt1);
x1 := Pt1.X;
y1 := Pt1.Y;
if not ClipLine(x1,y1,x2,y2,Infos.W-1,Infos.H-1,DrawLastPt) then Exit;
if x2<x1 then begin
dx := x1-x2;
MemPixSize := -Infos.BpP end
else begin
dx := x2-x1;
MemPixSize := Infos.BpP;
end;
if y2<y1 then begin
dy := y1-y2;
MemLineSize := -Infos.BpL; end
else begin
dy := y2-y1;
MemLineSize := Infos.BpL
end;
with Col4 do begin
rgbRed := gBmpCol.R;
rgbGreen := gBmpCol.G;
rgbBlue := gBmpCol.B;
rgbReserved := gBmpCol.A;
end;
pPix4 := pRGBQuad(Infos.Scan0 - y1*Infos.BpL + x1*4);
if dx>=dy then begin
de := dx;
dx := dx shl 1;
dy := dy shl 1;
for PixelNbr := 1 to de do begin
pPix4^ := Col4;
Inc(Integer(pPix4),MemPixSize);
Dec(de,dy);
if de<0 then begin
Dec(Integer(pPix4),MemLineSize);
Inc(de,dx);
end;
end; end
else begin
de := dy;
dy := dy shl 1;
dx := dx shl 1;
for PixelNbr := 1 to de do begin
pPix4^ := Col4;
Dec(Integer(pPix4),MemLineSize);
Dec(de,dx);
if de<0 then begin
Inc(Integer(pPix4),MemPixSize);
Inc(de,dy);
end;
end;
end;
if DrawLastPt then pPix4^ := Col4;
end;
procedure BmpGetLine(Infos: TBmpMemInfos; var LineArray: TBmp24Line; x1,y1,x2,y2:
Integer; DrawLastPt: Boolean = true); overload;
var
de,dx,dy : Integer;
pPix3 : pRGBTriple;
MemLineSize: Integer;
MemPixSize : Integer;
PixelNbr : Integer;
begin
if not ClipLine(x1,y1,x2,y2,Infos.W-1,Infos.H-1,DrawLastPt) then Exit;
if x2<x1 then begin
dx := x1-x2;
MemPixSize := -Infos.BpP end
else begin
dx := x2-x1;
MemPixSize := Infos.BpP;
end;
if y2<y1 then begin
dy := y1-y2;
MemLineSize := -Infos.BpL; end
else begin
dy := y2-y1;
MemLineSize := Infos.BpL
end;
pPix3 := pRGBTriple(Infos.Scan0 - y1*Infos.BpL + x1*3);
if dx>=dy then begin
if DrawLastPt then SetLength(LineArray,dx+1) else SetLength(LineArray,dx);
de := dx;
dx := dx shl 1;
dy := dy shl 1;
for PixelNbr := 0 to de-1 do begin
LineArray[PixelNbr] := pPix3;
Inc(Integer(pPix3),MemPixSize);
Dec(de,dy);
if de<0 then begin
Dec(Integer(pPix3),MemLineSize);
Inc(de,dx);
end;
end; end
else begin
if DrawLastPt then SetLength(LineArray,dy+1) else SetLength(LineArray,dy);
de := dy;
dy := dy shl 1;
dx := dx shl 1;
for PixelNbr := 0 to de-1 do begin
LineArray[PixelNbr] := pPix3;
Dec(Integer(pPix3),MemLineSize);
Dec(de,dx);
if de<0 then begin
Inc(Integer(pPix3),MemPixSize);
Inc(de,dy);
end;
end;
end;
if DrawLastPt then LineArray[High(LineArray)] := pPix3;
end;
procedure BmpGetLine(Infos: TBmpMemInfos; var LineArray: TBmp32Line; x1,y1,x2,y2:
Integer; DrawLastPt: Boolean = true); overload;
var
de,dx,dy : Integer;
pPix4 : pRGBQuad;
MemLineSize: Integer;
MemPixSize : Integer;
PixelNbr : Integer;
begin
if not ClipLine(x1,y1,x2,y2,Infos.W-1,Infos.H-1,DrawLastPt) then Exit;
if x2<x1 then begin
dx := x1-x2;
MemPixSize := -Infos.BpP end
else begin
dx := x2-x1;
MemPixSize := Infos.BpP;
end;
if y2<y1 then begin
dy := y1-y2;
MemLineSize := -Infos.BpL; end
else begin
dy := y2-y1;
MemLineSize := Infos.BpL
end;
pPix4 := pRGBQuad(Infos.Scan0 - y1*Infos.BpL + x1*4);
if dx>=dy then begin
if DrawLastPt then SetLength(LineArray,dx+1) else SetLength(LineArray,dx);
de := dx;
dx := dx shl 1;
dy := dy shl 1;
for PixelNbr := 0 to de-1 do begin
LineArray[PixelNbr] := pPix4;
Inc(Integer(pPix4),MemPixSize);
Dec(de,dy);
if de < 0 then begin
Dec(Integer(pPix4),MemLineSize);
Inc(de,dx);
end;
end; end
else begin
if DrawLastPt then SetLength(LineArray,dy+1) else SetLength(LineArray,dy);
de := dy;
dy := dy shl 1;
dx := dx shl 1;
for PixelNbr := 0 to de-1 do begin
LineArray[PixelNbr] := pPix4;
Dec(Integer(pPix4),MemLineSize);
Dec(de,dx);
if de < 0 then begin
Inc(Integer(pPix4),MemPixSize);
Inc(de,dy);
end;
end;
end;
if DrawLastPt then LineArray[High(LineArray)] := pPix4;
end;
procedure BmpGetCol (InfosDest,InfosSrc: TBmpMemInfos; LineArray: TBmp24Line; var ColArray: TBmp24LineCol); overload;
var
i, Shift : Integer;
begin
Shift := InfosSrc.Scan0 - InfosDest.Scan0;
SetLength(ColArray, Length(LineArray));
for i := 0 to High(ColArray) do ColArray[i] := pRGBTriple(Integer(LineArray[i]) + Shift)^;
end;
procedure BmpGetCol(InfosDest,InfosSrc: TBmpMemInfos; LineArray: TBmp32Line; var ColArray: TBmp32LineCol); overload;
var
i, Shift : Integer;
begin
Shift := InfosSrc.Scan0 - InfosDest.Scan0;
SetLength(ColArray, Length(LineArray));
for i := 0 to High(ColArray) do ColArray[i] := pRGBQuad(Integer(LineArray[i]) + Shift)^;
end;
END.
Algo de Bresenham brut en Delphi (pour pf32bit) :
procedure Bmp32BresenhamLineTo(var BmpInfo: TMemBmpInfos; x2,y2: Integer);
const
W : Integer = 1;
E : Integer = 2;
S : Integer = 4;
N : Integer = 8;
var
Region1, Region2 : Integer;
BmpXmax, BmpYmax : Integer;
fx1,fy1,fx2,fy2 : Double;
DrawLastPoint : Boolean;
de,dx,dy : Integer;
x1,y1 : Integer;
Col : TRGBQuad;
pPix : pRGBQuad;
MemLineSize : Integer;
MemPixSize : Integer;
i : Integer;
begin
with BmpInfo do begin
MoveToEx(HDC,x2,y2,@Pt1);
x1 := Pt1.X;
y1 := Pt1.Y;
BmpXmax := W-1;
BmpYmax := H-1;
end;
if y1<0 then Region1 := N else if y1>BmpYmax then Region1 := S else Region1 := 0;
if x1<0 then Region1 := (Region1 or W) else if x1>BmpXmax then Region1 := (Region1 or E);
if y2<0 then Region2 := N else if y2>BmpYmax then Region2 := S else Region2 := 0;
if x2<0 then Region2 := (Region2 or W) else if x2>BmpXmax then Region2 := (Region2 or E);
if (Region1 and Region2)<>0 then Exit;
DrawLastPoint := Region2<>0;
if (Region1 or Region2)<>0 then begin
fx1 := x1;
fy1 := y1;
fx2 := x2;
fy2 := y2;
repeat
if (Region1 or Region2)=0 then begin
x1 := Round(fx1);
y1 := Round(fy1);
x2 := Round(fx2);
y2 := Round(fy2);
Break;
end;
if (Region1 and Region2)<>0 then Exit
else begin
if Region1<>0 then begin
if (Region1 and N)=N then begin
fx1:= fx1 + (fx1-fx2)*fy1/(fy2-fy1);
fy1:= 0; end
else if (Region1 and S)=S then begin
fx1:= fx1 + (fx2-fx1)*(BmpYmax-fy1)/(fy2-fy1);
fy1:= BmpYmax; end
else if (Region1 and E)=E then begin
fy1:= fy1 + (fy2-fy1)*(BmpXmax-fx1)/(fx2-fx1);
fx1:= BmpXmax; end
else begin
fy1:= fy1 + (fy1-fy2)*fx1/(fx2-fx1);
fx1:= 0; end;
if fy1<0 then Region1 := N else if fy1>BmpYmax then Region1 := S else Region1 := 0;
if fx1<0 then Region1 := (Region1 or W) else if fx1>BmpXmax then Region1 := (Region1 or E);
end
else begin
if (Region2 and N)= N then begin
fx2 := fx1 + (fx1-fx2)*fy1/(fy2-fy1);
fy2 := 0; end
else if (Region2 and S)=S then begin
fx2 := fx1 + (fx2-fx1)*(BmpYmax-fy1)/(fy2-fy1);
fy2 := BmpYmax; end
else if (Region2 and E)=E then begin
fy2 := fy1 + (fy2-fy1)*(BmpXmax-fx1)/(fx2-fx1);
fx2 := BmpXmax; end
else begin
fy2 := fy1 + (fy1-fy2)*fx1/(fx2-fx1);
fx2 := 0; end;
if fy2<0 then Region2 := N else if fy2>BmpYmax then Region2 := S else Region2 := 0;
if fx2<0 then Region2 := (Region2 or W) else if fx2>BmpXmax then Region2 := (Region2 or E);
end;
end;
until false;
end;
Col.rgbRed := gBmpCol.R;
Col.rgbGreen := gBmpCol.G;
Col.rgbBlue := gBmpCol.B;
Col.rgbReserved := gBmpCol.A;
dx := x2-x1;
dy := y2-y1;
pPix := pRGBQuad(BmpInfo.Scan0 - y1*BmpInfo.BpL + x1*4);
MemLineSize := BmpInfo.BpL;
MemPixSize := BmpInfo.BpP;
if dy=0 then begin
if dx<0 then begin
for x1 := x1 downto x2+1 do begin
pPix^ := Col;
Dec(pPix);
end; end
else if dx>0 then begin
for x1 := x1 to x2-1 do begin
pPix^ := Col;
Inc(pPix);
end;
end;
if DrawLastPoint then pPix^ := Col;
Exit;
end;
if dx=0 then begin
if dy<0 then begin
for y1 := y1 downto y2+1 do begin
pPix^ := Col;
Inc(Integer(pPix), MemLineSize);
end; end
else begin
for y1 := y1 to y2-1 do begin
pPix^ := Col;
Dec(Integer(pPix), MemLineSize);
end;
end;
if DrawLastPoint then pPix^ := Col;
Exit;
end;
if dx<0 then begin
if dy>0 then begin
if dx+dy<=0 then begin
de := dx;
dx := dx shl 1;
dy := dy shl 1;
for i := 1 to -de do begin
pPix^ := Col;
Dec(Integer(pPix), MemPixSize);
Inc(de,dy);
if de >= 0 then begin
Dec(Integer(pPix), MemLineSize);
Inc(de,dx);
end;
end; end
else begin
de := dy;
dy := de shl 1;
dx := dx shl 1;
for i := 1 to de do begin
pPix^ := Col;
Dec(Integer(pPix), MemLineSize);
Inc(de,dx);
if de <= 0 then begin
Dec(Integer(pPix), MemPixSize);
Inc(de,dy);
end;
end;
end; end
else begin
if dx <= dy then begin
de := dx;
dx := de shl 1;
dy := dy shl 1;
for i := 1 to -de do begin
pPix^ := Col;
Dec(Integer(pPix), MemPixSize);
Dec(de,dy);
if de >= 0 then begin
Inc(Integer(pPix), MemLineSize);
Inc(de,dx);
end;
end; end
else begin
de := dy;
dy := de shl 1;
dx := dx shl 1;
for i := 1 to -de do begin
pPix^ := Col;
Inc(Integer(pPix), MemLineSize);
Dec(de,dx);
if de >= 0 then begin
Dec(Integer(pPix), MemPixSize);
Inc(de,dy);
end;
end;
end;
end; end
else begin
if dy>0 then begin
if dx>=dy then begin
de:= dx;
dx:= de shl 1;
dy:= dy shl 1;
for i := 1 to de do begin
pPix^ := Col;
Inc(Integer(pPix), MemPixSize);
Dec(de,dy);
if de<0 then begin
Dec(Integer(pPix), MemLineSize);
Inc(de,dx);
end;
end; end
else begin
de := dy;
dy := de shl 1;
dx := dx shl 1;
for i := 1 to de do begin
pPix^ := Col;
Dec(Integer(pPix), MemLineSize);
Dec(de,dx);
if de < 0 then begin
Inc(Integer(pPix), MemPixSize);
Inc(de,dy)
end;
end;
end; end
else begin
if dx+dy >= 0 then begin
de := dx;
dx := de shl 1;
dy := dy shl 1;
for i := 1 to de do begin
pPix^ := Col;
Inc(Integer(pPix), MemPixSize);
Inc(de,dy);
if de < 0 then begin
Inc(Integer(pPix), MemLineSize);
Inc(de,dx);
end;
end; end
else begin
de := dy;
dy := de shl 1;
dx := dx shl 1;
for i := 1 to -de do begin
pPix^ := Col;
Inc(Integer(pPix), MemLineSize);
Inc(de,dx);
if de > 0 then begin
Inc(Integer(pPix), MemPixSize);
Inc(de,dy);
end;
end;
end;
end;
end;
if DrawLastPoint then pPix^ := Col;
end;
Unit1 :
uses Math, uBmpLine
type
TRocket = record
TrajectoryArray : TBmp32Line;
TrajectColArray : TBmp32LineCol;
ProgressIndex : Integer;
end;
TFleet = array of TRocket;
const
XMAX = 400;
XMIN = -200;
YMAX = 400;
YMIN = -200;
TIMES = 1000000;
QROCKET : TRGBQuad = (rgbBlue: 100; rgbGreen: 100; rgbRed: 100; rgbReserved: 0);
QNOZZLE : TRGBQuad = (rgbBlue: 255; rgbGreen: 255; rgbRed: 255; rgbReserved: 0);
QFLAME : TRGBQuad = (rgbBlue: 70; rgbGreen: 128; rgbRed: 255; rgbReserved: 0);
var
gInitialScene : TBitmap;
gInitialSceneInfos : TBmpMemInfos;
gMyFleet : TFleet;
gVirtualTarget : TPoint = (X:0; Y:-10);
gFramesCount : Integer;
gFPStime : Int64;
//
procedure TForm1.btnAPITestClick(Sender: TObject);
var Btn : TButton absolute Sender;
Start, Elapsed : Int64;
i : Integer;
begin
imgAPI.Canvas.FillRect(imgAPI.Canvas.ClipRect);
imgAPI.Refresh;
Screen.Cursor := crHourGlass;
RandSeed := 0;
Start := GetTickCount;
for i := 1 to TIMES do begin
imgAPI.Canvas.Pen.Color := RandomRange(0,16777215);
Windows.LineTo(imgAPI.Canvas.Handle, RandomRange(XMIN,XMAX), RandomRange(YMIN,YMAX));
end;
Elapsed := GetTickCount-Start;
if Btn.Tag>Elapsed then begin
Btn.Tag := Elapsed;
Btn.Caption := Format('API Windows.LineTo' + #13#10 +'Temps mini : %.0n ms',[Elapsed/1]);
end;
imgAPI.Refresh;
Screen.Cursor := crDefault;
end;
procedure TForm1.btnALGOTestClick(Sender: TObject);
var Btn : TButton absolute Sender;
Infos : TBmpMemInfos;
Start, Elapsed : Int64;
i : Integer;
begin
imgALGO.Canvas.FillRect(imgALGO.Canvas.ClipRect);
imgALGO.Refresh;
if not BmpGetMemInfos(imgALGO.Picture.Bitmap, Infos) then Exit;
Screen.Cursor := crHourGlass;
RandSeed := 0;
Start := GetTickCount;
for i := 1 to TIMES do begin
gBmpCol.Color := RandomRange(0,16777215);
gBmpCol.A := 111;
if Infos.BpP=3
then Bmp24LineTo(Infos, RandomRange(XMIN,XMAX), RandomRange(YMIN,YMAX))
else Bmp32LineTo(Infos, RandomRange(XMIN,XMAX), RandomRange(YMIN,YMAX));
end;
Elapsed := GetTickCount-Start;
if Btn.Tag>Elapsed then begin
Btn.Tag := Elapsed;
Btn.Caption := Format('Delphi Algorithm LineTo' + #13#10 +'Temps mini : %.0n ms',[Elapsed/1]);
end;
imgALGO.Refresh;
Screen.Cursor := crDefault;
end;
procedure DoProgress;
var RocketIndex : Integer;
i, R, G, B : Integer;
QTrail : TRGBQuad;
FirstPix : Integer;
begin
RocketIndex := 0;
repeat
with gMyFleet[RocketIndex] do begin
if ProgressIndex<Length(TrajectoryArray) then TrajectoryArray[ProgressIndex]^ := QROCKET;
case ProgressIndex of
0 : TrajectoryArray[0]^ := QFLAME;
1..3: TrajectoryArray[ProgressIndex]^ := QROCKET;
4 : TrajectoryArray[1]^ := QNOZZLE;
5 : TrajectoryArray[2]^ := QNOZZLE;
6 : TrajectoryArray[3]^ := QNOZZLE;
7 : begin TrajectoryArray[4]^ := QNOZZLE;
TrajectoryArray[1]^ := QFLAME; end;
8 : begin TrajectoryArray[5]^ := QNOZZLE;
TrajectoryArray[2]^ := QFLAME; end;
9 : begin TrajectoryArray[6]^ := QNOZZLE;
TrajectoryArray[3]^ := QFLAME; end;
10 : begin TrajectoryArray[7]^ := QNOZZLE;
TrajectoryArray[4]^ := QFLAME; end;
11 : begin TrajectoryArray[8]^ := QNOZZLE;
TrajectoryArray[5]^ := QFLAME; end;
12 : begin TrajectoryArray[9]^ := QNOZZLE;
TrajectoryArray[6]^ := QFLAME; end;
else begin if ProgressIndex<Length(TrajectoryArray)+3
then TrajectoryArray[ProgressIndex-3]^ := QNOZZLE;
if ProgressIndex<Length(TrajectoryArray)+6
then TrajectoryArray[ProgressIndex-6]^ := QFLAME;
if ProgressIndex<Length(TrajectoryArray)+12 then begin
R := TrajectColArray[ProgressIndex-12].rgbGreen shl 2;
G := TrajectColArray[ProgressIndex-12].rgbGreen shl 2;
B := TrajectColArray[ProgressIndex-12].rgbBlue shl 2;
if R>255 then QTrail.rgbRed := 255 else QTrail.rgbRed := R;
if G>255 then QTrail.rgbGreen := 255 else QTrail.rgbGreen := G;
if B>255 then QTrail.rgbBlue := 255 else QTrail.rgbBlue := B;
QTrail.rgbReserved := 0;
TrajectoryArray[ProgressIndex-12]^ := QTrail;
end;
if ProgressIndex>=Length(TrajectoryArray) then begin
FirstPix := ProgressIndex-Length(TrajectoryArray);
TrajectoryArray[FirstPix]^ := TrajectColArray[FirstPix];
for i := FirstPix+1 to Length(TrajectoryArray)-1 do begin
R := Round(TrajectoryArray[i]^.rgbRed -(TrajectoryArray[i]^.rgbRed -TrajectColArray[i].rgbRed )*2/i);
G := Round(TrajectoryArray[i]^.rgbGreen-(TrajectoryArray[i]^.rgbGreen-TrajectColArray[i].rgbGreen)*2/i);
B := Round(TrajectoryArray[i]^.rgbBlue -(TrajectoryArray[i]^.rgbBlue -TrajectColArray[i].rgbBlue )*2/i);
if R<0 then QTrail.rgbRed := 0 else QTrail.rgbRed := R;
if G<0 then QTrail.rgbGreen := 0 else QTrail.rgbGreen := G;
if B<0 then QTrail.rgbBlue := 0 else QTrail.rgbBlue := B;
TrajectoryArray[i]^ := QTrail;
end;
end;
end;
end;
Inc(ProgressIndex);
if ProgressIndex = Length(TrajectoryArray) shl 1 then begin
if RocketIndex <> Length(gMyFleet)-1 then gMyFleet[RocketIndex] := gMyFleet[Length(gMyFleet)-1];
Dec(RocketIndex);
SetLength(gMyFleet, Length(gMyFleet)-1);
end;
Inc(RocketIndex);
end;
until RocketIndex=Length(gMyFleet);
Form1.imgScene.Refresh;
Inc(gFramesCount);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if Length(gMyFleet)<>0 then DoProgress;
Application.ProcessMessages;
Inc(gVirtualTarget.X);
if (gVirtualTarget.X>450) then gVirtualTarget.X := -100;
if gFramesCount>35 then begin
btnRockets.Caption := Format('ROCKETS LAUNCHER' + #13#10 +'( %u FPS ) ',[Round(1000/(GetTickCount-gFPStime)*gFramesCount)]);
gFramesCount := 0;
gFPStime := GetTickCount;
end;
Timer1.Enabled := Length(gMyFleet)<>0;
end;
procedure TForm1.btnRocketsClick(Sender: TObject);
var Infos : TBmpMemInfos;
RandomLine : TBmp32Line;
ColArray : TBmp32LineCol;
x1,y1,x2,y2 : Integer;
begin
if not BmpGetMemInfos(imgScene.Picture.Bitmap, Infos) then Exit;
x1 := RandomRange( 12,150);
y1 := RandomRange(150,200);
x2 := gVirtualTarget.X;
y2 := gVirtualTarget.Y;
BmpGetLine(Infos,RandomLine,x1,y1,x2,y2);
SetLength(ColArray, Length(RandomLine));
BmpGetCol(Infos, gInitialSceneInfos, RandomLine, ColArray);
SetLength(gMyFleet, Length(gMyFleet) + 1);
with gMyFleet[High(gMyFleet)] do begin
TrajectoryArray := RandomLine;
TrajectColArray := ColArray;
ProgressIndex := 0;
end;
gFramesCount := 0;
gFPStime := GetTickCount;
Timer1.Enabled := true;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
imgAPI .Picture.Bitmap.Width := imgAPI.Width;
imgAPI .Picture.Bitmap.Height := imgAPI.Height;
imgAPI .Picture.Bitmap.PixelFormat := pf32bit;
imgALGO .Picture.Bitmap.Width := imgALGO.Width;
imgALGO .Picture.Bitmap.Height := imgALGO.Height;
imgALGO .Picture.Bitmap.PixelFormat := pf32bit;
imgScene.Picture.Bitmap.PixelFormat := pf32bit;
gInitialScene := TBitmap.Create;
gInitialScene.Assign(imgScene.Picture.Bitmap);
if not BmpGetMemInfos(gInitialScene, gInitialSceneInfos) then Exit;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
gInitialScene.Free;
end;
Keine Kommentare:
Kommentar veröffentlichen