目前博客園中成系列的Direct2D的教程有
1、萬一的 Direct2D 系列,用的是Delphi 2009
2、zdd的 Direct2D 系列,用的是VS中的C++
3、本文所在的 Direct2D教程 系列,用的是VS2010的Visual Basic語言(可以很方便的轉為C#),基於Windows API Code Pack 1.1。
還有官方的說明文檔 Direct2D ,用的是C++。
本系列的前幾篇文章:
Direct2D教程II——繪制基本圖形和線型(StrokeStyle)的設置詳解
Direct2D教程V——位圖(Bitmap)和位圖筆刷(BitmapBrush)
Direct2D教程VII——變換幾何(TransformedGeometry)對象
研究Direct2D已經有一段時間了。在參閱了一些相關的文章后,發現雖然Windows API Code Pack 1.1對Direct2D封裝的比較好,但也有不足的地方(封裝不完全)。
1、在WIC組件中,沒有封裝BitmapFrameEncode對象
在前文中曾介紹,WIC組件中有BitmapFrameDecode對象,負責圖像數據的解碼。相對應的也應該有BitmapFrameEncode對象,負責圖像數據的編碼。但是在Windows API Code Pack 1.1中的WIC組件中沒有這個對象,僅僅在ImagingBitmap對象中提供了SaveToFile方法。該方法提供了圖像數據保存到文件的途徑,但是擴展性不夠,沒有提供不同格式的參數設置(全采用該格式的默認設置)
2、沒有提供ID2D1Effect對象的封裝
Direct2D提供了一些圖像的特效,通過ID2D1Effect對象實現,參看 Built-in Effects 。由於沒有封裝ID2D1Effect對象,自然也就沒法實現圖像的特效了。
期待Windows API Code Pack的下個版本能彌補上面的兩個不足
言歸正傳,接下來介紹幾何(Geometry)對象的運算。
幾何(Geometry)對象的運算
在前文 Direct2D教程III——幾何(Geometry)對象 中介紹了幾何(Geometry)對象的一些高級功能。其中一個就是兩個幾何(Geometry)對象的運算功能。
運算方法的原型定義
Public Sub CombineWithGeometry(inputGeometry As Direct2D1. Geometry, combineMode As Direct2D1. CombineMode, geometrySink As Direct2D1. ISimplifiedGeometrySink)
Public Sub CombineWithGeometry(inputGeometry As Direct2D1. Geometry, combineMode As Direct2D1. CombineMode, geometrySink As Direct2D1. ISimplifiedGeometrySink, flatteningTolerance As Single)
Public Sub CombineWithGeometry(inputGeometry As Direct2D1. Geometry, combineMode As Direct2D1. CombineMode, geometrySink As Direct2D1. ISimplifiedGeometrySink, flatteningTolerance As Single, inputGeometryTransform As Direct2D1. Matrix3x2F)
Public Enum CombineMode
Union = 0
Intersect = 1
Xor = 2
Exclude = 3
End Enum
該方法的幾個參數的意義如下:
inputGeometry:要和本對象運算的幾何對象,類型是Geometry類
combineMode:運算的類型,類型是CombineMode枚舉,分別是Union(並集)、Intersect(交集)、Xor(異或,兩個對象不屬於對方的部分的合集)、Exclude(差集)
geometrySink:運算的結果要添加到的Sink對象,類型是ISimplifiedGeometry接口
flatteningTolerance:運算結果的精度,類型是數值,表示模擬結果的每條邊的長度,值越小越精細,在可以接受的精度下,可以適當提高精度的數值
inputGeometryTransform:和本對象運算的幾何對象要進行的轉換(Transform),類型是Matrix3x2F,是先轉換再運算
下面是個示例代碼,用兩個矩形對象來演示運算結果,運算的類型我們用Xor表示,其余的和這個類似
Public Class clsDirect2DSample17
Inherits clsDirect2DSample11
Public Shadows Sub Render()
If Not _renderTarget Is Nothing Then
With _renderTarget
.BeginDraw()
.Clear( New Direct2D1. ColorF( Color.Chocolate.ToArgb))
Dim BorderBrush As Direct2D1. SolidColorBrush = _renderTarget.CreateSolidColorBrush( New Direct2D1. ColorF(0, 0, 0))
Dim Bmp As Direct2D1. D2DBitmap = LoadBitmapFromFile( "216.png")
Dim BmpBrush As Direct2D1. BitmapBrush = _renderTarget.CreateBitmapBrush(Bmp)
Dim R1 As Direct2D1. RectangleGeometry, R2 As Direct2D1. RectangleGeometry
R1 = _d2DFactory.CreateRectangleGeometry( New Direct2D1. RectF(30, 30, 150, 150))
R2 = _d2DFactory.CreateRectangleGeometry( New Direct2D1. RectF(60, 60, 180, 180))
Dim P As Direct2D1. PathGeometry
Dim Sink As Direct2D1. GeometrySink
P = _d2DFactory.CreatePathGeometry()
Sink = P.Open
R1.CombineWithGeometry(R2, Direct2D1. CombineMode.Xor, Sink)
Sink.Close()
.DrawGeometry(P, BorderBrush, 3)
.FillGeometry(P, BmpBrush)
.EndDraw()
End With
End If
End Sub
End Class
下面是該示例代碼的效果圖
故事到此似乎很完美,然而,接下來的調試徹底讓我崩潰了,先看看效果圖
代碼和前面的代碼幾乎一樣,僅僅是用EllipseGeometry對象替換了RectangleGeometry對象,結果出現了不可預知的錯誤,大大出乎我的意料。在反復檢查代碼后,證實不是代碼的寫錯后,我開始懷疑Windows API Code Pack 1.1來。
RectangleGeometry對象有一個Rectangle屬性,其還有Top、Left、Right、Bottom四個屬性,在上文的示例代碼中,這四個值分別是30、30、150、150。
同樣EllipseGeometry對象有一個Ellipse屬性,其有Point屬性,其還有X、Y兩個屬性,在調試代碼時發現,這兩個值是0、0。這太奇怪了,正常值是100、100(我設的中心點是(100,100))。這也許是Windows API Code Pack 1.1封裝EllipseGeometry對象的一個失誤。導致這兩個值異常,導致幾何對象運算出現不可預知的錯誤。
遺憾的是,在幾個幾何對象中(RectangleGeometry、EllipseGeometry、RoundedRectangleGeometry、PathGeometry)僅僅有RectangleGeometry對象支持CombineWithGeometry方法,其余的都會出現不可預知的錯誤
我很喜歡Windows API Code Pack 1.1,它是微軟推出的,兼容性應該是最好的。
在測試CombineWithGeometry方法后,大失所望。沒有詳細的測試后,就推出了。期待Windows API Code Pack 的下一個版本,本系列的教程就到此為止了。
聽聞SharpDx對Direct2D封裝的很好,下圖是SharpDx官網的說明圖
可以看出SharpDx的優勢了,打算研究一段時間。再視情況而定是否寫新的教程系列。
也歡迎網友提供相關的教程,謝謝!!!!!