123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- unit MainUnit;
- {$include GR32.inc}
- interface
- uses
- {$IFNDEF FPC}Windows, {$ELSE} LCLIntf, LCLType, LMessages, {$ENDIF}
- Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- GR32, GR32_Image, GR32_Polygons, GR32_ColorGradients;
- type
- TFrmAntiAliasingTest = class(TForm)
- PaintBox32: TPaintBox32;
- procedure PaintBox32PaintBuffer(Sender: TObject);
- end;
- var
- FrmAntiAliasingTest: TFrmAntiAliasingTest;
- implementation
- {$R *.dfm}
- uses
- Math,
- Types,
- GR32_Math,
- GR32_Gamma,
- GR32_VectorUtils;
- procedure TFrmAntiAliasingTest.PaintBox32PaintBuffer(Sender: TObject);
- function ArrayOfFloat(Values: array of TFloat): TArrayOfFloat;
- var
- Index: Integer;
- begin
- SetLength(Result, Length(Values));
- for Index := 0 to High(Values) do
- Result[Index] := Values[Index];
- end;
- function IndexToColor32(Index: Integer): TColor32;
- begin
- Result := Color32(
- $FF * (Index mod 2), // red
- ($FF * (Index mod 3)) shr 1, // green
- ($FF * (Index mod 5)) shr 2 // blue
- );
- end;
- var
- W, H: Integer;
- Center: TFloatPoint;
- Points: TArrayOfFloatPoint;
- Outline: TArrayOfFloatPoint;
- Temp, MinCenter: TFloat;
- Index: Integer;
- LinGrad: TLinearGradientPolygonFiller;
- Renderer: TPolygonRenderer32;
- const
- CDeg2Rad = Pi / 180;
- procedure DrawCircleLine;
- var
- Index: Integer;
- Offset, Angle: TFloatPoint;
- begin
- // setup an efficient quadrature oscillator algorithm
- Angle.X := 0;
- Angle.Y := 1;
- GR32_Math.SinCos(2 * CDeg2Rad, Offset.X, Offset.Y);
- Offset.X := -Offset.X;
- // set color
- Renderer.Color := $33FFFFFF;
- // keep the same center
- Points[0] := FloatPoint(Center.X, Center.Y);
- for Index := 180 downto 1 do
- begin
- // specify line end around the circle
- Points[1] := FloatPoint(Center.X + MinCenter * Angle.X,
- Center.Y + MinCenter * Angle.Y);
- if Index < 90 then
- Renderer.PolyPolygonFS(BuildPolyPolyline(BuildDashedLine(Points,
- ArrayOfFloat([Index, Index])), False, 1))
- else
- Renderer.PolygonFS(BuildPolyline(Points, 1));
- Temp := Angle.Y * Offset.Y - Angle.X * Offset.X;
- Angle.X := Angle.X * Offset.Y + Angle.Y * Offset.X;
- Angle.Y := Temp;
- end;
- end;
- procedure DrawTriangles;
- var
- Index: Integer;
- begin
- // Triangles
- SetLength(Points, 3);
- Renderer.Filler := LinGrad;
- for Index := 1 to 13 do
- begin
- Points[0] := FloatPoint(W - 150, H - 20 - Index * (Index + 1.5));
- Points[1] := FloatPoint(W - 20, H - 20 - Index * (Index + 1));
- Points[2] := FloatPoint(W - 20, H - 20 - Index * (Index + 2));
- LinGrad.SimpleGradient(Points[0], clWhite32, Points[1], IndexToColor32(Index));
- Renderer.PolygonFS(Points);
- end;
- end;
- procedure DrawAlmostHorzVert;
- const
- LineCount = 20;
- var
- Index: Integer;
- begin
- Renderer.Color := clWhite32;
- Renderer.Filler := nil;
- for Index := 0 to LineCount do
- Renderer.PolygonFS(
- BuildPolyLine(Line(FloatPoint(20+Index*4, H-20), FloatPoint(20+Index*4 + Index/4, 200)), 0.5)
- );
- for Index := 0 to LineCount do
- Renderer.PolygonFS(
- BuildPolyLine(Line(FloatPoint(20, H-20-Index*4), FloatPoint(W div 2, H-20-Index*4 - Index/4)), 0.5)
- );
- end;
- begin
- Paintbox32.Buffer.Clear($FF000000);
- // cache width (W) and height (H) for faster access
- W := Paintbox32.Width;
- H := Paintbox32.Height;
- // calculate the center point for a faster access
- Center.X := 0.5 * W;
- Center.Y := 0.5 * H;
- // initialize some variables for a fast quadrature oscillator algorithm
- MinCenter := Min(Center.X, Center.Y);
- SetLength(Points, 2);
- Renderer := TPolygonRenderer32VPR.Create;
- Renderer.Bitmap := PaintBox32.Buffer;
- try
- DrawCircleLine;
- // Top patterns
- LinGrad := TLinearGradientPolygonFiller.Create;
- try
- LinGrad.Gradient.StartColor := clWhite32;
- for Index := 1 to 20 do
- begin
- Renderer.Color := clWhite32;
- Renderer.Filler := nil;
- // integral point sizes 1..20
- Outline := Circle(20.5 + Index * (Index + 1), 20.5, 0.5 * Index, 8 + Index);
- Renderer.PolygonFS(Outline);
- // fractional point sizes 0..2
- Outline := Circle(18.5 + 4 * Index, 33.5, 0.05 * Index, 8);
- Renderer.PolygonFS(Outline);
- // fractional point positioning
- Outline := Circle(18.4 + 4.1 * Index, 27.4 + 0.1 * Index, 0.5, 8);
- Renderer.PolygonFS(Outline);
- Renderer.Filler := LinGrad;
- Points[0] := FloatPoint(20 + Index * (Index + 1), 40.5);
- Points[1] := FloatPoint(20 + Index * (Index + 1) + (Index - 1) * 4, 100.5);
- LinGrad.SimpleGradient(Points[0], clWhite32, Points[1], IndexToColor32(Index));
- Outline := BuildPolyline(Points, Index, jsRound, esRound);
- Renderer.PolygonFS(Outline);
- // fractional line lengths H (red/blue)
- LinGrad.Gradient.StartColor := $FF0000FF;
- LinGrad.Gradient.EndColor := $FFFF0000;
- Points[0] := FloatPoint(17.5 + 4 * Index, 107);
- Points[1] := FloatPoint(17.5 + 4.15 * Index, 107);
- LinGrad.SetPoints(Points[0], Points[1]);
- Renderer.PolygonFS(BuildPolyline(Points, 1));
- // fractional line lengths V (red/blue)
- Points[0] := FloatPoint(18 + 4 * Index, 112.5);
- Points[1] := FloatPoint(18 + 4.15 * Index, 112.5 + Index * 0.15);
- LinGrad.SetPoints(Points[0], Points[1]);
- Renderer.PolygonFS(BuildPolyline(Points, 1));
- // fractional line positioning (red)
- Points[0] := FloatPoint(21.5, 120 + (Index - 1) * 3.1);
- Points[1] := FloatPoint(52.5, 120 + (Index - 1) * 3.1);
- LinGrad.SimpleGradient(Points[0], $FFFF0000, Points[1], clWhite32);
- Renderer.PolygonFS(BuildPolyline(Points, 1));
- // fractional line width 2..0 (green)
- Points[0] := FloatPoint(52.5, 118 + Index * 3);
- Points[1] := FloatPoint(83.5, 118 + Index * 3);
- LinGrad.SimpleGradient(Points[0], $FF00FF00, Points[1], clWhite32);
- Outline := BuildPolyline(Points, 2 - (Index - 1) * 0.1, jsRound, esRound);
- Renderer.PolygonFS(Outline);
- // stippled fractional width 2..0 (blue)
- Points[0] := FloatPoint(83.5, 119 + Index * 3);
- Points[1] := FloatPoint(114.5, 119 + Index * 3);
- LinGrad.SimpleGradient(Points[0], $FF0000FF, Points[1], clWhite32);
- Renderer.PolyPolygonFS(BuildPolyPolyline(BuildDashedLine(Points,
- ArrayOfFloat([3, 3])), False, 2 - (Index - 1) * 0.1));
- Renderer.Color := clWhite32;
- Renderer.Filler := nil;
- // integral line width, horz aligned (mipmap test)
- if Index < 10 then
- begin
- Points[0] := FloatPoint(125.5, 119.5 + (Index + 2) * (Index * 0.5));
- Points[1] := FloatPoint(135.5, 119.5 + (Index + 2) * (Index * 0.5));
- Outline := BuildPolyline(Points, Index, jsRound, esRound);
- Renderer.PolygonFS(Outline);
- end;
- // fractional line positioning, 1 px H
- Points[0] := FloatPoint(17.5 + 4.1 * Index - 0.1, 186);
- Points[1] := FloatPoint(18.5 + 4.1 * Index - 0.1, 186);
- Renderer.PolygonFS(BuildPolyline(Points, 1));
- // fractional line width 0..2, 1 px H
- Points[0] := FloatPoint(17.5 + 4 * Index, 192);
- Points[1] := FloatPoint(18.5 + 4 * Index, 192);
- Renderer.PolygonFS(BuildPolyline(Points, 0.1 * Index));
- end;
- DrawTriangles;
- DrawAlmostHorzVert;
-
- finally
- LinGrad.Free;
- end;
- finally
- Renderer.Free;
- end;
- end;
- end.
|