Direct2D教程(十二)圖層

來源:互聯網
上載者:User
什麼是Layers?

Layer,中文譯成圖層,在Direct2D中可以用來完成一些特殊效果,使用Layer的時候,先將Layer Push到render target,然後進行繪製,此時是直接繪製在Layer上的,繪製完畢後,將Layer Pop出來,剛剛繪製在Layer上的內容就會組合到render target上。在Direct2D中,Layer使用介面ID2D1Layer來表示。

和畫刷一樣,Layer由render target建立,屬於裝置相關的資源,Layer可以用於任何render target上,只要二者在相同的資源範圍內,在同一時間內,Layer只能用於一個render target。

儘管Layer為建立特效提供了強大的支援人員,但是過度使用Layer將導致D2D程式效能下降,因為操作Layer是比較耗時的,比如清除Layer上的內容,將Layer上繪製的內容混合到render target上都需要時間。

使用Layer的步驟

在Direct2D中,使用Layer的步驟非常簡單,首先建立一個Layer,在建立的時候,會指定一系列Layer的屬性,在繪製之前,先將Layer Push到當前的render target上,然後進行繪製操作,繪製完畢後將Layer Pop出來即可。

建立Layer

建立Layer使用CreateLayer函數,該函數定義如下:

virtual HRESULT CreateLayer(  [in, optional]  D2D1_SIZE_F *size,  [out]           ID2D1Layer **layer) = 0;

參數說明:

size,這是一個矩形地區,定義了建立的Layer的大小(像素尺寸),通常這個值設定為NULL,當調用PushLayer函數時,會自動為Layer分配最小的所需尺寸(通常是render target的尺寸)。

layer,這是一個ID2D1Layer**類型的變數,用來接收建立好的Layer。

建立Layer代碼如下。

ID2D1Layer* g_pLayer = NULL ;// Create layerhr = g_pRenderTarget->CreateLayer(NULL, &g_pLayer) ;if (FAILED(hr)){    MessageBox(hWnd, "Create layer failed!", "Error", 0) ;    return ;}
Push Layer

在BeginDraw函數調用完之後,並且在具體繪製開始之前,將Layer Push到render target。

PushLayer函數定義如下:

void PushLayer(  const D2D1_LAYER_PARAMETERS &layerParameters,  [in]   ID2D1Layer *layer);

參數說明:

layerParameters,這是一個D2D1_LAYER_PARAMETERS類型的變數,它可以指定一系列Layer屬性,D2D1_LAYER_PARAMETERS結構體定義如下:

struct D2D1_LAYER_PARAMETERS {  D2D1_RECT_F         contentBounds;  ID2D1Geometry       *geometricMask;  D2D1_ANTIALIAS_MODE maskAntialiasMode;  D2D1_MATRIX_3X2_F   maskTransform;  FLOAT               opacity;  ID2D1Brush          *opacityBrush;  D2D1_LAYER_OPTIONS  layerOptions;};

參數說明

  • contentBounds,這是一個矩形地區,指定了Layer的繪製範圍,也就是說在該範圍之外的內容都不會被繪製。
  • geometricMask,這是一個幾何圖形,它指定了Layer的哪一部分被顯示,比如你可以設定一Path Geometry,然後繪製一個位元影像,這樣,只有PathGeometry內部的位元影像會顯示,相當於給幾何圖形加上了位元影像紋理。
  • maskAntialiasMode,這個暫時用不到,不理它。
  • maskTransform,這是一個變換矩陣,指定了施加在第二個參數上的幾何變換。
  • opacity,這是一個透明值,指定了Layer與render target混合時使用的透明值。
  • opacityBrush,這是一個畫刷,用來改變Layer的透明值。
  • layerOptions,一個D2D1_LAYER_OPTIONS變數,基本用不到,從windows 8開始,使用D2D1_LAYER_OPTIONS1來代替。

Direct2D提供了一個函數LayerParameters來初始化上面這些參數,這個函數為上面每個參數都提供了一個預設值,如下:

D2D1_LAYER_PARAMETERS LayerParameters(  _In_      const D2D1_RECT_F &contentBounds = D2D1::InfiniteRect(),  _In_opt_  ID2D1Geometry *geometricMask = NULL,  D2D1_ANTIALIAS_MODE maskAntialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,  D2D1_MATRIX_3X2_F maskTransform = D2D1::IdentityMatrix(),  FLOAT opacity = 1.0,  ID2D1Brush *opacityBrush = NULL,  D2D1_LAYER_OPTIONS layerOptions = D2D1_LAYER_OPTIONS_NONE);

在這裡,我們使用這個函數建立一個Layer,在隨後的介紹中,會指定某些特定的參數來達到特殊的效果。

g_pRenderTarget->PushLayer(    D2D1::LayerParameters(),    g_pLayer) ;
繪製

這裡可以繪製任意內容,幾何圖形,文本,圖片等,為了示範Layer的特殊效果,這裡通常繪製位元影像。

Pop Layer

繪製完畢後,將Layer Pop出來,這樣已經在Layer上繪製的內容就會與render target上的內容混合。

Demo

下面幾個Demo都是通過位元影像來示範的,原始的位元影像如下,三個可愛的企鵝。

限定位元影像繪製地區

在PushLayer的時候指定一個矩形地區,在這個地區內的圖形將被顯示,而這個地區外的圖形都將被屏蔽掉,為了方便查看結果,這裡繪製一個位元影像,可以清楚的看到位元影像的那一部分被繪製了。

代碼

g_pRenderTarget->BeginDraw() ;g_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));g_pRenderTarget->PushLayer(    D2D1::LayerParameters(D2D1::RectF(100, 100, 400, 400)),    g_pLayer) ;D2D1_SIZE_F size = g_pBitmap->GetSize() ;D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(0.f, 0.f) ;// Draw bitmapg_pRenderTarget->DrawBitmap(    g_pBitmap,    D2D1::RectF(    upperLeftCorner.x,    upperLeftCorner.y,    upperLeftCorner.x + size.width,    upperLeftCorner.y + size.height)) ;// Pop layer before EndDrawg_pRenderTarget->PopLayer() ;g_pRenderTarget->EndDraw() ;

透明效果

在PushLayer調用完之後,先繪製一個位元影像,然後再繪製三個矩形,這三個矩形使用綠顏色的畫刷來繪製,所以最終的結果就是位元影像和矩形混合後的結果,可以看到矩形呈透明狀,建立綠色畫刷的代碼省略。

代碼

g_pRenderTarget->BeginDraw() ;g_pRenderTarget->PushLayer(D2D1::LayerParameters(), g_pLayer) ;g_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));D2D1_SIZE_F size = g_pBitmap->GetSize() ;D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(0.f, 0.f) ;// Draw bitmapg_pRenderTarget->DrawBitmap(    g_pBitmap,    D2D1::RectF(    upperLeftCorner.x,    upperLeftCorner.y,    upperLeftCorner.x + size.width,    upperLeftCorner.y + size.height)) ;// Opacity mask 1g_pRenderTarget->FillRectangle(D2D1::RectF(100, 100, 200, 200), g_pBlackBrush) ;// Opacity mask 2g_pRenderTarget->FillRectangle(D2D1::RectF(200, 200, 300, 300), g_pBlackBrush) ;// Opacity mask 3g_pRenderTarget->FillRectangle(D2D1::RectF(300, 300, 400, 400), g_pBlackBrush) ;// Pop layer before EndDrawg_pRenderTarget->PopLayer() ;g_pRenderTarget->EndDraw() ;

圓形漸層畫刷

先建立一個圓形的漸層色畫刷,調用PushLayer的時候將這個畫刷作為參數傳遞給PushLayer的第一個參數。接下來繪製一個位元影像,當調用PopLayer的時候兩次繪製的內容將被混合到一起,最後形成一個夜視鏡的效果。

代碼

g_pRenderTarget->BeginDraw() ;// Clear background color to whiteg_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));g_pRenderTarget->PushLayer(    D2D1::LayerParameters(        D2D1::InfiniteRect(),        NULL,        D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,        D2D1::IdentityMatrix(),        1.0f,        g_pRadialGradientBrush,        D2D1_LAYER_OPTIONS_NONE),        g_pLayer);D2D1_SIZE_F size = g_pBitmap->GetSize() ;D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(0.f, 0.f) ;// Draw bitmapg_pRenderTarget->DrawBitmap(    g_pBitmap,    D2D1::RectF(    upperLeftCorner.x,    upperLeftCorner.y,    upperLeftCorner.x + size.width,    upperLeftCorner.y + size.height)) ;// Pop layer before EndDrawg_pRenderTarget->PopLayer() ;g_pRenderTarget->EndDraw() ;

== Happy Coding ==

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.