文章出處

目前,在博客園上,相對寫得比較好的兩個關于Direct2D的教程系列,分別是萬一Direct2D系列和zddDirect2D系列。有興趣的網友可以去看看。本系列也是介紹Direct2D的教程,是基于Windows API Code Pack 1.1的Direct2D的教程,如果要調試文中的代碼的話,還得參考前文 Direct2D教程I——簡介及首個例子 下載導入Windows API Code Pack 1.1的動態庫

 

在前文 Direct2D教程I——簡介及首個例子 簡單介紹了Direct2D,并給了一個簡單的示例。接下來,本文對一些基本的繪圖命令做個介紹

 

繪制基本圖形:直線、矩形、圓角矩形、橢圓

 

和GDI+類似,在RenderTarget對象下有各個繪圖命令(GDI+是在Graphics對象下有各個繪圖命令),下面是各個基本圖形的繪圖命令的函數原型

 

直線:
Public Sub DrawLine(firstPoint As Direct2D1.Point2F, secondPoint As Direct2D1.Point2F, brush As Direct2D1.Brush, skrokeWidth As Single, strokeStyle As Direct2D1.StrokeStyle)

 

矩形:
Public Sub DrawRectangle(rect As Direct2D1.RectF, brush As Direct2D1.Brush, strokeWidth As Single
Public Sub DrawRectangle(rect As Direct2D1.RectF, brush As Direct2D1.Brush, strokeWidth As Single, strokeStyle As Direct2D1.StrokeStyle
Public Sub FillRectangle(rect As Direct2D1.RectF, brush As Direct2D1.Brush)

 

圓角矩形:
Public Sub DrawRoundedRectangle(roundedRect As Direct2D1.RoundedRect, brush As Direct2D1.Brush, strokeWidth As Single)
Public Sub DrawRoundedRectangle(roundedRect As Direct2D1.RoundedRect, brush As Direct2D1.Brush, strokeWidth As Single, strokeStyle As Direct2D1.StrokeStyle
Public Sub FillRoundedRectangle(roundedRect As Direct2D1.RoundedRect, brush As Direct2D1.Brush)

 

橢圓:
Public Sub DrawEllipse(ellipse As Direct2D1.Ellipse, brush As Direct2D1.Brush, strokeWidth As Single)
Public Sub DrawEllipse(ellipse As Direct2D1.Ellipse, brush As Direct2D1.Brush, strokeWidth As Single, strokeStyle As Direct2D1.StrokeStyle
Public Sub FillEllipse(ellipse As Direct2D1.Ellipse, brush As Direct2D1.Brush)

 

從上面的函數原型可以看出,以Draw開頭的函數都是繪制函數。以Fill開頭的函數都是填充函數。繪制函數的線寬由strokeWidth參數指定,繪制函數的線型由strokeStyle參數指定(默認是實線)。和GDI+不同的是,在Direct2D中,不再區分Brush(畫刷)和Pen(畫筆)對象,而統一用Brush(畫刷)對象,在用Brush(畫刷)繪制線的時候再指定線寬和線型參數。

 

從參數strokeWidth和參數strokeStyle來看,都帶有單詞stroke。熟悉PS的都知道,stroke指的是描邊,在PS中描邊的位置分為“外部”、“內部”、“居中”。那么在Direct2D中,這里的描邊的位置在哪兒呢?我們用代碼實驗一下。

 

說明:為了代碼的復用,我們把前文中的_d2DFactory和_renderTarget修飾限定詞從Private改為Protected。這樣在后面的例子中直接繼承前文的類,也可以直接用_d2DFactory和_renderTarget這兩個對象。

 

先給出Point2FRectFRoundedRectEllipse這四個類的原型定義,參數都簡介明了,不再詳述


Direct2D1.Point2F(x As Single, y As Single)
Direct2D1.RectF(left As Single, top As Single, right As Single, buttom As Single)
Direct2D1.RoundedRect(rect As Direct2D1.RectF, radiusX As Single, radiusY As Single)
Direct2D1.Ellipse(point As Direct2D1.Point2F, radiusX As Single, radiusY As Single)

 

下面是實驗示例代碼


Public Class clsDirect2DSample2
    Inherits clsDirect2DSample

    Public Shadows Sub Render()
        If Not _renderTarget Is Nothing Then

            With _renderTarget
                .BeginDraw()

                Dim F1 As New Direct2D1.RectF(0, 0, 100, 50)
                Dim F2 As New Direct2D1.RectF(200, 200, 300, 250)
                Dim B As Direct2D1.SolidColorBrush = _renderTarget.CreateSolidColorBrush(New Direct2D1.ColorF(1, 0, 0))

                _renderTarget.DrawRectangle(F1, B, 10)
                _renderTarget.DrawRectangle(F2, B, 10)

                .EndDraw()
            End With

        End If
    End Sub

End Class

 

從上圖的代碼來看,在(0,0)位置上畫了一個100*50的矩形,描邊寬度10px。在(200,200)位置上畫了一個矩形,描邊寬度10px,如下圖所示

image

 

從上面的效果可以看出兩點:

一是左上角的矩形說明,Direct2D中的描邊類型應該是“居中”;

二是右邊的矩形說明Direct2D中的RectF定義和原本GDI+中的RectangleF定義不同,Direct2D中的RectF中后兩個參數是右下角的坐標,而GDI+中的RectangleF中的后兩個參數指的是矩形的寬和高。

 

線型(StrokeStyle)的設置

在上面的函數原型中,線型是由參數strokeStyle決定的,它是StrokeStyle類。這個類不能直接初始化,必須由D2DFactory對象的CreateStrokeStyle函數創建(Direct2D中有不少的類不能直接初始化,必須由D2DFactory或RenderTarget對象的相應的函數創建,如上面的SolidColorBrush對象就必須由RenderTarget對象的CreateSolidColorBrush函數創建)。

 

先看看CreateStrokeStyle函數的原型定義:
Public Function CreateStrokeStyle(strokeStyleProperties As Direct2D1.StrokeStyleProperties) As Direct2D1.StrokeStyle
Public Function CreateStrokeStyle(strokeStyleProperties As Direct2D1.StrokeStyleProperties, dashes() As Single) As Direct2D1.StrokeStyle

 

主要是通過strokeStyleProperties參數來設置線型,來看看StrokeStyleProperties結構及其參數對象的原型定義。

Direct2D1.StrokeStyleProperties(startCap As Direct2D1.CapStyle, endCap As Direct2D1.CapStyle, dashCap As Direct2D1.CapStyle, _
                                            lineJoin As Direct2D1.LineJoin, miterLimit As Single, _
                                            dashStyle As Direct2D1.DashStyle, dashOffset As Single)
Public Enum CapStyle
    Flat = 0
    Square = 1
    Round = 2
    Triangle = 3
End Enum
Public Enum LineJoin
    Miter = 0
    Bevel = 1
    Round = 2
    MiterOrBevel = 3
End Enum
Public Enum DashStyle
    Solid = 0
    Dash = 1
    Dot = 2
    DashDot = 3
    DashDotDot = 4
    Custom = 5
End Enum

其中CapStyle枚舉指的是線端的線頭類型,分別是Flat(平整,即無)、Square(方塊)、Round(圓)、Triangle(三角)。和GDI+中的DashCap枚舉類似,多了一個Square(方塊),而在下面的例子中會說明Flat和Square的區別。參數startCap決定線起點的線頭類型、endCap決定線終點的線頭類型、dashCap決定中間劃線端的線頭類型。

而DashStyle枚舉指的是線型,分別是Solid(實線)、Dash(劃線)、Dot(點線)、DashDot(點劃線)、DashDotDot(點點劃線)、Custom(自定義)。和GDI+中的DashStyle一樣。

參數dashOffset指的是點劃線的偏移量

 

下面的代碼是對上面的兩個枚舉的演示,請注意枚舉CapStyle中的Flat和Square的區別。


Public Class clsDirect2DSample3
    Inherits clsDirect2DSample

    Public Shadows Sub Render()
        If Not _renderTarget Is Nothing Then

            With _renderTarget
                .BeginDraw()

                Dim B As Direct2D1.SolidColorBrush = _renderTarget.CreateSolidColorBrush(New Direct2D1.ColorF(1, 0, 0))
                Dim SP As New Direct2D1.StrokeStyleProperties()
                Dim S As Direct2D1.StrokeStyle

                SP.StartCap = Direct2D1.CapStyle.Flat
                SP.EndCap = Direct2D1.CapStyle.Flat
                S = _d2DFactory.CreateStrokeStyle(SP)
                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 20), New Direct2D1.Point2F(200, 20), B, 8, S)

                SP.StartCap = Direct2D1.CapStyle.Square
                SP.EndCap = Direct2D1.CapStyle.Square
                S = _d2DFactory.CreateStrokeStyle(SP)
                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 40), New Direct2D1.Point2F(200, 40), B, 8, S)

                SP.StartCap = Direct2D1.CapStyle.Round
                SP.EndCap = Direct2D1.CapStyle.Round
                S = _d2DFactory.CreateStrokeStyle(SP)
                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 60), New Direct2D1.Point2F(200, 60), B, 8, S)

                SP.StartCap = Direct2D1.CapStyle.Triangle
                SP.EndCap = Direct2D1.CapStyle.Triangle
                S = _d2DFactory.CreateStrokeStyle(SP)
                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 80), New Direct2D1.Point2F(200, 80), B, 8, S)

                SP.StartCap = Direct2D1.CapStyle.Flat
                SP.EndCap = Direct2D1.CapStyle.Flat
                SP.DashCap = Direct2D1.CapStyle.Round

                SP.DashStyle = Direct2D1.DashStyle.Solid
                S = _d2DFactory.CreateStrokeStyle(SP)
                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 120), New Direct2D1.Point2F(200, 120), B, 6, S)

                SP.DashStyle = Direct2D1.DashStyle.Dash
                S = _d2DFactory.CreateStrokeStyle(SP)
                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 140), New Direct2D1.Point2F(200, 140), B, 6, S)

                SP.DashStyle = Direct2D1.DashStyle.Dot
                S = _d2DFactory.CreateStrokeStyle(SP)
                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 160), New Direct2D1.Point2F(200, 160), B, 6, S)

                SP.DashStyle = Direct2D1.DashStyle.DashDot
                S = _d2DFactory.CreateStrokeStyle(SP)
                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 180), New Direct2D1.Point2F(200, 180), B, 6, S)

                SP.DashStyle = Direct2D1.DashStyle.DashDotDot
                S = _d2DFactory.CreateStrokeStyle(SP)
                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 200), New Direct2D1.Point2F(200, 200), B, 6, S)

                .EndDraw()
            End With
        End If
    End Sub
End Class

 

image

上面四條線是演示枚舉CapStyle的四種類型,注意第一條線是Flat,第二條線是Square。雖然都是方形,但是很明顯第二條線比第一條線兩邊還多出一點(方形線帽)

下面五條線是演示枚舉DashStyle表示的五個線型。注意:上面代碼中紅色的部分,DashCap不能設置為Direct2D1.CapStyle.Flat,如果設置為Flat,則所有的點都不見了;設置其他三種類型分別代表不同的點(方形點、圓點、菱形點)。

 

再說說枚舉DashStyle中的Custom線型。設定為Custom后,必須用一個數組來指定自定義劃線的線型。數組按照{實、空、實、空……}順序來指定各部分的長度,單位是線寬。

例如{2,2}表示2線寬長的實線和2線寬長的空白組成的劃線,也就是枚舉DashStyle中的Dash

{0,2}表示0線寬長的實線和2線寬長的空白組成的劃線,就是枚舉DashStyle中的Dot。這也解釋了DashCap設置為Direct2D1.CapStyle.Flat時,為何點不見了(設置為其他值時,點實際上是由線頭組成的,點本身的長度為0)。

以此類推,{2,2,0,2}表示DashStyle中的DashDot,{2,2,0,2,0,2}表示DashStyle中的DashDotDot

要注意的是,只有枚舉DashStyle設置為Custom時,才能傳遞數組,否則會直接報錯的。

 

最后說說LineJoin枚舉,指的是連接兩條線的連接方式。分別是Miter(折角)、Bevel(倒角)、Round(圓角)、MiterOrBevel(折角或倒角)。和GDI+中的LineJoin枚舉類似,只是MiterOrBevel好像對應GDI+中LineJoin枚舉中的MiterClipped。

說說MiterOrBevel,當折角的值沒有超過指定的值(系統指定)時,是Miter(折角),反之超過的話是Bevel(倒角)。

參數miterLimit是指折角的限制,低于限制時會自動添加倒角。參數miterLimit最小是1。注意的是miterLimit參數并不是配合LineJoin使用。當miterLimit設置為1的時候,下面的例子中,LineJoin枚舉設置成Miter、Bevel、MiterOrBevel效果是一樣的。當miterLimit設置為3的時候,LineJoin枚舉設置成Miter、Bevel、MiterOrBevel效果才是不一樣的

 

下面是LineJoin的示例,由于是演示兩條線的連接,故用了一些后面才會詳述的代碼。不過,不影響我們理解枚舉LineJoin的各個設置值的意義。

左上是Miter,右上是Bevel,左下是Round,右下是MiterOrBevel

 
Public Class clsDirect2DSample4
    Inherits clsDirect2DSample

    Public Shadows Sub Render()
        If Not _renderTarget Is Nothing Then

            With _renderTarget
                .BeginDraw()

                Dim B As Direct2D1.SolidColorBrush = _renderTarget.CreateSolidColorBrush(New Direct2D1.ColorF(1, 0, 0))
                Dim SP As New Direct2D1.StrokeStyleProperties()
                Dim S As Direct2D1.StrokeStyle

                Dim PG As Direct2D1.PathGeometry
                Dim sink As Direct2D1.GeometrySink

                PG = _d2DFactory.CreatePathGeometry
                sink = PG.Open

                sink.BeginFigure(New Direct2D1.Point2F(17, 17), Direct2D1.FigureBegin.Hollow)

                sink.AddLine(New Direct2D1.Point2F(45, 85))
                sink.AddLine(New Direct2D1.Point2F(85, 45))
                sink.AddLine(New Direct2D1.Point2F(85, 125))
                sink.AddLine(New Direct2D1.Point2F(165, 17))

                sink.EndFigure(Direct2D1.FigureEnd.Open)
                sink.Close()

                SP.LineJoin = Direct2D1.LineJoin.Miter
                SP.MiterLimit = 3
                S = _d2DFactory.CreateStrokeStyle(SP)

                .DrawGeometry(PG, B, 10, S)



                PG = _d2DFactory.CreatePathGeometry
                sink = PG.Open

                sink.BeginFigure(New Direct2D1.Point2F(217, 17), Direct2D1.FigureBegin.Hollow)

                sink.AddLine(New Direct2D1.Point2F(245, 85))
                sink.AddLine(New Direct2D1.Point2F(285, 45))
                sink.AddLine(New Direct2D1.Point2F(285, 125))
                sink.AddLine(New Direct2D1.Point2F(365, 17))

                sink.EndFigure(Direct2D1.FigureEnd.Open)
                sink.Close()

                SP.LineJoin = Direct2D1.LineJoin.Bevel
                SP.MiterLimit = 3
                S = _d2DFactory.CreateStrokeStyle(SP)

                .DrawGeometry(PG, B, 10, S)


                PG = _d2DFactory.CreatePathGeometry
                sink = PG.Open

                sink.BeginFigure(New Direct2D1.Point2F(17, 217), Direct2D1.FigureBegin.Hollow)

                sink.AddLine(New Direct2D1.Point2F(45, 285))
                sink.AddLine(New Direct2D1.Point2F(85, 245))
                sink.AddLine(New Direct2D1.Point2F(85, 325))
                sink.AddLine(New Direct2D1.Point2F(165, 217))

                sink.EndFigure(Direct2D1.FigureEnd.Open)
                sink.Close()

                SP.LineJoin = Direct2D1.LineJoin.Round
                SP.MiterLimit = 3
                S = _d2DFactory.CreateStrokeStyle(SP)

                .DrawGeometry(PG, B, 10, S)


                PG = _d2DFactory.CreatePathGeometry
                sink = PG.Open

                sink.BeginFigure(New Direct2D1.Point2F(217, 217), Direct2D1.FigureBegin.Hollow)

                sink.AddLine(New Direct2D1.Point2F(245, 285))
                sink.AddLine(New Direct2D1.Point2F(285, 245))
                sink.AddLine(New Direct2D1.Point2F(285, 325))
                sink.AddLine(New Direct2D1.Point2F(365, 217))

                sink.EndFigure(Direct2D1.FigureEnd.Open)
                sink.Close()

                SP.LineJoin = Direct2D1.LineJoin.MiterOrBevel
                SP.MiterLimit = 3
                S = _d2DFactory.CreateStrokeStyle(SP)

                .DrawGeometry(PG, B, 10, S)

                .EndDraw()
            End With

        End If
    End Sub


End Class

 

下面是效果圖

image

 

從上圖能看出四種類型的不同。左上是Miter,右上是Bevel,左下是Round,右下是MiterOrBevel

 

在網上搜到的官網的Direct2D的幫助文檔。http://msdn.microsoft.com/zh-cn/library/windows/desktop/dd370990(v=vs.85).aspx,可以參考一下。


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 AutoPoster 的頭像
    AutoPoster

    互聯網 - 大數據

    AutoPoster 發表在 痞客邦 留言(0) 人氣()