Přehled štětců
Tento přehled popisuje, jak vytvořit a používat ID2D1SolidColorBrush, ID2D1LinearGradientBrush, ID2D1RadialGradientBrusha ID2D1BitmapBrush objekty k malování oblastí pomocí plných barev, přechodů a rastrových obrázků. Obsahuje následující části.
Požadavky
Tento přehled předpokládá, že znáte strukturu základní aplikace Direct2D, jak je popsáno v Vytvoření jednoduché aplikace Direct2D.
Typy štětců
Štětec "maluje" oblast svým výstupem. Různé štětce mají různé typy výstupu. Direct2D poskytuje čtyři typy štětců: ID2D1SolidColorBrush maluje oblast plnou barvou, ID2D1LinearGradientBrush lineárním přechodem, ID2D1RadialGradientBrush paprskovým přechodem a ID2D1BitmapBrush bitmapou.
Poznámka
Počínaje Windows 8 můžete také použít ID2D1ImageBrush, který je podobný rastrovým štětci, ale můžete také použít primitivy.
Všechny štětce dědí z ID2D1Brush a sdílejí sadu společných funkcí (nastavení a získání neprůhlednosti a transformace štětců); jsou vytvořené ID2D1RenderTarget a jsou prostředky závislé na zařízení: vaše aplikace by měla po inicializaci cíle vykreslení vytvořit cíl vykreslení, pomocí kterého se štětce použijí, a znovu vytvořit štětce pokaždé, když se cíl vykreslení znovu vytvoří. (Další informace o prostředcích najdete v tématu Přehled prostředků.)
Následující obrázek ukazuje příklady jednotlivých typů štětců.
Základy barev
Než začnete malovat pomocí ID2D1SolidColorBrush nebo přechodového štětce, musíte zvolit barvy. V Direct2D jsou barvy reprezentovány strukturou D2D1_COLOR_F (což je ve skutečnosti jen nový název struktury, která je používána Direct3D, D3DCOLORVALUE).
Před Windows 8 používá D2D1_COLOR_F kódování sRGB. Kódování sRGB rozděluje barvy do čtyř součástí: červená, zelená, modrá a alfa. Každá součást je reprezentována hodnotou s plovoucí desetinnou čárkou s normálním rozsahem (0,0 až 1,0). Hodnota 0,0 označuje úplnou nepřítomnost této barvy, zatímco hodnota 1,0 označuje, že barva je plně přítomna. Pro alfa součást představuje 0,0 plně průhlednou barvu a 1,0 představuje plně neprůhlednou barvu.
Počínaje Windows 8 D2D1_COLOR_F také přijímá kódování SCRGB. SCRGB je nadmnožina, která umožňuje hodnoty barev nad 1,0 a nižší než 0,0.
Pokud chcete definovat barvu, můžete použít strukturu D2D1_COLOR_F a inicializovat její pole sami, nebo můžete použít D2D1::ColorF třídu, která vám pomůže vytvořit barvu. Třída ColorF poskytuje několik konstruktorů pro definování barev. Pokud není v konstruktorech zadána alfa hodnota, je výchozí hodnota 1,0.
Pomocí konstruktoru ColorF(Enum, FLOAT) určete předdefinovanou barvu a hodnotu alfa kanálu. Hodnota alfa kanálu se pohybuje od 0,0 do 1,0, kde 0,0 představuje plně průhlednou barvu a 1,0 představuje plně neprůhlednou barvu. Následující obrázek ukazuje několik předdefinovaných barev a jejich šestnáctkové ekvivalenty. Úplný seznam předdefinovaných barev najdete v části Konstanty barev ColorF třídy.
Následující příklad vytvoří předdefinovanou barvu a použije ji k určení barvy ID2D1SolidColorBrush.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black, 1.0f),
&m_pBlackBrush
);
Pomocí ColorF(FLOAT, FLOAT, FLOAT, FLOAT) konstruktoru zadejte barvu v pořadí červené, zelené, modré a alfa, kde každý prvek má hodnotu mezi 0,0 a 1,0.
Následující příklad určuje červené, zelené, modré a alfa hodnoty pro barvu.
ID2D1SolidColorBrush *pGridBrush = NULL;
hr = pCompatibleRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF(0.93f, 0.94f, 0.96f, 1.0f)),
&pGridBrush
);
- Pomocí konstruktoru ColorF(UINT32, FLOAT) zadejte šestnáctkovou hodnotu barvy a alfa hodnoty, jak je znázorněno v následujícím příkladu.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF(0x9ACD32, 1.0f)),
&m_pYellowGreenBrush
);
Režimy alfa
Bez ohledu na alfa režim vykreslení cíle, se kterým použijete štětec, D2D1_COLOR_F hodnoty jsou vždy interpretovány jako rovné alfa.
Použití jednobarevných štětců
Chcete-li vytvořit plnobarevný štětec, zavolejte metodu ID2D1RenderTarget::CreateSolidColorBrush, která vrátí HRESULT a objekt ID2D1SolidColorBrush. Následující obrázek znázorňuje čtverec, který je ohraničen černým štětcem a vyplněn jednobarevným štětcem s hodnotou barvy 0x9ACD32.
Následující kód ukazuje, jak vytvořit a použít černobarevný štětec a štětec s barevnou hodnotou 0x9ACD32 vyplnit a nakreslit tento čtverec.
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);
Na rozdíl od jiných štětců je vytvoření ID2D1SolidColorBrush relativně levnou operací. Můžete vytvořit objekty ID2D1SolidColorBrush pokaždé, když budete vykreslovat, aniž by to mělo výrazný dopad na výkon. Tento přístup se nedoporučuje pro přechodové nebo rastrové štětce.
Použití lineárních přechodových štětců
ID2D1LinearGradientBrush maluje oblast lineárním přechodem definovaným podél čáry, osa přechodu. Pomocí objektů ID2D1GradientStop určujete barvy přechodu a jejich umístění na ose přechodu. Můžete také upravit osu přechodu, která umožňuje vytvořit vodorovný a svislý přechod a obrátit směr přechodu. Chcete-li vytvořit lineární přechodový štětec, zavolejte metodu ID2D1RenderTarget::CreateLinearGradientBrush.
Následující obrázek znázorňuje čtverec, který je vykreslen pomocí ID2D1LinearGradientBrush a má dvě předdefinované barvy, "Žlutá" a "ForestGreen".
Pokud chcete vytvořit přechod zobrazený na předchozím obrázku, proveďte následující kroky:
Deklarujte dva D2D1_GRADIENT_STOP objekty. Každý bod přechodu určuje barvu a pozici. Pozice 0,0 označuje začátek přechodu, zatímco pozice 1,0 označuje konec přechodu.
Následující kód vytvoří pole dvou D2D1_GRADIENT_STOP objektů. První zarážka určuje barvu Žlutá na pozici 0 a druhá zarážka určuje barvu ForestGreen na pozici 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;
- Vytvořte ID2D1GradientStopCollection. Následující příklad volá CreateGradientStopCollection, předáním pole D2D1_GRADIENT_STOP objektů, počtu přechodových zarážek (2), D2D1_GAMMA_2_2 pro účely interpolace a D2D1_EXTEND_MODE_CLAMP pro nastavení režimu rozšíření.
// 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
);
- Vytvořte ID2D1LinearGradientBrush. Další příklad volá metodu CreateLinearGradientBrush a předá jí vlastnosti lineárního přechodového štětce, které obsahují počáteční bod v (0, 0), koncový bod v (150, 150) a přechodové zarážky vytvořené v předchozím kroku.
// 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
);
}
- Použijte ID2D1LinearGradientBrush. Následující příklad kódu používá štětec k vyplnění obdélníku.
m_pRenderTarget->FillRectangle(&rcBrushRect, m_pLinearGradientBrush);
Více informací o přechodových zarážkách
D2D1_GRADIENT_STOP je základní stavební kámen pro gradientový štětec. Přechodová zarážka určuje barvu a pozici podél osy přechodu. Hodnota umístění přechodu se pohybuje mezi 0,0 a 1,0. Čím blíže je 0,0, tím blíže je barva na začátek přechodu; čím blíž je 1,0, tím blíž je barva ke konci přechodu.
Následující obrázek zobrazuje body přechodu. Kruh označuje pozici přechodových zarážek a přerušovaná čára zobrazuje osu přechodu.
První bod přechodu určuje žlutou barvu na pozici 0.0. Druhá přechodová zarážka určuje červenou barvu na pozici 0,25. Zleva doprava podél gradientové osy se barvy mezi těmito dvěma body postupně mění z žluté na červenou. Třetí barevná přechodová zarážka určuje modrou barvu na pozici 0,75. Barvy mezi druhým a třetím barevným přechodem se postupně mění z červené na modrou. Čtvrtá přechodová zarážka určuje limetovou zelenou na pozici 1,0. Barvy mezi třetím a čtvrtým barevným přechodovým bodem se postupně mění z modré na limetově zelenou.
Osa přechodu
Jak už bylo zmíněno dříve, přechodové zarážky lineárního přechodového štětce jsou umístěny podél čáry, osa přechodu. Orientaci a velikost čáry můžete určit pomocí polí startPoint a endPoint ve struktuře D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES při vytváření štětce s lineárním přechodem. Po vytvoření štětce můžete upravit přechodovou osu zavoláním metody SetStartPoint a metody SetEndPoint. Při manipulaci s počátečním a koncovým bodem štětce můžete vytvořit vodorovné a svislé přechody, obrátit směr přechodu a provádět další akce.
Například na následujícím obrázku je počáteční bod nastavený na (0,0) a koncový bod na (150, 50); tím se vytvoří diagonální přechod, který začíná v levém horním rohu a rozšiřuje se do pravého dolního rohu oblasti, která se maluje. Když nastavíte počáteční bod na (0, 25) a koncový bod na (150, 25), vytvoří se vodorovný přechod. Podobně nastavení počátečního bodu na (75, 0) a koncového bodu na (75, 50) vytvoří svislý přechod. Nastavení počátečního bodu na (0, 50) a koncového bodu na (150, 0) vytvoří diagonální přechod, který začíná v levém dolním rohu a rozšiřuje se do pravého horního rohu oblasti, která se maluje.
Použití radiálních přechodových kartáčů
Na rozdíl od ID2D1LinearGradientBrush, která kombinuje dvě nebo více barev podél přechodové osy, ID2D1RadialGradientBrush maluje oblast paprskovým přechodem, který kombinuje dvě nebo více barev napříč elipsou. Zatímco ID2D1LinearGradientBrush definuje svou přechodovou osu s počátečním bodem a koncovým bodem, ID2D1RadialGradientBrush definuje svou přechodovou elipsu zadáním středu, vodorovného a svislého poloměru a posunu původu přechodu.
Stejně jako ID2D1LinearGradientBrush, ID2D1RadialGradientBrush používá ID2D1GradientStopCollection k určení barev a pozic v přechodu.
Následující obrázek znázorňuje kruh, který je namalovaný štětcem ID2D1RadialGradientBrush . Kruh má dvě přechodové zarážky: první určuje předdefinovanou barvu Žlutou na pozici 0,0 a druhá určuje předdefinovanou barvu ForestGreen na pozici 1,0. Přechod má střed (75, 75), posun původu přechodu (0, 0) a poloměr x a y 75.
Následující příklady kódu ukazují, jak tento kruh vybarvit pomocí ID2D1RadialGradientBrush, který má dva barevné přechody: "Žlutá" na pozici 0.0 a "ForestGreen" na pozici 1.0. Podobně jako při vytvoření ID2D1LinearGradientBrush, příklad používá CreateGradientStopCollection ke vytvoření ID2D1GradientStopCollection z pole přechodových bodů.
// 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
);
Chcete-li vytvořit ID2D1RadialGradientBrush, použijte metodu ID2D1RenderTarget::CreateRadialGradientBrush. CreateRadialGradientBrush přebírá tři parametry. První parametr, D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES určuje střed, posun počátku přechodu a vodorovnou a svislou radii přechodu. Druhý parametr je ID2D1GradientStopCollection, který popisuje barvy a jejich pozice v přechodu, a třetí parametr je adresa ukazatele, který obdrží nový ID2D1RadialGradientBrush reference. Některé přetížení umožňují vstup dalšího parametru, strukturu D2D1_BRUSH_PROPERTIES, která určuje hodnotu průsvitnosti a transformaci, která se má použít na nový kartáč.
Další příklad volá CreateRadialGradientBrush, předávání pole přechodových zarážek, a vlastnosti štětce paprskového přechodu, které mají středovou hodnotu nastavenou na (75, 75), gradientOriginOffset nastavena na (0, 0) a radiusX a poloměrY oba nastaveny na 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
);
}
Poslední příklad používá štětec k vyplnění elipsy.
m_pRenderTarget->FillEllipse(ellipse, m_pRadialGradientBrush);
m_pRenderTarget->DrawEllipse(ellipse, m_pBlackBrush, 1, NULL);
Konfigurace radiálního přechodu
Různé hodnoty pro střed, gradientOriginOffset, radiusX a/nebo radiusY vytvářejí různé přechody. Následující obrázek znázorňuje několik paprskových přechodů, které mají různé posuny původu přechodu, což vytváří vzhled světla osvětlujícího kružnice z různých úhlů.
Použití rastrových štětců
ID2D1BitmapBrush maluje oblast rastrovým obrázkem (reprezentovaný objektem ID2D1Bitmap).
Následující obrázek znázorňuje čtverec malovaný rastrovým obrázkem rostliny.
Následující příklady ukazují, jak nabarvit tento čtverec pomocí štětce ID2D1BitmapBrush.
První příklad inicializuje ID2D1Bitmap pro použití se štětcem. ID2D1Bitmap poskytuje pomocná metoda LoadResourceBitmap, definovaná jinde v ukázce.
// 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
);
}
Chcete-li vytvořit rastrový štětec, zavolejte metodu ID2D1RenderTarget::CreateBitmapBrush a zadejte ID2D1Bitmap pro malování. Metoda vrátí HRESULT a objekt ID2D1BitmapBrush. Některé CreateBitmapBrush přetížení vám umožňují zadat další možnosti tím, že přijímají strukturu D2D1_BRUSH_PROPERTIES a D2D1_BITMAP_BRUSH_PROPERTIES.
if (SUCCEEDED(hr))
{
hr = m_pRenderTarget->CreateBitmapBrush(
m_pBitmap,
&m_pBitmapBrush
);
}
Další příklad používá štětec k vyplnění obdélníku.
m_pRenderTarget->FillRectangle(&rcBrushRect, m_pBitmapBrush);
Konfigurace rozšiřujících režimů
Někdy přechod přechodového štětce nebo rastrového obrázku rastrového štětce úplně nevyplní oblast, která se maluje.
Pokud k tomu dojde u ID2D1BitmapBrush, Direct2D použije nastavení režimu rozšíření štětce pro vodorovný (SetExtendModeX) a svislý (SetExtendModeY) směr k určení, jak vyplnit zbývající oblast.
Pokud k tomu dojde u přechodového štětce, Direct2D určuje, jak vyplnit zbývající oblast, pomocí hodnoty parametru D2D1_EXTEND_MODE, který jste zadali při volání CreateGradientStopCollection k vytvoření kolekce přechodového štětce ID2D1GradientStopCollection.
Následující obrázek ukazuje výsledky každé možné kombinace režimů rozšíření pro ID2D1BitmapBrush: D2D1_EXTEND_MODE_CLAMP (CLAMP), D2D1_EXTEND_MODE_WRAP (WRAP) a D2D1_EXTEND_MIRROR (MIRROR).
Následující příklad ukazuje, jak nastavit režimy x- a y-protažení pro bitový štětec na D2D1_EXTEND_MIRROR. Pak nakreslí obdélník s ID2D1BitmapBrush.
m_pBitmapBrush->SetExtendModeX(D2D1_EXTEND_MODE_MIRROR);
m_pBitmapBrush->SetExtendModeY(D2D1_EXTEND_MODE_MIRROR);
m_pRenderTarget->FillRectangle(exampleRectangle, m_pBitmapBrush);
Vytvoří výstup, jak je znázorněno na následujícím obrázku.
Transformace štětců
Když malujete štětcem, maluje se v souřadnicovém prostoru vykreslovacího cíle. Štětce se automaticky nezarovnávají s objektem, který se maluje; ve výchozím nastavení začínají pracovat na počátku (0, 0) vykreslovací plochy.
Přechod definovaný pomocí ID2D1LinearGradientBrush lze "přesunout" do cílové oblasti nastavením jeho počátečního a koncového bodu. Stejně tak můžete přechod definovaný ID2D1RadialGradientBrush přesunout změnou jeho středu a radii.
Chcete-li zarovnat obsah ID2D1BitmapBrush k vykreslené oblasti, můžete použít SetTransform metodu k překladu rastrového obrázku do požadovaného umístění. Tato transformace ovlivňuje pouze štětec; nemá vliv na žádný jiný obsah nakreslený cílem vykreslení.
Následující ilustrace znázorňují efekt použití ID2D1BitmapBrush k vyplnění obdélníku umístěného v hodnotě (100, 100). Ilustrace vlevo znázorňuje výsledek vyplnění obdélníku bez transformace štětce: rastrový obrázek se nakreslí na počátku cíle vykreslení. V důsledku toho se v obdélníku zobrazí pouze část rastrového obrázku. Obrázek vpravo ukazuje výsledek transformace ID2D1BitmapBrush tak, aby se jeho obsah přesunul o 50 pixelů doprava a o 50 pixelů dolů. Rastrový obrázek teď vyplní obdélník.
Následující kód ukazuje, jak toho dosáhnout. Nejprve použijte překlad na ID2D1BitmapBrush, přesunutí štětce o 50 pixelů doprava podél osy x a 50 pixelů dolů podél osy y. Potom použijte ID2D1BitmapBrush k vyplnění obdélníku, který má levý horní roh (100, 100) a pravý dolní roh (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);