MainUnit.pas 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. unit MainUnit;
  2. {$include 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. {$R *.dfm}
  17. uses
  18. Math,
  19. Types,
  20. GR32_Math,
  21. GR32_Gamma,
  22. 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. procedure DrawAlmostHorzVert;
  97. const
  98. LineCount = 20;
  99. var
  100. Index: Integer;
  101. begin
  102. Renderer.Color := clWhite32;
  103. Renderer.Filler := nil;
  104. for Index := 0 to LineCount do
  105. Renderer.PolygonFS(
  106. BuildPolyLine(Line(FloatPoint(20+Index*4, H-20), FloatPoint(20+Index*4 + Index/4, 200)), 0.5)
  107. );
  108. for Index := 0 to LineCount do
  109. Renderer.PolygonFS(
  110. BuildPolyLine(Line(FloatPoint(20, H-20-Index*4), FloatPoint(W div 2, H-20-Index*4 - Index/4)), 0.5)
  111. );
  112. end;
  113. begin
  114. Paintbox32.Buffer.Clear($FF000000);
  115. // cache width (W) and height (H) for faster access
  116. W := Paintbox32.Width;
  117. H := Paintbox32.Height;
  118. // calculate the center point for a faster access
  119. Center.X := 0.5 * W;
  120. Center.Y := 0.5 * H;
  121. // initialize some variables for a fast quadrature oscillator algorithm
  122. MinCenter := Min(Center.X, Center.Y);
  123. SetLength(Points, 2);
  124. Renderer := TPolygonRenderer32VPR.Create;
  125. Renderer.Bitmap := PaintBox32.Buffer;
  126. try
  127. DrawCircleLine;
  128. // Top patterns
  129. LinGrad := TLinearGradientPolygonFiller.Create;
  130. try
  131. LinGrad.Gradient.StartColor := clWhite32;
  132. for Index := 1 to 20 do
  133. begin
  134. Renderer.Color := clWhite32;
  135. Renderer.Filler := nil;
  136. // integral point sizes 1..20
  137. Outline := Circle(20.5 + Index * (Index + 1), 20.5, 0.5 * Index, 8 + Index);
  138. Renderer.PolygonFS(Outline);
  139. // fractional point sizes 0..2
  140. Outline := Circle(18.5 + 4 * Index, 33.5, 0.05 * Index, 8);
  141. Renderer.PolygonFS(Outline);
  142. // fractional point positioning
  143. Outline := Circle(18.4 + 4.1 * Index, 27.4 + 0.1 * Index, 0.5, 8);
  144. Renderer.PolygonFS(Outline);
  145. Renderer.Filler := LinGrad;
  146. Points[0] := FloatPoint(20 + Index * (Index + 1), 40.5);
  147. Points[1] := FloatPoint(20 + Index * (Index + 1) + (Index - 1) * 4, 100.5);
  148. LinGrad.SimpleGradient(Points[0], clWhite32, Points[1], IndexToColor32(Index));
  149. Outline := BuildPolyline(Points, Index, jsRound, esRound);
  150. Renderer.PolygonFS(Outline);
  151. // fractional line lengths H (red/blue)
  152. LinGrad.Gradient.StartColor := $FF0000FF;
  153. LinGrad.Gradient.EndColor := $FFFF0000;
  154. Points[0] := FloatPoint(17.5 + 4 * Index, 107);
  155. Points[1] := FloatPoint(17.5 + 4.15 * Index, 107);
  156. LinGrad.SetPoints(Points[0], Points[1]);
  157. Renderer.PolygonFS(BuildPolyline(Points, 1));
  158. // fractional line lengths V (red/blue)
  159. Points[0] := FloatPoint(18 + 4 * Index, 112.5);
  160. Points[1] := FloatPoint(18 + 4.15 * Index, 112.5 + Index * 0.15);
  161. LinGrad.SetPoints(Points[0], Points[1]);
  162. Renderer.PolygonFS(BuildPolyline(Points, 1));
  163. // fractional line positioning (red)
  164. Points[0] := FloatPoint(21.5, 120 + (Index - 1) * 3.1);
  165. Points[1] := FloatPoint(52.5, 120 + (Index - 1) * 3.1);
  166. LinGrad.SimpleGradient(Points[0], $FFFF0000, Points[1], clWhite32);
  167. Renderer.PolygonFS(BuildPolyline(Points, 1));
  168. // fractional line width 2..0 (green)
  169. Points[0] := FloatPoint(52.5, 118 + Index * 3);
  170. Points[1] := FloatPoint(83.5, 118 + Index * 3);
  171. LinGrad.SimpleGradient(Points[0], $FF00FF00, Points[1], clWhite32);
  172. Outline := BuildPolyline(Points, 2 - (Index - 1) * 0.1, jsRound, esRound);
  173. Renderer.PolygonFS(Outline);
  174. // stippled fractional width 2..0 (blue)
  175. Points[0] := FloatPoint(83.5, 119 + Index * 3);
  176. Points[1] := FloatPoint(114.5, 119 + Index * 3);
  177. LinGrad.SimpleGradient(Points[0], $FF0000FF, Points[1], clWhite32);
  178. Renderer.PolyPolygonFS(BuildPolyPolyline(BuildDashedLine(Points,
  179. ArrayOfFloat([3, 3])), False, 2 - (Index - 1) * 0.1));
  180. Renderer.Color := clWhite32;
  181. Renderer.Filler := nil;
  182. // integral line width, horz aligned (mipmap test)
  183. if Index < 10 then
  184. begin
  185. Points[0] := FloatPoint(125.5, 119.5 + (Index + 2) * (Index * 0.5));
  186. Points[1] := FloatPoint(135.5, 119.5 + (Index + 2) * (Index * 0.5));
  187. Outline := BuildPolyline(Points, Index, jsRound, esRound);
  188. Renderer.PolygonFS(Outline);
  189. end;
  190. // fractional line positioning, 1 px H
  191. Points[0] := FloatPoint(17.5 + 4.1 * Index - 0.1, 186);
  192. Points[1] := FloatPoint(18.5 + 4.1 * Index - 0.1, 186);
  193. Renderer.PolygonFS(BuildPolyline(Points, 1));
  194. // fractional line width 0..2, 1 px H
  195. Points[0] := FloatPoint(17.5 + 4 * Index, 192);
  196. Points[1] := FloatPoint(18.5 + 4 * Index, 192);
  197. Renderer.PolygonFS(BuildPolyline(Points, 0.1 * Index));
  198. end;
  199. DrawTriangles;
  200. DrawAlmostHorzVert;
  201. finally
  202. LinGrad.Free;
  203. end;
  204. finally
  205. Renderer.Free;
  206. end;
  207. end;
  208. end.