在我将GDI代码迁移到Direct2D之前,我正在读取它,并且我试图弄清楚路径是如何工作的。我理解大部分涉及几何和几何接收器的工作,但有一件事我不明白:D2D1_FIGURE_BEGIN
类型及其参数BeginFigure()
。
首先,为什么甚至需要这个值?为什么几何体需要知道它是否已经提前填充或凹陷?我不知道其他关于路径对象是否被提前填充的绘图API;你只需定义形状的端点,然后然后调用fill()
或stroke()
来绘制路径,那么几何有何不同?
如果这个参数是必要的,那么选择一个值而不是另一个值会影响我绘制的形状吗?
最后,如果我正确理解了此枚举的用法,您应该只使用DrawGeometry()
的填充路径和DrawGeometry()
的空心路径。但是,the hourglass example here并被多个方法文档页面引用(例如BeginFigure()
one)会创建一个填充的数字,并使用DrawGeometry()
和FillGeometry()
绘制它!这是未定义的行为吗?它是否与示例图片中渐变周围的蓝色边框有关,我在代码中的任何地方都看不到它?
感谢。
编辑好吧我想我理解渐变的奇怪轮廓正在发生什么:渐变也是转换alpha值,填充与笔画重叠,因为笔划以线为中心,填充在笔划后绘制。这仍然无法解释为什么我可以用填充的几何体填充和描边,或者空心几何体和填充几何体之间的区别是什么......
此外,我才意识到空心几何形状被记录为没有边界。这是否意味着空心几何形状纯粹是仅限行程几何形状的优化,否则与填充几何体的行为相同?
答案 0 :(得分:1)
如果您想更好地了解Direct2D的几何系统,我建议您研究WPF几何系统。 WPF,XPS,Direct2D,Silverlight和更新的" XAML"框架都使用相同的构建块(相同的#34;语言",如果你愿意的话)。我发现在WPF中理解面向对象的API更容易理解,之后使用Direct2D中的命令式API变得轻而易举。您可以将WPF的可变几何系统视为" builder"的实现。来自Java的模式,其中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
("扩展"对我来说似乎是一个误称,顺便说一下:在Photoshop或Illustrator中你可以做到&#39}来完成同样的事情。 ; d可能使用像" stroke")这样的动词。这并不是说任何一个总是表现更好/更差......一定要确定基准。我已经看到它双向发展。您可以将其视为辅助方法的原因取决于光栅化引擎的最低级别只能做一件事:填充三角形。所有其他绘图"原语"必须转换为三角形列表或条带(这也是ID2D1Mesh
如此快速的原因:它绕过了各种处理代码!)。填充几何体需要将其内部细分为三角形条带列表,然后可以通过Direct3D填充。 "绘图"几何图形需要应用笔触(宽度和/或样式):即使是简单的1像素宽的直线也必须首先转换为2个填充的三角形。
哦,如果你想计算"真实"使用空心数字的几何边界,使用行程宽度为零的ID2D1Geometry::GetWidenedBounds
。这是Direct2D和WPF之间的差异让我感到困惑。 Geometry.Bounds
(在WPF中)相当于ID2D1Geometry::GetWidenedBounds(0.0f)
。