Requires: Direct2D.lg32
Creates a path geometry Direct2D object and a geometry sink to populate the geometry.
Set geoObj = D2PathGeometry()
Set geoSink = D2GeometrySink(geoObj [,fFillWinding])
D2Sink_FillMode geoSink, fillMode
geoObj, geoSink | : Object |
fFillWinding | : bool exp |
fillMode | : iexp |
Direct2D geometries enable you to describe two-dimensional figures, cache them and lateron draw them using D2DrawGeometry and/or D2FillGeometry. The D2PathGeometry function creates a path geometry to collect a series of figures that describe the geometry. To populate a path geometry a geometry sink (ID2D1GeometrySink) is created by passing in the geometry object:
Set geoSink = D2GeometrySink(geoObj)
An ID2D1GeometrySink consists of one or more figures and describes a geometric path that can contain lines, arcs, cubic Bezier curves, and quadratic Bezier curves. The D2GeometrySink function is used to open a sink for the geometry and (usually) these functions are used in pairs. The fill mode of the sink defaults to D2D1_FILL_MODE_ALTERNATE. To set the fill mode, specify True for the optional parameter fFillWinding, or call D2Sink_FillMode before the first call to D2Sink_BeginFigure. The fill mode specifies the method used to determine which points are inside the geometry described by this geometry sink and which points are outside.
To create a figure the application needs to a call a series of D2Sink_* commands. Call the D2Sink_BeginFigure command, passing in the figure's starting point, and then use the D2Sink_Add* commands (such as D2Sink_AddLine(s) and D2Sink_AddBezier) to add segments. When you are finished adding segments, call the D2Sink_EndFigure command. You can repeat this sequence to create additional figures. When you are finished creating figures, call the D2Sink_Close command.
The example shows the GFA-BASIC 32 implementation of the SDK mountain-scenery example found at: Path Geometries Overview - Win32 apps | Microsoft Docs.
'
' D2PathGeometry sample (dpi-unaware)
' GB32 implementation of
' https://docs.microsoft.com/en-us/windows/win32/direct2d/path-geometries-overview
'
$Library "direct2d"
Global Object Win1RT
OpenW 1, 0, 0, 720, 460, ~15
Set Win1RT = D2GetRT() ' DC render target
' Create the geometry's for scenery
Global Object LeftMountainGeometry, RightMountainGeometry, _
SunGeometry, RiverGeometry, _
RadialGradientBrush
DefScenery()
Do
Sleep
Until Me Is Nothing
Sub Win_1_Paint
D2BeginDraw Win1RT, D2C_Wheat
' Draw sun
D2FillGeometry SunGeometry, RadialGradientBrush
D2DrawGeometry SunGeometry
' Draw left mountain
D2DefFill D2C_OliveDrab
D2FillGeometry LeftMountainGeometry
D2DrawGeometry LeftMountainGeometry
' Draw river
D2DefFill D2C_LightSkyBlue
D2FillGeometry RiverGeometry
D2DrawGeometry RiverGeometry
' Draw right mountain
D2DefFill D2C_YellowGreen
D2FillGeometry RightMountainGeometry
D2DrawGeometry RightMountainGeometry
D2EndDraw
EndSub
Sub Win_1_ReSize
D2ResizeRT Win1RT, _X, _Y
EndSub
Procedure DefScenery()
Local Object Sink ' released when it goes out-of-scope
Local points(0 .. 6) As D2D1_POINT_2F
Local arcSeg As D2D1_ARC_SEGMENT
Local bezier As D2D1_BEZIER_SEGMENT
' Left mountain
Set LeftMountainGeometry = D2PathGeometry()
Set Sink = D2GeometrySink(LeftMountainGeometry)
D2Sink_FillMode Sink, D2D1_FILL_MODE_WINDING
D2Sink_BeginFigure Sink, 346, 255 ' first point, D2FillGeometry will fill
points(0).x = 267, points(0).y = 177
points(1).x = 236, points(1).y = 192
points(2).x = 212, points(2).y = 160
points(3).x = 156, points(3).y = 255
points(4).x = 346, points(4).y = 255
D2Sink_AddLines Sink, points(), 5
D2Sink_EndFigure Sink, D2D1_FIGURE_END_CLOSED
D2Sink_Close Sink
' Right mountain
Set RightMountainGeometry = D2PathGeometry()
Set Sink = D2GeometrySink(RightMountainGeometry)
D2Sink_FillMode Sink, D2D1_FILL_MODE_WINDING
D2Sink_BeginFigure Sink, 575, 263 ' first point, D2FillGeometry will fill
points(0).x = 481, points(0).y = 146
points(1).x = 449, points(1).y = 181
points(2).x = 433, points(2).y = 159
points(3).x = 401, points(3).y = 214
points(4).x = 381, points(4).y = 199
points(5).x = 323, points(5).y = 263
points(6).x = 575, points(6).y = 263
D2Sink_AddLines Sink, points(), 7
D2Sink_EndFigure Sink, D2D1_FIGURE_END_CLOSED
D2Sink_Close Sink
' Sun with flares
Set SunGeometry = D2PathGeometry()
Set Sink = D2GeometrySink(SunGeometry)
D2Sink_FillMode Sink, D2D1_FILL_MODE_WINDING
' Sun
D2Sink_BeginFigure Sink, 270, 255 ' first point, D2FillGeometry will fill
arcSeg.point.x = 440, arcSeg.point.y = 255
arcSeg.size.width = 85, arcSeg.size.height = 85
arcSeg.rotationAngle = 0.0
arcSeg.sweepDirection = D2D1_SWEEP_DIRECTION_CLOCKWISE
arcSeg.arcSize = D2D1_ARC_SIZE_SMALL
D2Sink_AddArc Sink, arcSeg
D2Sink_EndFigure Sink, D2D1_FIGURE_END_CLOSED
' Flares
D2Sink_BeginFigure Sink, 299, 182, D2D1_FIGURE_BEGIN_HOLLOW
bezier.point1.x = 299, bezier.point1.y = 182
bezier.point2.x = 294, bezier.point2.y = 176
bezier.point3.x = 285, bezier.point3.y = 178
D2Sink_AddBezier Sink, bezier
bezier.point1.x = 276, bezier.point1.y = 179
bezier.point2.x = 272, bezier.point2.y = 173
bezier.point3.x = 272, bezier.point3.y = 173
D2Sink_AddBezier Sink, bezier
D2Sink_EndFigure Sink
D2Sink_BeginFigure Sink, 354, 156, D2D1_FIGURE_BEGIN_HOLLOW
bezier.point1.x = 354, bezier.point1.y = 156
bezier.point2.x = 358, bezier.point2.y = 149
bezier.point3.x = 354, bezier.point3.y = 142
D2Sink_AddBezier Sink, bezier
bezier.point1.x = 349, bezier.point1.y = 134
bezier.point2.x = 354, bezier.point2.y = 127
bezier.point3.x = 354, bezier.point3.y = 127
D2Sink_AddBezier Sink, bezier
D2Sink_EndFigure Sink
D2Sink_BeginFigure Sink, 322, 164, D2D1_FIGURE_BEGIN_HOLLOW
bezier.point1.x = 322, bezier.point1.y = 164
bezier.point2.x = 322, bezier.point2.y = 156
bezier.point3.x = 314, bezier.point3.y = 152
D2Sink_AddBezier Sink, bezier
bezier.point1.x = 306, bezier.point1.y = 149
bezier.point2.x = 305, bezier.point2.y = 141
bezier.point3.x = 305, bezier.point3.y = 141
D2Sink_AddBezier Sink, bezier
D2Sink_EndFigure Sink
D2Sink_BeginFigure Sink, 385, 164, D2D1_FIGURE_BEGIN_HOLLOW
bezier.point1.x = 385, bezier.point1.y = 164
bezier.point2.x = 392, bezier.point2.y = 161
bezier.point3.x = 394, bezier.point3.y = 152
D2Sink_AddBezier Sink, bezier
bezier.point1.x = 395, bezier.point1.y = 144
bezier.point2.x = 402, bezier.point2.y = 141
bezier.point3.x = 402, bezier.point3.y = 142
D2Sink_AddBezier Sink, bezier
D2Sink_EndFigure Sink
D2Sink_BeginFigure Sink, 408, 182, D2D1_FIGURE_BEGIN_HOLLOW
bezier.point1.x = 408, bezier.point1.y = 182
bezier.point2.x = 416, bezier.point2.y = 184
bezier.point3.x = 422, bezier.point3.y = 178
D2Sink_AddBezier Sink, bezier
bezier.point1.x = 428, bezier.point1.y = 171
bezier.point2.x = 435, bezier.point2.y = 173
bezier.point3.x = 435, bezier.point3.y = 173
D2Sink_AddBezier Sink, bezier
D2Sink_EndFigure Sink
D2Sink_Close Sink
' River
Set RiverGeometry = D2PathGeometry()
Set Sink = D2GeometrySink(RiverGeometry)
D2Sink_FillMode Sink, D2D1_FILL_MODE_WINDING
D2Sink_BeginFigure Sink, 183, 392
bezier.point1.x = 238, bezier.point1.y = 284
bezier.point2.x = 472, bezier.point2.y = 345
bezier.point3.x = 356, bezier.point3.y = 303
D2Sink_AddBezier Sink, bezier
bezier.point1.x = 237, bezier.point1.y = 261
bezier.point2.x = 333, bezier.point2.y = 256
bezier.point3.x = 333, bezier.point3.y = 256
D2Sink_AddBezier Sink, bezier
bezier.point1.x = 335, bezier.point1.y = 257
bezier.point2.x = 241, bezier.point2.y = 261
bezier.point3.x = 411, bezier.point3.y = 306
D2Sink_AddBezier Sink, bezier
bezier.point1.x = 574, bezier.point1.y = 350
bezier.point2.x = 288, bezier.point2.y = 324
bezier.point3.x = 296, bezier.point3.y = 392
D2Sink_AddBezier Sink, bezier
D2Sink_EndFigure Sink
D2Sink_Close Sink
' Create a GradientBrush for the sun geoemetry
Local GS(1 .. 2) As D2Gradient ' the stop collection
GS(1).position = 0.0 ' beginning of gradient is yellow
GS(1).argbcolor = D2C_Yellow
GS(2).position = 1.0 ' end of gradient is orange
GS(2).argbcolor = D2C_Orange
' Create a gradientbrush that fits in the sun circle.
' axis's starting point is center (340,255) and offset (0, 20)
' opacity = 1 and radius of circle is 85, 85
Set RadialGradientBrush = D2BrushGradient(1, GS(), 2, 340, 255, 0, 20, 1, 85, 85) ' gradient axis
EndProc
For more information on Direct2D geometries go to Geometries - Win32 apps .
The D2GeometrySink function calls the ID2D1PathGeometry::Open method see: ID2D1PathGeometry::Open (d2d1.h) - Win32 apps .
More info on fill mode: ID2D1SimplifiedGeometrySink::SetFillMode (d2d1.h) - Win32 apps, an example can be found in D2Sink_AddLines topic.
D2DrawGeometry, D2FillGeometry, D2Sink_BeginFigure, D2Sink_EndFigure, D2Sink_Close, D2Sink_Fillmode, D2Sink_AddLines, D2Sink_AddArc, D2Sink_AddBezier, D2Sink_AddQuadraticBezier.
{Created by Sjouke Hamstra; Last updated: 11/03/2021 by James Gaite}