随笔 - 2146  文章 - 19 评论 - 11846 阅读 - 1267万


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormPaint(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses Direct2D, D2D1;

{左边小山的路径}
function GetLeftMountainGeometry: ID2D1PathGeometry;
const
  pts: array[0..5] of TD2DPoint2f = (
    (x:346; y:255),
    (x:267; y:177),
    (x:236; y:192),
    (x:212; y:160),
    (x:156; y:255),
    (x:346; y:255)
  );
var
  iGeometrySink: ID2D1GeometrySink;
begin
  D2DFactory.CreatePathGeometry(Result);
  Result.Open(iGeometrySink);
  with iGeometrySink do begin
    SetFillMode(D2D1_FILL_MODE_WINDING);
    BeginFigure(pts[0], D2D1_FIGURE_BEGIN_FILLED);
    AddLines(@pts[1], Length(pts)-1);
    EndFigure(D2D1_FIGURE_END_CLOSED);
    Close;
  end;
end;

{右边小山的路径}
function GetRightMountainGeometry: ID2D1PathGeometry;
const
  pts: array[0..7] of TD2DPoint2f = (
    (x:575; y:263),
    (x:481; y:146),
    (x:449; y:181),
    (x:433; y:159),
    (x:401; y:214),
    (x:381; y:199),
    (x:323; y:263),
    (x:575; y:263)
  );
var
  iGeometrySink: ID2D1GeometrySink;
begin
  D2DFactory.CreatePathGeometry(Result);
  Result.Open(iGeometrySink);
  with iGeometrySink do begin
    SetFillMode(D2D1_FILL_MODE_WINDING);
    BeginFigure(pts[0], D2D1_FIGURE_BEGIN_FILLED);
    AddLines(@pts[1], Length(pts)-1);
    EndFigure(D2D1_FIGURE_END_CLOSED);
    Close;
  end;
end;

{太阳的路径}
function GetSunGeometry: ID2D1PathGeometry;
var
  iGeometrySink: ID2D1GeometrySink;
begin
  D2DFactory.CreatePathGeometry(Result);
  Result.Open(iGeometrySink);
  with iGeometrySink do begin
    SetFillMode(D2D1_FILL_MODE_WINDING);
    {太阳}
    BeginFigure(D2D1PointF(270,255), D2D1_FIGURE_BEGIN_FILLED);
    AddArc(D2D1ArcSegment(
      D2D1PointF(440,255),
      D2D1SizeF(85,85),
      0,
      D2D1_SWEEP_DIRECTION_CLOCKWISE,
      D2D1_ARC_SIZE_SMALL
    ));
    EndFigure(D2D1_FIGURE_END_CLOSED);
    {太阳的光辉}
    BeginFigure(D2D1PointF(299,182), D2D1_FIGURE_BEGIN_HOLLOW);
    AddBezier(D2D1BezierSegment(D2D1PointF(299,182), D2D1PointF(294,176), D2D1PointF(285,178)));
    AddBezier(D2D1BezierSegment(D2D1PointF(276,179), D2D1PointF(272,173), D2D1PointF(272,173)));
    EndFigure(D2D1_FIGURE_END_OPEN);
    //
    BeginFigure(D2D1PointF(354,156), D2D1_FIGURE_BEGIN_HOLLOW);
    AddBezier(D2D1BezierSegment(D2D1PointF(354,156), D2D1PointF(358,149), D2D1PointF(354,142)));
    AddBezier(D2D1BezierSegment(D2D1PointF(349,134), D2D1PointF(354,127), D2D1PointF(354,127)));
    EndFigure(D2D1_FIGURE_END_OPEN);
    //
    BeginFigure(D2D1PointF(322,164), D2D1_FIGURE_BEGIN_HOLLOW);
    AddBezier(D2D1BezierSegment(D2D1PointF(322,164), D2D1PointF(322,156), D2D1PointF(314,152)));
    AddBezier(D2D1BezierSegment(D2D1PointF(306,149), D2D1PointF(305,141), D2D1PointF(305,141)));
    EndFigure(D2D1_FIGURE_END_OPEN);
    //
    BeginFigure(D2D1PointF(385, 164), D2D1_FIGURE_BEGIN_HOLLOW);
    AddBezier(D2D1BezierSegment(D2D1PointF(385,164), D2D1PointF(392,161), D2D1PointF(394,152)));
    AddBezier(D2D1BezierSegment(D2D1PointF(395,144), D2D1PointF(402,141), D2D1PointF(402,142)));
    EndFigure(D2D1_FIGURE_END_OPEN);
    //
    BeginFigure(D2D1PointF(408,182), D2D1_FIGURE_BEGIN_HOLLOW);
    AddBezier(D2D1BezierSegment(D2D1PointF(408,182), D2D1PointF(416,184), D2D1PointF(422,178)));
    AddBezier(D2D1BezierSegment(D2D1PointF(428,171), D2D1PointF(435,173), D2D1PointF(435,173)));
    EndFigure(D2D1_FIGURE_END_OPEN);
    Close;
  end;
end;

{小河的路径}
function GetRiverGeometry: ID2D1PathGeometry;
var
  iGeometrySink: ID2D1GeometrySink;
begin
  D2DFactory.CreatePathGeometry(Result);
  Result.Open(iGeometrySink);
  with iGeometrySink do begin
    SetFillMode(D2D1_FILL_MODE_WINDING);
    BeginFigure(D2D1PointF(183, 392), D2D1_FIGURE_BEGIN_FILLED);
    AddBezier(D2D1BezierSegment(D2D1PointF(238,284), D2D1PointF(472,345), D2D1PointF(356,303)));
    AddBezier(D2D1BezierSegment(D2D1PointF(237,261), D2D1PointF(333,256), D2D1PointF(333,256)));
    AddBezier(D2D1BezierSegment(D2D1PointF(335,257), D2D1PointF(241,261), D2D1PointF(411,306)));
    AddBezier(D2D1BezierSegment(D2D1PointF(574,350), D2D1PointF(288,324), D2D1PointF(296,392)));
    EndFigure(D2D1_FIGURE_END_OPEN);
    Close;
  end;
end;

{绘制太阳需要的放射渐变画刷}
function GetSunRadialGradientBrush(RenderTarget: ID2D1RenderTarget): ID2D1RadialGradientBrush;
var
  arrGradientStop: array[0..2] of TD2D1GradientStop;
  iGradientStops: ID2D1GradientStopCollection;
begin
  arrGradientStop[0].position := 0;
  arrGradientStop[0].color := D2D1ColorF(clWebGold);
  arrGradientStop[1].position := 0.85;
  arrGradientStop[1].color := D2D1ColorF(clWebOrange, 0.8);
  arrGradientStop[2].position := 1;
  arrGradientStop[2].color := D2D1ColorF(clWebOrangeRed, 0.7);

  RenderTarget.CreateGradientStopCollection(
    @arrGradientStop[0], Length(arrGradientStop),
    D2D1_GAMMA_2_2,
    D2D1_EXTEND_MODE_CLAMP,
    iGradientStops);

  RenderTarget.CreateRadialGradientBrush(
    D2D1RadialGradientBrushProperties(D2D1PointF(330,330), D2D1PointF(140,140), 140, 140),
    nil,
    iGradientStops,
    Result
  );
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  cvs: TDirect2DCanvas;
  iLeftMountainGeometry,
  iRightMountainGeometry,
  iSunGeometry,
  iRiverGeometry: ID2D1PathGeometry;
begin
  iLeftMountainGeometry := GetLeftMountainGeometry;
  iRightMountainGeometry := GetRightMountainGeometry;
  iSunGeometry := GetSunGeometry;
  iRiverGeometry := GetRiverGeometry;

  cvs := TDirect2DCanvas.Create(Canvas, ClientRect);
  cvs.BeginDraw;
  cvs.RenderTarget.Clear(D2D1ColorF(clWhite));
  {因为太阳被挡在小山后面,先画太阳}
  cvs.DrawGeometry(iSunGeometry);
  cvs.Brush.Handle := GetSunRadialGradientBrush(cvs.RenderTarget);
  cvs.FillGeometry(iSunGeometry);
  {左边小山}
  cvs.DrawGeometry(iLeftMountainGeometry);
  cvs.Brush.Color := clOlive;
  cvs.FillGeometry(iLeftMountainGeometry);
  {右边小山}
  cvs.DrawGeometry(iRightMountainGeometry);
  cvs.Brush.Color := clWebYellowGreen;
  cvs.FillGeometry(iRightMountainGeometry);
  {小河}
  cvs.DrawGeometry(iRiverGeometry);
  cvs.Brush.Color := clWebLightSkyBlue;
  cvs.FillGeometry(iRiverGeometry);

  cvs.EndDraw;
  cvs.Free;
end;

end.


效果图:



posted on   万一  阅读(2098)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
历史上的今天:
2010-04-06 学 Win32 汇编[11]: 数据对齐相关的伪指令(ALIGN、EVEN、ORG)
2010-04-06 学 Win32 汇编[10]: TYPE、$、LENGTHOF、SIZEOF、TYPEDEF
2008-04-06 PChar 类型的又一些用法


点击右上角即可分享
微信分享提示