CnGLCanvasDemo.pas
上传用户:zkjn0718
上传日期:2021-01-01
资源大小:776k
文件大小:15k
源码类别:

Delphi/CppBuilder

开发平台:

Delphi

  1. unit CnGLCanvasDemo;
  2. interface
  3. uses
  4.    Windows,
  5.    Messages,
  6.    SysUtils,
  7.    Variants,
  8.    Classes,
  9.    Graphics,
  10.    Controls,
  11.    Forms,
  12.    CnOpenGLCanvas,
  13.    StdCtrls,
  14.    ExtCtrls,
  15.    OpenGL,
  16.    ComCtrls,
  17.    Math;
  18. type
  19.    TMainTests = (mtDot, mtLine, mtPolyline, mtCurve, mtRectEllipse, mtArc, mtText, mtImage);
  20.    TBenchTests = (btLines, btRectangles, btEllipses, btPoints, btTexts);
  21.    TfrmMain = class(TForm)
  22.       PageControl1: TPageControl;
  23.       TabSheet1: TTabSheet;
  24.       glcMain: TCnGLCanvas;
  25.       Panel1: TPanel;
  26.       chkAntialiasing: TCheckBox;
  27.       btnDot: TButton;
  28.       cboLineStipple: TComboBox;
  29.       TabSheet2: TTabSheet;
  30.       btnLine: TButton;
  31.       btnPolyline: TButton;
  32.       clrPen: TColorBox;
  33.       btnCurve: TButton;
  34.       btnRectEllipse: TButton;
  35.       btnArc: TButton;
  36.       btnText: TButton;
  37.       btnImage: TButton;
  38.       Label1: TLabel;
  39.       clrBrush: TColorBox;
  40.       Label2: TLabel;
  41.       Label3: TLabel;
  42.       chkTranslate: TCheckBox;
  43.       chkRotate: TCheckBox;
  44.       chkScale: TCheckBox;
  45.       Label4: TLabel;
  46.       trackPenWidth: TTrackBar;
  47.       Label5: TLabel;
  48.       trackFillAlpha: TTrackBar;
  49.       glcBench: TCnGLCanvas;
  50.       imgBench: TImage;
  51.       lblGLCanvasBench: TLabel;
  52.       lblGDIBench: TLabel;
  53.     GroupBox1: TGroupBox;
  54.     Label6: TLabel;
  55.     btnBenchLines: TButton;
  56.     btnBenchRects: TButton;
  57.     btnBenchEllipses: TButton;
  58.     btnBenchPoints: TButton;
  59.     btnBenchTexts: TButton;
  60.     GroupBox2: TGroupBox;
  61.     btnBuildList: TButton;
  62.     btnExecuteList: TButton;
  63.     clrPenColor2: TColorBox;
  64.     Label7: TLabel;
  65.     trackPenWidth2: TTrackBar;
  66.     rdoPenWidth1: TRadioButton;
  67.     rdoPenWidth2: TRadioButton;
  68.     Label8: TLabel;
  69.       procedure FormCreate(Sender: TObject);
  70.       procedure MainTestClick(Sender: TObject);
  71.       procedure BenchTestClick(Sender: TObject);
  72.       procedure FormDestroy(Sender: TObject);
  73.       procedure PageControl1Change(Sender: TObject);
  74.     procedure glcMainResize(Sender: TObject);
  75.     procedure btnBuildListClick(Sender: TObject);
  76.     procedure btnExecuteListClick(Sender: TObject);
  77.    private
  78.     { Private declarations }
  79.       ImageTex: TBitmap;
  80.       OldMainTest: TMainTests;
  81.       BenchTest: TBenchTests;
  82.       BenchList: GLuint;
  83.       procedure GLCanvasBench;
  84.       procedure GDIBench;
  85.    public
  86.     { Public declarations }
  87.    end;
  88. var
  89.    frmMain: TfrmMain;
  90. implementation
  91. const
  92.    cBenchLines = 20000;
  93.    cBenchRects = 20000;
  94.    cBenchEllipses = 20000;
  95.    cBenchPoints = 200000;
  96.    cBenchTexts = 10000;
  97. {$R *.dfm}
  98. function StartPrecisionTimer: Int64;
  99. begin
  100.    QueryPerformanceCounter(Result);
  101. end;
  102. function StopPrecisionTimer(const precisionTimer: Int64): Double;
  103. var
  104.    cur, freq: Int64;
  105. begin
  106.    QueryPerformanceCounter(cur);
  107.    QueryPerformanceFrequency(freq);
  108.    Result := (cur - precisionTimer) / freq;
  109. end;
  110. procedure TfrmMain.BenchTestClick(Sender: TObject);
  111. var
  112.    t: Int64;
  113. begin
  114.    BenchTest := TBenchTests(TComponent(Sender).Tag);
  115.    if rdoPenWidth1.Checked then
  116.    begin
  117.       glcBench.PenWidth := 1;
  118.       imgBench.Canvas.Pen.Width := 1;
  119.    end
  120.    else
  121.    begin
  122.       glcBench.PenWidth := 2;
  123.       imgBench.Canvas.Pen.Width := 2;
  124.    end;
  125.    Application.ProcessMessages;
  126.    Randomize;
  127.    t := StartPrecisionTimer;
  128.    GLCanvasBench;
  129.    lblGLCanvasBench.Caption := Format('GLCanvas: %.3f msec', [StopPrecisionTimer(t) * 1000]);
  130.    Application.ProcessMessages;
  131.    Randomize;
  132.    t := StartPrecisionTimer;
  133.    GDIBench;
  134.    lblGDIBench.Caption := Format('GDI: %.3f msec', [StopPrecisionTimer(t) * 1000]);
  135. end;
  136. procedure TfrmMain.btnBuildListClick(Sender: TObject);
  137. begin
  138.    glcBench.CreateList(BenchList).ListBegin(BenchList).Line(0, 0, 50, 50).
  139.       FrameRect(30, 20, 100, 150).Ellipse(100, 35, 33, 100).Arc(250, 250, 100, 50, 90, 180).ListEnd;
  140.    btnExecuteList.Enabled := True;
  141.    btnBuildList.Enabled := False;
  142. end;
  143. procedure TfrmMain.btnExecuteListClick(Sender: TObject);
  144. var
  145.    penColor: ARGB;
  146. begin
  147.    penColor := TColorToARGB(clrPenColor2.Selected);
  148.    glcBench.RenderingBegin.ListExecute(BenchList, 0, penColor, trackPenWidth2.Position).RenderingEnd;
  149. end;
  150. procedure TfrmMain.FormCreate(Sender: TObject);
  151. begin
  152.    glcBench.Initialize(False);
  153.    glcMain.Initialize(True);
  154.    // 读取例子图片,采用预先构建纹理的方式,速度更快
  155.    ImageTex := TBitmap.Create;
  156.    ImageTex.LoadFromFile('test.bmp');
  157.    OldMainTest := mtLine;
  158. end;
  159. procedure TfrmMain.FormDestroy(Sender: TObject);
  160. begin
  161.    ImageTex.Free;
  162. end;
  163. procedure TfrmMain.GDIBench;
  164. var
  165.    i: Integer;
  166.    r: TRect;
  167. begin
  168.    with imgBench.Canvas do
  169.    begin
  170.       Brush.Style := bsSolid;
  171.       Brush.Color := clWhite;
  172.       Rectangle(0, 0, 380, 380);
  173.       Brush.Style := bsClear;
  174.       case BenchTest of
  175.          btLines:
  176.             for i := 1 to cBenchLines do
  177.             begin
  178.                Pen.Color := Random(256 * 256 * 256);
  179.                MoveTo(Random(380), Random(380));
  180.                LineTo(Random(380), Random(380));
  181.             end;
  182.          btEllipses:
  183.             for i := 1 to cBenchEllipses do
  184.             begin
  185.                Pen.Color := Random(256 * 256 * 256);
  186.                Ellipse(Random(380), Random(380), Random(380), Random(380));
  187.             end;
  188.          btRectangles:
  189.             for i := 1 to cBenchRects do
  190.             begin
  191.                Brush.Color := Random(256 * 256 * 256);
  192.                r := Rect(Random(380), Random(380), Random(380), Random(380));
  193.                FillRect(r);
  194.             end;
  195.          btPoints:
  196.             for i := 1 to cBenchPoints do
  197.                Pixels[Random(380), Random(380)] := Random(256 * 256 * 256);
  198.          btTexts:
  199.             for i := 1 to cBenchTexts do
  200.             begin
  201.                Font.Color := Random(256 * 256 * 256);
  202.                TextOut(Random(380), Random(380), 'Hello');
  203.             end;
  204.       end;
  205.    end;
  206. end;
  207. procedure TfrmMain.GLCanvasBench;
  208. var
  209.    i: Integer;
  210. begin
  211.    glcBench.RenderingBegin;
  212.    case BenchTest of
  213.       btLines:
  214.          begin
  215.             glcBench.BeginLines;
  216.             for i := 1 to cBenchLines do
  217.                glcBench.SetPenColorWin(Random(256 * 256 * 256), 255, False).
  218.                   Lines(Random(380), Random(380), Random(380), Random(380));
  219.             glcBench.EndLines;
  220.          end;
  221.       btEllipses:
  222.          for i := 1 to cBenchEllipses do
  223.             glcBench.SetPenColorWin(Random(256 * 256 * 256), 255, False).
  224.                EllipseRect(Random(380), Random(380), Random(380), Random(380));
  225.       btRectangles:
  226.          for i := 1 to cBenchRects do
  227.             glcBench.SetBrushColorWin(Random(256 * 256 * 256), 255, False).
  228.                FillRect(Random(380), Random(380), Random(380), Random(380));
  229.       btPoints:
  230.          begin
  231.             glcBench.BeginPixels;
  232.             for i := 1 to cBenchPoints do
  233.                glcBench.SetPenColorWin(Random(256 * 256 * 256), 255, False).Pixels(Random(380), Random(380));
  234.             glcBench.EndPixels;
  235.          end;
  236.       btTexts:
  237.          for i := 1 to cBenchTexts do
  238.          begin
  239.             glcBench.DefaultFont.WinColor := Random(256 * 256 * 256);
  240.             glcBench.TextOutASCII('Hello', Random(380), Random(380));
  241.          end;
  242.    end;
  243.    glcBench.RenderingEnd;
  244. end;
  245. procedure TfrmMain.glcMainResize(Sender: TObject);
  246. begin
  247.    if PageControl1.ActivePageIndex = 1 then
  248.       MainTestClick(nil);
  249. end;
  250. procedure TfrmMain.MainTestClick(Sender: TObject);
  251. const
  252.    ColorArray: array[0..3] of TColor = (clRed, clBlue, clTeal, clAqua);
  253.    ImageZoom: array[0..9] of Single = (0.1, 0.3, 0.5, 0.75, 0.8, 1, 1.5, 2, 3, 4);
  254. var
  255.    i: Integer;
  256.    fillColor: ARGB;
  257.    vertices: array[0..9] of TGLPointF;
  258.    procedure GenRandomVertices;
  259.    var
  260.       i: Integer;
  261.    begin
  262.       Randomize;
  263.       for i := 0 to 9 do
  264.       begin
  265.          vertices[i].x := RandomRange(-20, glcMain.Width - 20);
  266.          vertices[i].y := RandomRange(-10, glcMain.Height - 10);
  267.       end;
  268.    end;
  269. begin
  270.    if Sender is TButton then
  271.       OldMainTest := TMainTests(TComponent(Sender).Tag);
  272.    glcMain.Antialiasing := chkAntialiasing.Checked;
  273.    fillColor := TColorToARGB(clrBrush.Selected, trackFillAlpha.Position);
  274.    glcMain.RenderingBegin. // 开始绘制
  275.       SetBrushColor(fillColor).SetPenWidth(trackPenWidth.Position).
  276.       SetPenColorWin(clrPen.Selected).LineStipple(TLineStippleStyle(cboLineStipple.ItemIndex));
  277.    // 当有大量连续坐标变换操作时,先BeginUpdateTransformation,可以最后一次更新,提高速度
  278.    glcMain.BeginUpdateTransformation.ResetTransformation; // 开始更新坐标变换,并重置
  279.    if chkTranslate.Checked then
  280.       glcMain.SetTranslateX(50).SetTranslateY(50); // 各移动50像素
  281.    if chkScale.Checked then
  282.       glcMain.SetEqualScale(2.0); // x与y轴都放大两倍
  283.    if chkRotate.Checked then
  284.       glcMain.SetRotation(20); // 度, degree
  285.    glcMain.EndUpdateTransformation;
  286.    case OldMainTest of
  287.       mtDot:
  288.          begin
  289.             Randomize;
  290.             // 绘制比别的点大一点的原点
  291.             glcMain.SetPenWidth(trackPenWidth.Position + 2).PlotPixel(0, 0).SetPenWidth(trackPenWidth.Position);
  292.             glcMain.BeginPixels; //开始绘制点,当连续绘制大量点时,使用BeginPixels和EndPixels速度更快
  293.             for i := 0 to 100 do
  294.                glcMain.Pixels(RandomRange(-20, glcMain.Width - 20), RandomRange(-10, glcMain.Height - 10));
  295.             glcMain.EndPixels;
  296.          end;
  297.       mtLine:
  298.          begin
  299.             Randomize;
  300.             glcMain.SetPenWidth(trackPenWidth.Position + 2).Line(0, 0, 100, 0).
  301.                Line(0, 0, 0, 100).SetPenWidth(trackPenWidth.Position); // 绘制坐标轴,比其它直线粗一点
  302.             glcMain.BeginLines; //用途同BeginPixels
  303.             for i := 0 to 30 do
  304.                glcMain.Lines(RandomRange(-20, glcMain.Width - 20), RandomRange(-10, glcMain.Height - 10),
  305.                   RandomRange(-20, glcMain.Width - 20), RandomRange(-10, glcMain.Height - 10));
  306.             glcMain.EndLines;
  307.          end;
  308.       mtPolyline:
  309.          begin
  310.             Randomize;
  311.             glcMain.SetPenWidth(trackPenWidth.Position + 2).Line(0, 0, 100, 0).
  312.                Line(0, 0, 0, 100).SetPenWidth(trackPenWidth.Position); // 绘制坐标轴,比其它直线粗一点
  313.             GenRandomVertices; // 生成随机点
  314.             glcMain.
  315.                Polyline(TGLPointsF(@vertices[0]), 5). // 折线
  316.                Polygon(TGLPointsF(@vertices[5]), 5); // 多边形
  317.             vertices[0].X := RandomRange(-20, glcMain.Width div 2 - 20);
  318.             vertices[0].Y := RandomRange(-20, glcMain.Height div 2 - 20);
  319.             vertices[1].X := RandomRange(-20, glcMain.Width div 2 - 20);
  320.             vertices[1].Y := RandomRange(glcMain.Height div 2 - 10, glcMain.Height - 10);
  321.             vertices[2].X := RandomRange(glcMain.Width div 2 - 10, glcMain.Width - 20);
  322.             vertices[2].Y := RandomRange(glcMain.Height div 2 - 10, glcMain.Height - 10);
  323.             vertices[3].X := RandomRange(glcMain.Width div 2 - 10, glcMain.Width - 20);
  324.             vertices[3].Y := RandomRange(-20, glcMain.Height div 2 - 20);
  325.             glcMain.FillPolygon(TGLPointsF(@vertices[0]), 4, True {显示边框}); // 填充多边形
  326.          end;
  327.       mtCurve:
  328.          begin
  329.             Randomize;
  330.             glcMain.SetPenWidth(trackPenWidth.Position + 2).Line(0, 0, 100, 0).
  331.                Line(0, 0, 0, 100).SetPenWidth(trackPenWidth.Position); // 绘制坐标轴,比其它直线粗一点
  332.             GenRandomVertices; // 生成随机点
  333.             glcMain.
  334.                Curve(TGLPointsF(@vertices[0]), 5).
  335.                FillClosedCurve(TGLPointsF(@vertices[5]), 5, True {显示边框});
  336.          end;
  337.       mtRectEllipse:
  338.          begin
  339.             Randomize;
  340.             glcMain.SetPenWidth(trackPenWidth.Position + 2).Line(0, 0, 100, 0).
  341.                Line(0, 0, 0, 100).SetPenWidth(trackPenWidth.Position); // 绘制坐标轴,比其它直线粗一点
  342.             for i := 0 to 3 do
  343.             begin
  344.                glcMain.FrameRect(RandomRange(-20, glcMain.Width - 20), RandomRange(-10, glcMain.Height - 10),
  345.                   RandomRange(-20, glcMain.Width - 20), RandomRange(-10, glcMain.Height - 10));
  346.                glcMain.FillRect(RandomRange(-20, glcMain.Width - 20), RandomRange(-10, glcMain.Height - 10),
  347.                   RandomRange(-20, glcMain.Width - 20), RandomRange(-10, glcMain.Height - 10), True {显示边框});
  348.                glcMain.EllipseRect(RandomRange(-20, glcMain.Width - 20), RandomRange(-10, glcMain.Height - 10),
  349.                   RandomRange(-20, glcMain.Width - 20), RandomRange(-10, glcMain.Height - 10));
  350.                glcMain.FillEllipseRect(RandomRange(-20, glcMain.Width - 20), RandomRange(-10, glcMain.Height - 10),
  351.                   RandomRange(-20, glcMain.Width - 20), RandomRange(-10, glcMain.Height - 10), True {显示边框});
  352.             end;
  353.          end;
  354.       mtArc:
  355.          begin
  356.             Randomize;
  357.             glcMain.SetPenWidth(trackPenWidth.Position + 2).Line(0, 0, 100, 0).
  358.                Line(0, 0, 0, 100).SetPenWidth(trackPenWidth.Position); // 绘制坐标轴,比其它直线粗一点
  359.             for i := 0 to 7 do
  360.             begin
  361.                glcMain.Arc(i * 150 + 80, 200, (i + 3) * 10, (i * 2 + 2) * 5, RandomRange(0, 180), RandomRange(50, 180));
  362.                glcMain.FillPie(i * 150 + 80, 500, (i + 3) * 10, (i * 2 + 2) * 5, RandomRange(0, 180), RandomRange(50, 180), True);
  363.             end;
  364.          end;
  365.       mtText:
  366.          begin
  367.             Randomize;
  368.             glcMain.SetPenWidth(trackPenWidth.Position + 2).Line(0, 0, 100, 0).
  369.                Line(0, 0, 0, 100).SetPenWidth(trackPenWidth.Position); // 绘制坐标轴,比其它直线粗一点
  370.             glcMain.RecreateDefaultFont;
  371.             for i := 0 to 3 do
  372.             begin
  373.                glcMain.TextOut('这是可以利用OpenGL硬件加速的画布控件。',
  374.                   RandomRange(-20, glcMain.Width - 100), RandomRange(-10, glcMain.Height - 10));
  375.                glcMain.TextOutASCII('abcdefghijklmnopqrstuvwxyz 0123456789 !@#$%^&*()_+', // 只输出ASCII字符使用这个方法更快
  376.                   RandomRange(-20, glcMain.Width - 100), RandomRange(-10, glcMain.Height - 10));
  377.                glcMain.DefaultFont.Size := RandomRange(6, 20);
  378.                if i <= 3 then
  379.                begin
  380.                   glcMain.DefaultFont.Styles := glcMain.DefaultFont.Styles + [TFontStyle(i)];
  381.                   glcMain.DefaultFont.Color := TColorToARGB(ColorArray[i]);
  382.                end;
  383.                glcMain.DefaultFont.Update; // 更改字体后必须使用Update更新
  384.             end;
  385.          end;
  386.       mtImage:
  387.          begin
  388.             Randomize;
  389.             glcMain.SetPenWidth(trackPenWidth.Position + 2).Line(0, 0, 100, 0).
  390.                Line(0, 0, 0, 100).SetPenWidth(trackPenWidth.Position); // 绘制坐标轴,比其它直线粗一点
  391.             for i := 0 to 9 do
  392.                glcMain.DrawBitmap(ImageTex, i * 70 + 40, i * 30 + 100,
  393.                   ImageZoom[i], ImageZoom[i]);
  394.          end;
  395.    end;
  396.    glcMain.RenderingEnd; // 结束绘制
  397. end;
  398. procedure TfrmMain.PageControl1Change(Sender: TObject);
  399. begin
  400.    if PageControl1.ActivePageIndex = 1 then
  401.       MainTestClick(nil);
  402. end;
  403. end.