MainUnit.pas 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. unit MainUnit;
  2. {$I GR32.inc}
  3. interface
  4. uses
  5. {$IFNDEF FPC}Windows, {$ELSE} LCLIntf, LCLType, LMessages, {$ENDIF}
  6. Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  7. GR32, GR32_Image, GR32_Polygons, GR32_ColorGradients;
  8. type
  9. TFrmAntiAliasingTest = class(TForm)
  10. PaintBox32: TPaintBox32;
  11. procedure PaintBox32PaintBuffer(Sender: TObject);
  12. end;
  13. var
  14. FrmAntiAliasingTest: TFrmAntiAliasingTest;
  15. implementation
  16. {$IFDEF FPC}
  17. {$R *.lfm}
  18. {$ELSE}
  19. {$R *.dfm}
  20. {$ENDIF}
  21. uses
  22. Math, GR32_Math, GR32_Gamma, GR32_VectorUtils;
  23. procedure TFrmAntiAliasingTest.PaintBox32PaintBuffer(Sender: TObject);
  24. function ArrayOfFloat(Values: array of TFloat): TArrayOfFloat;
  25. var
  26. Index: Integer;
  27. begin
  28. SetLength(Result, Length(Values));
  29. for Index := 0 to High(Values) do
  30. Result[Index] := Values[Index];
  31. end;
  32. function IndexToColor32(Index: Integer): TColor32;
  33. begin
  34. Result := Color32(
  35. $FF * (Index mod 2), // red
  36. ($FF * (Index mod 3)) shr 1, // green
  37. ($FF * (Index mod 5)) shr 2 // blue
  38. );
  39. end;
  40. var
  41. W, H: Integer;
  42. Center: TFloatPoint;
  43. Points: TArrayOfFloatPoint;
  44. Outline: TArrayOfFloatPoint;
  45. Temp, MinCenter: TFloat;
  46. Index: Integer;
  47. LinGrad: TLinearGradientPolygonFiller;
  48. Renderer: TPolygonRenderer32;
  49. const
  50. CDeg2Rad = Pi / 180;
  51. procedure DrawCircleLine;
  52. var
  53. Index: Integer;
  54. Offset, Angle: TFloatPoint;
  55. begin
  56. // setup an efficient quadrature oscillator algorithm
  57. Angle.X := 0;
  58. Angle.Y := 1;
  59. GR32_Math.SinCos(2 * CDeg2Rad, Offset.X, Offset.Y);
  60. Offset.X := -Offset.X;
  61. // set color
  62. Renderer.Color := $33FFFFFF;
  63. // keep the same center
  64. Points[0] := FloatPoint(Center.X, Center.Y);
  65. for Index := 180 downto 1 do
  66. begin
  67. // specify line end around the circle
  68. Points[1] := FloatPoint(Center.X + MinCenter * Angle.X,
  69. Center.Y + MinCenter * Angle.Y);
  70. if Index < 90 then
  71. Renderer.PolyPolygonFS(BuildPolyPolyline(BuildDashedLine(Points,
  72. ArrayOfFloat([Index, Index])), False, 1))
  73. else
  74. Renderer.PolygonFS(BuildPolyline(Points, 1));
  75. Temp := Angle.Y * Offset.Y - Angle.X * Offset.X;
  76. Angle.X := Angle.X * Offset.Y + Angle.Y * Offset.X;
  77. Angle.Y := Temp;
  78. end;
  79. end;
  80. procedure DrawTriangles;
  81. var
  82. Index: Integer;
  83. begin
  84. // Triangles
  85. SetLength(Points, 3);
  86. Renderer.Filler := LinGrad;
  87. for Index := 1 to 13 do
  88. begin
  89. Points[0] := FloatPoint(W - 150, H - 20 - Index * (Index + 1.5));
  90. Points[1] := FloatPoint(W - 20, H - 20 - Index * (Index + 1));
  91. Points[2] := FloatPoint(W - 20, H - 20 - Index * (Index + 2));
  92. LinGrad.SimpleGradient(Points[0], clWhite32, Points[1], IndexToColor32(Index));
  93. Renderer.PolygonFS(Points);
  94. end;
  95. end;
  96. begin
  97. Paintbox32.Buffer.Clear($FF000000);
  98. // cache width (W) and height (H) for faster access
  99. W := Paintbox32.Width;
  100. H := Paintbox32.Height;
  101. // calculate the center point for a faster access
  102. Center.X := 0.5 * W;
  103. Center.Y := 0.5 * H;
  104. // initialize some variables for a fast quadrature oscillator algorithm
  105. MinCenter := Min(Center.X, Center.Y);
  106. SetLength(Points, 2);
  107. Renderer := TPolygonRenderer32VPR.Create;
  108. Renderer.Bitmap := PaintBox32.Buffer;
  109. try
  110. DrawCircleLine;
  111. // Top patterns
  112. LinGrad := TLinearGradientPolygonFiller.Create;
  113. LinGrad.Gradient.StartColor := clWhite32;
  114. for Index := 1 to 20 do
  115. begin
  116. Renderer.Color := clWhite32;
  117. Renderer.Filler := nil;
  118. // integral point sizes 1..20
  119. Outline := Circle(20.5 + Index * (Index + 1), 20.5, 0.5 * Index, 8 + Index);
  120. Renderer.PolygonFS(Outline);
  121. // fractional point sizes 0..2
  122. Outline := Circle(18.5 + 4 * Index, 33.5, 0.05 * Index, 8);
  123. Renderer.PolygonFS(Outline);
  124. // fractional point positioning
  125. Outline := Circle(18.4 + 4.1 * Index, 27.4 + 0.1 * Index, 0.5, 8);
  126. Renderer.PolygonFS(Outline);
  127. Renderer.Filler := LinGrad;
  128. Points[0] := FloatPoint(20 + Index * (Index + 1), 40.5);
  129. Points[1] := FloatPoint(20 + Index * (Index + 1) + (Index - 1) * 4, 100.5);
  130. LinGrad.SimpleGradient(Points[0], clWhite32, Points[1], IndexToColor32(Index));
  131. Outline := BuildPolyline(Points, Index, jsRound, esRound);
  132. Renderer.PolygonFS(Outline);
  133. // fractional line lengths H (red/blue)
  134. LinGrad.Gradient.StartColor := $FF0000FF;
  135. LinGrad.Gradient.EndColor := $FFFF0000;
  136. Points[0] := FloatPoint(17.5 + 4 * Index, 107);
  137. Points[1] := FloatPoint(17.5 + 4.15 * Index, 107);
  138. LinGrad.SetPoints(Points[0], Points[1]);
  139. Renderer.PolygonFS(BuildPolyline(Points, 1));
  140. // fractional line lengths V (red/blue)
  141. Points[0] := FloatPoint(18 + 4 * Index, 112.5);
  142. Points[1] := FloatPoint(18 + 4.15 * Index, 112.5 + Index * 0.15);
  143. LinGrad.SetPoints(Points[0], Points[1]);
  144. Renderer.PolygonFS(BuildPolyline(Points, 1));
  145. // fractional line positioning (red)
  146. Points[0] := FloatPoint(21.5, 120 + (Index - 1) * 3.1);
  147. Points[1] := FloatPoint(52.5, 120 + (Index - 1) * 3.1);
  148. LinGrad.SimpleGradient(Points[0], $FFFF0000, Points[1], clWhite32);
  149. Renderer.PolygonFS(BuildPolyline(Points, 1));
  150. // fractional line width 2..0 (green)
  151. Points[0] := FloatPoint(52.5, 118 + Index * 3);
  152. Points[1] := FloatPoint(83.5, 118 + Index * 3);
  153. LinGrad.SimpleGradient(Points[0], $FF00FF00, Points[1], clWhite32);
  154. Outline := BuildPolyline(Points, 2 - (Index - 1) * 0.1, jsRound, esRound);
  155. Renderer.PolygonFS(Outline);
  156. // stippled fractional width 2..0 (blue)
  157. Points[0] := FloatPoint(83.5, 119 + Index * 3);
  158. Points[1] := FloatPoint(114.5, 119 + Index * 3);
  159. LinGrad.SimpleGradient(Points[0], $FF0000FF, Points[1], clWhite32);
  160. Renderer.PolyPolygonFS(BuildPolyPolyline(BuildDashedLine(Points,
  161. ArrayOfFloat([3, 3])), False, 2 - (Index - 1) * 0.1));
  162. Renderer.Color := clWhite32;
  163. Renderer.Filler := nil;
  164. // integral line width, horz aligned (mipmap test)
  165. if Index < 10 then
  166. begin
  167. Points[0] := FloatPoint(125.5, 119.5 + (Index + 2) * (Index * 0.5));
  168. Points[1] := FloatPoint(135.5, 119.5 + (Index + 2) * (Index * 0.5));
  169. Outline := BuildPolyline(Points, Index, jsRound, esRound);
  170. Renderer.PolygonFS(Outline);
  171. end;
  172. // fractional line positioning, 1 px H
  173. Points[0] := FloatPoint(17.5 + 4.1 * Index - 0.1, 186);
  174. Points[1] := FloatPoint(18.5 + 4.1 * Index - 0.1, 186);
  175. Renderer.PolygonFS(BuildPolyline(Points, 1));
  176. // fractional line width 0..2, 1 px H
  177. Points[0] := FloatPoint(17.5 + 4 * Index, 192);
  178. Points[1] := FloatPoint(18.5 + 4 * Index, 192);
  179. Renderer.PolygonFS(BuildPolyline(Points, 0.1 * Index));
  180. end;
  181. DrawTriangles;
  182. finally
  183. Renderer.Free;
  184. end;
  185. end;
  186. end.