Översikt över sökvägsgeometrier
Det här avsnittet beskriver hur du använder Direct2D-sökvägsgeometrier för att skapa komplexa ritningar. Den innehåller följande avsnitt.
- Förutsättningar
- Sökvägsgeometrier i Direct2D
- Använda en ID2D1GeometrySink för att fylla i en sökvägsgeometri
- Exempel: Skapa en komplex ritning
- Relaterade ämnen
Förutsättningar
Den här översikten förutsätter att du är bekant med att skapa grundläggande Direct2D-program enligt beskrivningen i Skapa ett enkelt Direct2D-program. Det förutsätter också att du är bekant med de grundläggande funktionerna i Direct2D-geometrier, enligt beskrivningen i översikten över geometrier.
Sökvägsgeometrier i Direct2D
Sökvägsgeometrier representeras av gränssnittet ID2D1PathGeometry. Om du vill instansiera en sökvägsgeometri anropar du metoden ID2D1Factory::CreatePathGeometry. Dessa objekt kan användas för att beskriva komplexa geometriska figurer som består av segment som bågar, kurvor och linjer. Om du vill fylla i en sökvägsgeometri med siffror och segment anropar du metoden Open för att hämta en ID2D1GeometrySink- och använder geometrimottagarens metoder för att lägga till siffror och segment i sökvägens geometri.
Använda en ID2D1GeometrySink för att fylla i en sökvägsgeometri
ID2D1GeometrySink beskriver en geometrisk väg som kan innehålla linjer, bågar, kubiska Bezier-kurvor och kvadratiska Bezier-kurvor.
En geometrimottagare består av en eller flera figurer. Varje bild består av ett eller flera linje-, kurv- eller bågsegment. Om du vill skapa en bild anropar du metoden BeginFigure, skickar in bildens startpunkt och använder sedan dess Lägg till metoder (till exempel AddLine och AddBezier) för att lägga till segment. När du är klar med att lägga till segment anropar du metoden EndFigure. Du kan upprepa den här sekvensen för att skapa ytterligare siffror. När du är klar med att skapa siffror anropar du metoden Stäng.
Exempel: Skapa en komplex ritning
Följande bild visar en komplex ritning med linjer, bågar och Bezier-kurvor. Kodexemplet som följer visar hur du skapar ritningen med hjälp av fyra sökvägsgeometriobjekt, en för det vänstra berget, en för det högra berget, en för floden och en för solen med facklor.
Skapa en sökvägsgeometri för det vänstra berget
Exemplet skapar först en banform för det vänstra berget, som visas i följande illustration.
För att skapa det vänstra berget anropar exemplet metoden ID2D1Factory::CreatePathGeometry för att skapa en ID2D1PathGeometry-.
hr = m_pD2DFactory->CreatePathGeometry(&m_pLeftMountainGeometry);
Exemplet använder sedan metoden Open för att hämta en geometrimottagare från en ID2D1PathGeometry- och lagrar den i variabeln pSink.
ID2D1GeometrySink *pSink = NULL;
hr = m_pLeftMountainGeometry->Open(&pSink);
Exemplet anropar sedan BeginFigureoch skickar in D2D1_FIGURE_BEGIN_FILLED som anger att den här siffran är fylld, anropar sedan AddLinesoch skickar en matris med D2D1_POINT_2F punkter, (267, 177), (236, 192), (212, 160), (156, 255) och (346, 255).
Följande kod visar hur du gör detta.
pSink->SetFillMode(D2D1_FILL_MODE_WINDING);
pSink->BeginFigure(
D2D1::Point2F(346,255),
D2D1_FIGURE_BEGIN_FILLED
);
D2D1_POINT_2F points[5] = {
D2D1::Point2F(267, 177),
D2D1::Point2F(236, 192),
D2D1::Point2F(212, 160),
D2D1::Point2F(156, 255),
D2D1::Point2F(346, 255),
};
pSink->AddLines(points, ARRAYSIZE(points));
pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
Skapa en sökvägsgeometri för det högra berget
Exemplet skapar sedan en annan sökvägsgeometri för det högra berget med punkter (481, 146), (449, 181), (433, 159), (401, 214), (381, 199), (323, 263) och (575, 263). Följande bild visar hur det högra berget visas.
Följande kod visar hur du gör detta.
hr = m_pD2DFactory->CreatePathGeometry(&m_pRightMountainGeometry);
if(SUCCEEDED(hr))
{
ID2D1GeometrySink *pSink = NULL;
hr = m_pRightMountainGeometry->Open(&pSink);
if (SUCCEEDED(hr))
{
pSink->SetFillMode(D2D1_FILL_MODE_WINDING);
pSink->BeginFigure(
D2D1::Point2F(575,263),
D2D1_FIGURE_BEGIN_FILLED
);
D2D1_POINT_2F points[] = {
D2D1::Point2F(481, 146),
D2D1::Point2F(449, 181),
D2D1::Point2F(433, 159),
D2D1::Point2F(401, 214),
D2D1::Point2F(381, 199),
D2D1::Point2F(323, 263),
D2D1::Point2F(575, 263)
};
pSink->AddLines(points, ARRAYSIZE(points));
pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
}
hr = pSink->Close();
SafeRelease(&pSink);
}
Skapa en sökvägsgeometri för solen
Exemplet fyller sedan i en annan sökvägsgeometri för solen enligt följande bild.
** För att göra detta skapar sökvägsgeometrin en fälla och lägger till en figur för bågen samt en figur för varje utbuktning till fällan. Genom att upprepa sekvensen med BeginFigure, dess metoder för att lägga till (till exempel AddBezier), och EndFigure, läggs flera figurer till i mottagaren.
Följande kod visar hur du gör detta.
hr = m_pD2DFactory->CreatePathGeometry(&m_pSunGeometry);
if(SUCCEEDED(hr))
{
ID2D1GeometrySink *pSink = NULL;
hr = m_pSunGeometry->Open(&pSink);
if (SUCCEEDED(hr))
{
pSink->SetFillMode(D2D1_FILL_MODE_WINDING);
pSink->BeginFigure(
D2D1::Point2F(270, 255),
D2D1_FIGURE_BEGIN_FILLED
);
pSink->AddArc(
D2D1::ArcSegment(
D2D1::Point2F(440, 255), // end point
D2D1::SizeF(85, 85),
0.0f, // rotation angle
D2D1_SWEEP_DIRECTION_CLOCKWISE,
D2D1_ARC_SIZE_SMALL
));
pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
pSink->BeginFigure(
D2D1::Point2F(299, 182),
D2D1_FIGURE_BEGIN_HOLLOW
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(299, 182),
D2D1::Point2F(294, 176),
D2D1::Point2F(285, 178)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(276, 179),
D2D1::Point2F(272, 173),
D2D1::Point2F(272, 173)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN);
pSink->BeginFigure(
D2D1::Point2F(354, 156),
D2D1_FIGURE_BEGIN_HOLLOW
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(354, 156),
D2D1::Point2F(358, 149),
D2D1::Point2F(354, 142)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(349, 134),
D2D1::Point2F(354, 127),
D2D1::Point2F(354, 127)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN);
pSink->BeginFigure(
D2D1::Point2F(322,164),
D2D1_FIGURE_BEGIN_HOLLOW
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(322, 164),
D2D1::Point2F(322, 156),
D2D1::Point2F(314, 152)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(306, 149),
D2D1::Point2F(305, 141),
D2D1::Point2F(305, 141)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN);
pSink->BeginFigure(
D2D1::Point2F(385, 164),
D2D1_FIGURE_BEGIN_HOLLOW
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(385,164),
D2D1::Point2F(392,161),
D2D1::Point2F(394,152)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(395,144),
D2D1::Point2F(402,141),
D2D1::Point2F(402,142)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN);
pSink->BeginFigure(
D2D1::Point2F(408,182),
D2D1_FIGURE_BEGIN_HOLLOW
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(408,182),
D2D1::Point2F(416,184),
D2D1::Point2F(422,178)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(428,171),
D2D1::Point2F(435,173),
D2D1::Point2F(435,173)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN);
}
hr = pSink->Close();
SafeRelease(&pSink);
}
Skapa en sökvägsgeometri för floden
Exemplet skapar sedan en annan geometriväg för floden som innehåller Bezier-kurvor. Följande bild visar hur floden visas.
Följande kod visar hur du gör detta.
hr = m_pD2DFactory->CreatePathGeometry(&m_pRiverGeometry);
if(SUCCEEDED(hr))
{
ID2D1GeometrySink *pSink = NULL;
hr = m_pRiverGeometry->Open(&pSink);
if (SUCCEEDED(hr))
{
pSink->SetFillMode(D2D1_FILL_MODE_WINDING);
pSink->BeginFigure(
D2D1::Point2F(183, 392),
D2D1_FIGURE_BEGIN_FILLED
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(238, 284),
D2D1::Point2F(472, 345),
D2D1::Point2F(356, 303)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(237, 261),
D2D1::Point2F(333, 256),
D2D1::Point2F(333, 256)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(335, 257),
D2D1::Point2F(241, 261),
D2D1::Point2F(411, 306)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(574, 350),
D2D1::Point2F(288, 324),
D2D1::Point2F(296, 392)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN);
}
Rendera sökvägsgeometrierna på skärmen
Följande kod visar hur du återger de ifyllda sökvägsgeometrierna på skärmen. Det ritar och målar först solgeometrin, därefter den vänstra berggeometrin, sedan flodgeometrin och till sist den högra berggeometrin.
m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
m_pRenderTarget->FillRectangle(
D2D1::RectF(0, 0, rtSize.width, rtSize.height),
m_pGridPatternBitmapBrush
);
m_pRenderTarget->FillGeometry(m_pSunGeometry, m_pRadialGradientBrush);
m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Black, 1.f));
m_pRenderTarget->DrawGeometry(m_pSunGeometry, m_pSceneBrush, 1.f);
m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::OliveDrab, 1.f));
m_pRenderTarget->FillGeometry(m_pLeftMountainGeometry, m_pSceneBrush);
m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Black, 1.f));
m_pRenderTarget->DrawGeometry(m_pLeftMountainGeometry, m_pSceneBrush, 1.f);
m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::LightSkyBlue, 1.f));
m_pRenderTarget->FillGeometry(m_pRiverGeometry, m_pSceneBrush);
m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Black, 1.f));
m_pRenderTarget->DrawGeometry(m_pRiverGeometry, m_pSceneBrush, 1.f);
m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::YellowGreen, 1.f));
m_pRenderTarget->FillGeometry(m_pRightMountainGeometry, m_pSceneBrush);
m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Black, 1.f));
m_pRenderTarget->DrawGeometry(m_pRightMountainGeometry, m_pSceneBrush, 1.f);
hr = m_pRenderTarget->EndDraw();
I det fullständiga exemplet visas följande bild.
Relaterade ämnen