Översikt över penslar
Den här översikten beskriver hur du skapar och använder ID2D1SolidColorBrush, ID2D1LinearGradientBrush, ID2D1RadialGradientBrushoch ID2D1BitmapBrush objekt för att måla områden med solida färger, toningar och bitmappar. Den innehåller följande avsnitt.
Förutsättningar
Den här översikten förutsätter att du är bekant med strukturen för ett grundläggande Direct2D-program enligt beskrivningen i Skapa ett enkelt Direct2D-program.
Penseltyper
En pensel "målar" ett område med sitt resultat. Olika penslar har olika typer av utdata. Direct2D innehåller fyra penseltyper: ID2D1SolidColorBrush målar ett område med en fast färg, ID2D1LinearGradientBrush med linjär toning, ID2D1RadialGradientBrush med radiell toning och ID2D1BitmapBrush med en bitmapp.
Obs!
Från och med Windows 8 kan du också använda ID2D1ImageBrush, som liknar en bitmappsborste, men du kan också använda primitiver.
Alla penslar ärver från ID2D1Brush och delar en uppsättning vanliga funktioner (inställning och opacitet och transformering av penslar); de skapas av ID2D1RenderTarget och är enhetsberoende resurser: ditt program bör skapa penslar när det initierar återgivningsmålet som penslar ska användas med och återskapa penslar när återgivningsmålet behöver återskapas. (Mer information om resurser finns i Resources Overview.)
Följande bild visar exempel på var och en av de olika penseltyperna.
Grunderna i färg
Innan du målar med en ID2D1SolidColorBrush eller en toningsborste måste du välja färger. I Direct2D representeras färgerna av den D2D1_COLOR_F strukturen (som faktiskt bara är ett nytt namn för den struktur som används av Direct3D, D3DCOLORVALUE).
Före Windows 8 använder D2D1_COLOR_F sRGB-kodning. sRGB-kodning delar in färger i fyra komponenter: röd, grön, blå och alfa. Varje komponent representeras av ett flyttalsvärde med ett normalt intervall på 0,0 till 1,0. Värdet 0,0 anger den fullständiga frånvaron av den färgen, medan värdet 1,0 anger att färgen är helt närvarande. För alfakomponenten representerar 0.0 en helt transparent färg och 1.0 representerar en helt ogenomskinlig färg.
Från och med Windows 8 accepterar D2D1_COLOR_F även scRGB-kodning. scRGB är en övermängd av RGB som tillåter färgvärden över 1,0 och under 0,0.
Om du vill definiera en färg kan du använda D2D1_COLOR_F struktur och initiera fälten själv, eller så kan du använda klassen D2D1::ColorF för att skapa färgen. Klassen ColorF innehåller flera konstruktorer för att definiera färger. Om alfavärdet inte anges i konstruktorerna är det standardvärdet 1.0.
Använd konstruktorn ColorF(Enum, FLOAT) för att ange en fördefinierad färg och ett alfakanalvärde. Ett alfakanalvärde varierar från 0,0 till 1,0, där 0,0 representerar en helt transparent färg och 1,0 representerar en helt ogenomskinlig färg. Följande bild visar flera fördefinierade färger och deras hexadecimala motsvarigheter. En fullständig lista över fördefinierade färger finns i avsnittet Färgkonstanter i klassen ColorF.
I följande exempel skapas en fördefinierad färg och används för att ange färgen på en ID2D1SolidColorBrush.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black, 1.0f),
&m_pBlackBrush
);
Använd ColorF(FLOAT, FLOAT, FLOAT, FLOAT) konstruktorn för att ange en färg i sekvensen för en röd, grön, blå och alfa, där varje element har ett värde mellan 0,0 och 1,0.
I följande exempel anges värdena röd, grön, blå och alfa för en färg.
ID2D1SolidColorBrush *pGridBrush = NULL;
hr = pCompatibleRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF(0.93f, 0.94f, 0.96f, 1.0f)),
&pGridBrush
);
- Använd ColorF(UINT32, FLOAT) konstruktor för att ange hexadecimalt värde för en färg och ett alfavärde, som du ser i följande exempel.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF(0x9ACD32, 1.0f)),
&m_pYellowGreenBrush
);
Alfalägen
Oavsett alfaläget för återgivningsmålet som du använder en pensel med tolkas alltid D2D1_COLOR_F värden som raka alfa.
Använda enfärgade penslar
Om du vill skapa en pensel med en fast färg anropar du metoden ID2D1RenderTarget::CreateSolidColorBrush, som returnerar en HRESULT och ett ID2D1SolidColorBrush- objekt. Följande bild visar en fyrkant som är streckad med en svart färgborste och målad med en helfärgsborste som har färgvärdet 0x9ACD32.
Följande kod visar hur du skapar och använder en svart färgborste och en pensel med ett färgvärde på 0x9ACD32 för att fylla och rita den här fyrkanten.
ID2D1SolidColorBrush *m_pBlackBrush;
ID2D1SolidColorBrush *m_pYellowGreenBrush;
if (SUCCEEDED(hr))
{
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black, 1.0f),
&m_pBlackBrush
);
}
// Create a solid color brush with its rgb value 0x9ACD32.
if (SUCCEEDED(hr))
{
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF(0x9ACD32, 1.0f)),
&m_pYellowGreenBrush
);
}
m_pRenderTarget->FillRectangle(&rcBrushRect, m_pYellowGreenBrush);
m_pRenderTarget->DrawRectangle(&rcBrushRect, m_pBlackBrush, 1, NULL);
Till skillnad från andra penslar är det en relativt billig åtgärd att skapa en ID2D1SolidColorBrush. Du kan skapa ID2D1SolidColorBrush objekt varje gång du renderar med liten eller ingen prestandapåverkan. Den här metoden rekommenderas inte för tonings- eller bitmappsborstar.
Använda linjära övertoningspenslar
En ID2D1LinearGradientBrush målar ett område med en linjär toning som definieras längs en linje, kallad toningsaxeln. Du anger toningens färger och deras plats längs toningsaxeln med hjälp av ID2D1GradientStop objekt. Du kan också ändra toningsaxeln, vilket gör att du kan skapa vågrät och lodrät toning och vända toningsriktningen. Om du vill skapa en linjär gradientborste anropar du metoden ID2D1RenderTarget::CreateLinearGradientBrush.
Följande bild visar en fyrkant som är målad med en ID2D1LinearGradientBrush som har två fördefinierade färger, "Yellow" och "ForestGreen".
Utför följande steg för att skapa toningen som visas i föregående bild:
Deklarera två D2D1_GRADIENT_STOP objekt. Varje toningsstopp anger en färg och en position. En position på 0,0 anger början av toningen, medan en position på 1,0 anger toningens slut.
Följande kod skapar en matris med två D2D1_GRADIENT_STOP objekt. Det första stoppet anger färgen "Gul" vid en position 0, och det andra stoppet anger färgen "ForestGreen" vid position 1.
// Create an array of gradient stops to put in the gradient stop
// collection that will be used in the gradient brush.
ID2D1GradientStopCollection *pGradientStops = NULL;
D2D1_GRADIENT_STOP gradientStops[2];
gradientStops[0].color = D2D1::ColorF(D2D1::ColorF::Yellow, 1);
gradientStops[0].position = 0.0f;
gradientStops[1].color = D2D1::ColorF(D2D1::ColorF::ForestGreen, 1);
gradientStops[1].position = 1.0f;
- Skapa en ID2D1GradientStopCollection. I följande exempel anropas CreateGradientStopCollectiongenom att skicka in matrisen med D2D1_GRADIENT_STOP objekt, antalet toningsstopp (2), D2D1_GAMMA_2_2 för interpolering och D2D1_EXTEND_MODE_CLAMP för förlängningsläget.
// Create the ID2D1GradientStopCollection from a previously
// declared array of D2D1_GRADIENT_STOP structs.
hr = m_pRenderTarget->CreateGradientStopCollection(
gradientStops,
2,
D2D1_GAMMA_2_2,
D2D1_EXTEND_MODE_CLAMP,
&pGradientStops
);
- Skapa ID2D1LinearGradientBrush. I nästa exempel anropas metoden CreateLinearGradientBrush och skickar den de linjära toningsborstegenskaperna som innehåller startpunkten vid (0, 0) och slutpunkten vid (150, 150) och toningsstoppen som skapades i föregående steg.
// The line that determines the direction of the gradient starts at
// the upper-left corner of the square and ends at the lower-right corner.
if (SUCCEEDED(hr))
{
hr = m_pRenderTarget->CreateLinearGradientBrush(
D2D1::LinearGradientBrushProperties(
D2D1::Point2F(0, 0),
D2D1::Point2F(150, 150)),
pGradientStops,
&m_pLinearGradientBrush
);
}
- Använd ID2D1LinearGradientBrush. I nästa kodexempel används penseln för att fylla en rektangel.
m_pRenderTarget->FillRectangle(&rcBrushRect, m_pLinearGradientBrush);
Läs mer om gradvis färgstopp
Den D2D1_GRADIENT_STOP är den grundläggande byggstenen i en gradientpensel. Ett toningsstopp anger färgen och positionen längs toningsaxeln. Värdet på gradientpositionen varierar mellan 0,0 och 1,0. Ju närmare det är 0,0, desto närmare är färgen i början av toningen; ju närmare den är 1,0, desto närmare är färgen i slutet av toningen.
Följande bild visar färglägesstoppen. Cirkeln markerar läget för gradstoppar och en streckad linje visar gradientens axel.
Det första toningsstoppet anger färgen gul vid en position på 0,0. Det andra toningsstoppet anger röd färg på positionen 0,25. Från vänster till höger längs toningsaxeln ändras färgerna mellan dessa två stopp gradvis från gult till rött. Det tredje toningsstoppet anger blå färg vid 0,75. Färgerna mellan den andra och tredje gradientsstoppen ändras gradvis från rött till blått. Det fjärde toningsstoppet anger limegrön på positionen 1,0. Färgerna mellan den tredje och fjärde tonstoppet förändras gradvis från blå till limegrönt.
Toningsaxeln
Som tidigare nämnts placeras gradientstopp för en linjär gradientborste längs en linje, gradientaxeln. Du kan ange linjens orientering och storlek med hjälp av startPoint- och slutpunkt- fälten i D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES-strukturen när du skapar en linjärt gradientpensel. När du har skapat en pensel kan du justera toningsaxeln genom att anropa penselns SetStartPoint-- och SetEndPoint- metoder. Genom att ändra penselns startpunkt och slutpunkt kan du skapa vågräta och lodräta toningar, vända toningsriktningen med mera.
I följande bild anges till exempel startpunkten till (0,0) och slutpunkten till (150, 50); Detta skapar en diagonal toning som börjar i det övre vänstra hörnet och sträcker sig till det nedre högra hörnet av området som målas. När du anger startpunkten till (0, 25) och slutpunkten till (150, 25) skapas en vågrät toning. Om du anger startpunkten till (75, 0) och slutpunkten till (75, 50) skapas en lodrät övertoning. Om du anger startpunkten till (0, 50) och slutpunkten till (150, 0) skapas en diagonal toning som börjar i det nedre vänstra hörnet och sträcker sig till det övre högra hörnet av det område som målas.
Att använda radiella toningsborstar
Till skillnad från en ID2D1LinearGradientBrush, som blandar två eller flera färger längs en toningsaxel, målar en ID2D1RadialGradientBrush ett område med en radiell toning som blandar två eller flera färger över en ellips. Medan en ID2D1LinearGradientBrush definierar sin toningsaxel med en startpunkt och en slutpunkt, definierar en ID2D1RadialGradientBrush dess toningsellips genom att ange en mittpunkt, vågräta och lodräta radier och en förskjutning av toningsursprung.
Precis som en ID2D1LinearGradientBrushanvänder en ID2D1RadialGradientBrush en ID2D1GradientStopCollection för att ange färger och positioner i toningen.
Följande bild visar en cirkel målad med en ID2D1RadialGradientBrush. Cirkeln har två toningsstopp: det första anger en fördefinierad färg "Gul" vid positionen 0.0 och det andra anger en fördefinierad färg "ForestGreen" vid positionen 1.0. Toningen har en mittpunkt vid (75, 75), en ursprungsförskjutning på (0, 0) och en x- och y-radie på 75.
Följande kodexempel visar hur du målar den här cirkeln med en ID2D1RadialGradientBrush som har två färgstopp: "Gul" vid 0,0 och "ForestGreen" vid placeringen 1.0. Precis som när du skapar en ID2D1LinearGradientBrushanropar exemplet CreateGradientStopCollection för att skapa en ID2D1GradientStopCollection från en matris med toningsstopp.
// Create an array of gradient stops to put in the gradient stop
// collection that will be used in the gradient brush.
ID2D1GradientStopCollection *pGradientStops = NULL;
D2D1_GRADIENT_STOP gradientStops[2];
gradientStops[0].color = D2D1::ColorF(D2D1::ColorF::Yellow, 1);
gradientStops[0].position = 0.0f;
gradientStops[1].color = D2D1::ColorF(D2D1::ColorF::ForestGreen, 1);
gradientStops[1].position = 1.0f;
// Create the ID2D1GradientStopCollection from a previously
// declared array of D2D1_GRADIENT_STOP structs.
hr = m_pRenderTarget->CreateGradientStopCollection(
gradientStops,
2,
D2D1_GAMMA_2_2,
D2D1_EXTEND_MODE_CLAMP,
&pGradientStops
);
Om du vill skapa en ID2D1RadialGradientBrushanvänder du metoden ID2D1RenderTarget::CreateRadialGradientBrush. CreateRadialGradientBrush tar tre parametrar. Den första parametern, en D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES anger centrum, förskjutning av gradientens ursprung samt toningens vågräta och lodräta radier. Den andra parametern är en ID2D1GradientStopCollection som beskriver färgerna och deras positioner i toningen, och den tredje parametern är adressen till pekaren som får den nya ID2D1RadialGradientBrush referensen. Vissa överlagringar tar ytterligare en parameter, en D2D1_BRUSH_PROPERTIES struktur som anger ett opacitetsvärde och en transformering som ska tillämpas på den nya penseln.
I nästa exempel anropas CreateRadialGradientBrushoch matrisen med toningsstopp skickas in, tillsammans med egenskaperna för den radiella toningsborsten som har värdet center inställt på (75, 75), gradientOriginOffset inställt på (0, 0), och radiusX och radiusY båda inställda på 75.
// The center of the gradient is in the center of the box.
// The gradient origin offset was set to zero(0, 0) or center in this case.
if (SUCCEEDED(hr))
{
hr = m_pRenderTarget->CreateRadialGradientBrush(
D2D1::RadialGradientBrushProperties(
D2D1::Point2F(75, 75),
D2D1::Point2F(0, 0),
75,
75),
pGradientStops,
&m_pRadialGradientBrush
);
}
I det sista exemplet används penseln för att fylla en ellips.
m_pRenderTarget->FillEllipse(ellipse, m_pRadialGradientBrush);
m_pRenderTarget->DrawEllipse(ellipse, m_pBlackBrush, 1, NULL);
Konfigurera en radiell toning
Olika värden för center, gradientOriginOffset, radiusX och/eller radiusY genererar olika toningar. Följande illustration visar flera radiella toningar med olika förskjutningar av toningens ursprung, vilket skapar intrycket av att ljuset belyser cirklarna från olika vinklar.
Använda bitmappspenslar
En ID2D1BitmapBrush målar ett område med en bitmapp (representeras av ett ID2D1Bitmap--objekt).
Följande bild visar en fyrkant målad med en bitmapp av en växt.
Exemplen som följer visar hur du målar den här fyrkanten med en ID2D1BitmapBrush.
I det första exemplet initieras en ID2D1Bitmap för användning med penseln. ID2D1Bitmap tillhandahålls av en hjälpmetod, LoadResourceBitmap, som definieras någon annanstans i exemplet.
// Create the bitmap to be used by the bitmap brush.
if (SUCCEEDED(hr))
{
hr = LoadResourceBitmap(
m_pRenderTarget,
m_pWICFactory,
L"FERN",
L"Image",
&m_pBitmap
);
}
För att skapa bitmapborsten anropar du metoden ID2D1RenderTarget::CreateBitmapBrush och specificerar ID2D1Bitmap som ska användas för att måla. Metoden returnerar ett HRESULT- och ett ID2D1BitmapBrush--objekt. Med vissa CreateBitmapBrush- överlagringar kan du ange ytterligare alternativ genom att acceptera en D2D1_BRUSH_PROPERTIES och en D2D1_BITMAP_BRUSH_PROPERTIES struktur.
if (SUCCEEDED(hr))
{
hr = m_pRenderTarget->CreateBitmapBrush(
m_pBitmap,
&m_pBitmapBrush
);
}
I nästa exempel används penseln för att fylla en rektangel.
m_pRenderTarget->FillRectangle(&rcBrushRect, m_pBitmapBrush);
Konfigurera utökningslägen
Ibland fyller inte toningen av en toningsborste eller bitmappen för en bitmappsborste helt det område som ska målas.
När detta händer för en ID2D1BitmapBrushanvänder Direct2D penselns vågräta (SetExtendModeX) och lodräta (SetExtendModeY) utökningslägesinställningar för att avgöra hur det återstående området ska fyllas.
När detta inträffar för en toningsborste avgör Direct2D hur du fyller det återstående området med hjälp av värdet för den D2D1_EXTEND_MODE parameter som du angav när du anropade CreateGradientStopCollection för att skapa toningspenselns ID2D1GradientStopCollection.
Följande bild visar resultaten från varje möjlig kombination av utökningslägena för en ID2D1BitmapBrush: D2D1_EXTEND_MODE_CLAMP (CLAMP), D2D1_EXTEND_MODE_WRAP (WRAP) och D2D1_EXTEND_MIRROR (MIRROR).
I följande exempel visas hur du ställer in bitmappsborstens x- och y-förlängningslägen på D2D1_EXTEND_MIRROR. Den målar sedan rektangeln med ID2D1BitmapBrush.
m_pBitmapBrush->SetExtendModeX(D2D1_EXTEND_MODE_MIRROR);
m_pBitmapBrush->SetExtendModeY(D2D1_EXTEND_MODE_MIRROR);
m_pRenderTarget->FillRectangle(exampleRectangle, m_pBitmapBrush);
Den genererar utdata som visas i följande bild.
Transformera penslar
När du målar med en pensel, målar du i återgivningsmålets koordinatutrymme. Penslar placerar sig inte automatiskt för att anpassa sig till objektet som målas; som standard börjar de måla på ursprunget (0, 0) för återgivningsmålet.
Du kan "flytta" det förlopp som definieras av en ID2D1LinearGradientBrush till ett målområde genom att ange dess start- och slutpunkt. På samma sätt kan du justera gradienten som definieras av en ID2D1RadialGradientBrush genom att ändra gradientens mittpunkt och radier.
Om du vill justera innehållet i en ID2D1BitmapBrush- till det område som målas kan du använda metoden SetTransform för att översätta bitmappen till önskad plats. Den här transformeringen påverkar bara penseln. Det påverkar inte något annat innehåll som ritas av återgivningsmålet.
Följande bilder visar effekten av att använda en ID2D1BitmapBrush för att fylla en rektangel som finns på (100, 100). Bilden till vänster visar resultatet av att fylla rektangeln utan att förändra penseln: bitmappen ritas vid renderingsmålets ursprung. Därför visas endast en del av bitmappen i rektangeln. Bilden till höger visar resultatet av transformering av ID2D1BitmapBrush så att innehållet flyttas 50 bildpunkter åt höger och 50 bildpunkter nedåt. Bitmappen fyller nu rektangeln.
Följande kod visar hur du gör detta. Använd först en översättning till ID2D1BitmapBrushoch flytta borsten 50 bildpunkter längs x-axeln och 50 bildpunkter nedåt längs y-axeln. Använd sedan ID2D1BitmapBrush för att fylla rektangeln som har det övre vänstra hörnet på (100, 100) och det nedre högra hörnet vid (200, 200).
// Create the bitmap to be used by the bitmap brush.
if (SUCCEEDED(hr))
{
hr = LoadResourceBitmap(
m_pRenderTarget,
m_pWICFactory,
L"FERN",
L"Image",
&m_pBitmap
);
}
if (SUCCEEDED(hr))
{
hr = m_pRenderTarget->CreateBitmapBrush(
m_pBitmap,
&m_pBitmapBrush
);
}
D2D1_RECT_F rcTransformedBrushRect = D2D1::RectF(100, 100, 200, 200);
// Demonstrate the effect of transforming a bitmap brush.
m_pBitmapBrush->SetTransform(
D2D1::Matrix3x2F::Translation(D2D1::SizeF(50,50))
);
// To see the content of the rcTransformedBrushRect, comment
// out this statement.
m_pRenderTarget->FillRectangle(
&rcTransformedBrushRect,
m_pBitmapBrush
);
m_pRenderTarget->DrawRectangle(rcTransformedBrushRect, m_pBlackBrush, 1, NULL);