unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
Spin, BGRAVirtualScreen, BGRABitmap, BGRABitmapTypes;
type
{ TForm1 }
TForm1 = class(TForm)
BGRAVirtualScreen1: TBGRAVirtualScreen;
Button1: TButton;
FloatSpinEdit1: TFloatSpinEdit;
FloatSpinEdit2: TFloatSpinEdit;
Panel1: TPanel;
SpinEdit1: TSpinEdit;
Timer1: TTimer;
procedure BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
ZoomFactor, MaxZoom, MinZoom, Angle, RotSpeed, Tmr, ZoomCenter, ZoomAmp: Single;
CellSize: Integer;
public
end;
var
Form1: TForm1;
tex : TBGRABitmap;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
// texture
tex := TBGRABitmap.Create('bird.jpg');
MaxZoom := 4.0;
MinZoom := 1.5;
CellSize := 12;
Angle := 0;
RotSpeed := 0.6;
Tmr := 0;
ZoomCenter := (MaxZoom + MinZoom) / 2;
ZoomAmp := (MaxZoom - MinZoom) / 2;
ZoomFactor := ZoomCenter / 8;
end;
procedure TForm1.BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
var
x, y: Integer;
bx, by: Integer;
dx, dy: Single;
sx, sy: Integer;
centerX, centerY: Single;
zoom: Single;
col: TBGRAPixel;
angleRad: Single;
sinVal, cosVal: Single;
rotX, rotY: Single;
begin
centerX := tex.Width / 2;
centerY := tex.Height / 2;
zoom := 1 / ZoomFactor;
angleRad := Angle * Pi / 180;
sinVal := Sin(angleRad);
cosVal := Cos(angleRad);
Bitmap.Fill(BGRABlack);
// pixel fx ok with pascal
for y := 0 to (BGRAVirtualScreen1.Height - 1) div CellSize do
begin
for x := 0 to (BGRAVirtualScreen1.Width - 1) div CellSize do
begin
dx := (x * CellSize - BGRAVirtualScreen1.Width/2) * zoom;
dy := (y * CellSize - BGRAVirtualScreen1.Height/2) * zoom;
rotX := dx * cosVal - dy * sinVal;
rotY := dx * sinVal + dy * cosVal;
sx := Round(centerX + rotX);
sy := Round(centerY + rotY);
// Replace pixel on each cells inside limits adapted from js;
if (sx >= 0) and (sx < tex.Width) and (sy >= 0) and (sy < tex.Height) then
begin
// get pixel source
col := tex.GetPixel(sx, sy);
// fill cells block
for by := 0 to CellSize - 1 do
begin
for bx := 0 to CellSize - 1 do
begin
if (x * CellSize + bx < BGRAVirtualScreen1.Width) and
(y * CellSize + by < BGRAVirtualScreen1.Height) then
begin
Bitmap.SetPixel(x * CellSize + bx, y * CellSize + by, col);
end;
end;
end;
end;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
FloatSpinEdit1.Value := -FloatSpinEdit1.Value;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Tmr := Tmr + 0.01; // counter timer
ZoomFactor := ZoomCenter + (ZoomAmp * Sin(Tmr * 0.5));
Angle := Angle + RotSpeed;
CellSize := SpinEdit1.Value;
RotSpeed := FloatSpinEdit1.Value;
ZoomFactor := FloatSpinEdit2.Value; // never negative ! div / 0
BGRAVirtualScreen1.RedrawBitmap;
end;
end.