不是很明白D2D1_FIGURE_BEGIN:为什么需要它,有什么区别,为什么微软的示例代码无论如何都会不匹配类型?

I don't fully understand D2D1_FIGURE_BEGIN: why is it needed, what's the difference, and why does Microsoft's sample code mismatch types anyway?

在将我的 GDI 代码迁移到 Direct2D 之前,我正在阅读它,并且我正在尝试弄清楚路径是如何工作的。我了解与几何和几何汇相关的大部分工作,但有一件事我不明白:D2D1_FIGURE_BEGIN 类型及其 BeginFigure().

的参数

首先,为什么需要这个值?为什么几何体需要提前知道它是填充的还是空心的?我不知道其他绘图 API 关心路径对象是否提前填充;您只需定义形状的端点,然后 然后 调用 fill()stroke() 来绘制您的路径,那么几何有何不同?

如果此参数是必需的,选择一个值而不是另一个值对我绘制的形状有何影响?

最后,如果我正确理解这个枚举的用法,你应该只使用 FillGeometry() 的填充路径和 DrawGeometry() 的空心路径。但是,the hourglass example here and cited by several method documentation pages (like the BeginFigure() one) 创建了一个填充图形并用 DrawGeometry()FillGeometry() 绘制了它!这是未定义的行为吗?它与示例图片中渐变周围的蓝色边框有什么关系吗?我在代码中的任何地方都没有看到它?

谢谢。

编辑 好吧,我想我明白渐变的奇怪轮廓是怎么回事了:渐变也在过渡 alpha 值,并且填充与笔划重叠,因为笔划居中在线上,填充绘制在 之后 描边。这仍然不能解释为什么我可以用填充几何体填充和描边,或者空心几何体和填充几何体之间的区别是什么......

我也刚刚意识到空心几何体被记录为没有边界。这是否意味着空心几何体纯粹是对仅描边几何体的优化,在其他方面与填充几何体的行为相同?

如果你想更好地理解Direct2D的几何系统,我推荐学习WPF几何系统。 WPF、XPS、Direct2D、Silverlight 和较新的 "XAML" 框架都使用相同的构建块(相同的 "language",如果您愿意的话)。我发现在 WPF 中更容易理解面向对象的声明式 API,然后在 Direct2D 中使用命令式 API 变得轻而易举。您可以将 WPF 的可变几何系统视为来自 Java 的 "builder" 模式的实现,其中 build() 方法在幕后(对您隐藏)并在它运行时吐出一个不可变的 Direct2D 几何是时候在屏幕上呈现东西了(WPF 使用一种叫做 "MIL" 的东西,它是 IIRC/AFAICT,Direct2D 是从中分叉出来的。它们真的是同一回事!)编写代码在两个表示,例如遍历 WPF PathGeometry 并将其流式传输到 Direct2D 几何接收器,您还可以使用 ID2D1PathGeometry::Stream 和自定义 ID2D1GeometrySink 实现来重构 WPF PathGeometry。

(顺便说一句,这不是理论上的 :) 这正是我在 Paint.NET 4.0+ 中所做的:我使用 WPF 风格的声明式可变对象模型,在渲染时吐出不可变的 Direct2D 几何图形。它真的很好用!)

好吧,无论如何,直接回答您的具体问题:BeginFigure()D2D1_FIGURE_BEGIN 直接映射到 WPF 中的 PathFigure.IsFilled 属性。为了直观地了解这有什么影响,您可以使用 KaXAML 之类的工具来处理 WPF 或 Silverlight 示例中的一些几何图形,并查看结果。并且 WPF 和 Silverlight 的文档肯定比 Direct2D 更好。

另一个关键概念是 DrawGeometry 基本上是一个辅助方法。您可以通过先使用 ID2D1Geometry::Widen 加宽几何形状然后使用 FillGeometry 来完成同样的事情("widening" 对我来说似乎用词不当,顺便说一句:在 Photoshop 或 Illustrator 中,您可能会使用像 "stroke" 这样的动词)。这并不是说任何一个总是执行 better/worse ...一定要进行基准测试。我已经看到它是双向的。您可以将此视为辅助方法的原因取决于光栅化引擎的最低级别只能做一件事:填充三角形。所有其他绘图 "primitives" 必须转换为三角形列表或条带(这也是为什么 ID2D1Mesh 如此之快:它绕过了各种处理代码!)。填充几何体需要将其内部细分为三角形条带列表,然后可以由 Direct3D 填充。 "Drawing" 几何图形需要应用描边(宽度 and/or 样式):即使是简单的 1 像素宽直线也必须先转换为 2 个填充三角形。

哦,另外,如果你想计算空心图形几何体的 "real" 边界,使用 ID2D1Geometry::GetWidenedBounds 和 strokeWidth 为零。这是令我困惑的 Direct2D 和 WPF 之间的差异。 Geometry.Bounds(在 WPF 中)等同于 ID2D1Geometry::GetWidenedBounds(0.0f).