Cenni preliminari sulle geometrie dei percorsi
In questo argomento viene descritto come utilizzare geometrie di percorso Direct2D per creare disegni complessi. Contiene le sezioni seguenti.
- Prerequisiti
- geometrie di percorso in Direct2D
- Uso di un ID2D1GeometrySink per riempire una geometria di percorso
- Esempio: Creare un disegno complesso
- argomenti correlati
Prerequisiti
Questa panoramica presuppone che si abbia familiarità con la creazione di applicazioni Direct2D di base, come descritto in Creare una semplice applicazione Direct2D. Si presuppone inoltre di avere familiarità con le funzionalità di base delle geometrie Direct2D, come descritto nella panoramica delle geometrie .
Geometrie di percorso in Direct2D
Le geometrie di percorso sono rappresentate dall'interfacciaID2D1PathGeometry. Per creare un'istanza di una geometria di percorso, chiamare il metodo ID2D1Factory::CreatePathGeometry. Questi oggetti possono essere utilizzati per descrivere figure geometriche complesse composte da segmenti quali archi, curve e linee. Per popolare una geometria di percorso con figure e segmenti, chiamare il metodo Open per recuperare un ID2D1GeometrySink e usare i metodi del geometry sink per aggiungere figure e segmenti alla geometria del percorso.
Uso di un ID2D1GeometrySink per riempire una geometria di percorso
ID2D1GeometrySink descrive un percorso geometrico che può contenere linee, archi, curve di Bézier cubiche e curve quadratiche di Bézier.
Un ricettore di geometria è costituito da una o più figure. Ogni figura è costituita da uno o più segmenti di linea, curva o arco. Per creare una figura, chiamare il metodoBeginFigure, passando il punto iniziale della figura e quindi usare i relativi metodi Add (ad esempio AddLine e AddBezier) per aggiungere segmenti. Al termine dell'aggiunta di segmenti, chiamare il metodo EndFigure. È possibile ripetere questa sequenza per creare figure aggiuntive. Al termine della creazione delle figure, chiamare il metodo Close.
Esempio: Creare un disegno complesso
La figura seguente mostra un disegno complesso con linee, archi e curve di Bézier. L'esempio di codice seguente mostra come creare il disegno utilizzando quattro oggetti di geometrie di percorso, uno per la montagna a sinistra, uno per la montagna a destra, uno per il fiume e uno per il sole con bagliori.
Creare una geometria di percorso per la montagna sinistra
L'esempio crea prima una geometria di percorso per la montagna sinistra, come illustrato nella figura seguente.
Per creare la montagna sinistra, nell'esempio viene chiamato il metodo ID2D1Factory::CreatePathGeometry per creare un ID2D1PathGeometry.
hr = m_pD2DFactory->CreatePathGeometry(&m_pLeftMountainGeometry);
Nell'esempio viene quindi utilizzato il metodo Open per ottenere un geometry sink da un ID2D1PathGeometry e viene memorizzato nella variabile pSink.
ID2D1GeometrySink *pSink = NULL;
hr = m_pLeftMountainGeometry->Open(&pSink);
L'esempio chiama quindi BeginFigure, passando D2D1_FIGURE_BEGIN_FILLED che indica che questa figura è compilata, chiama quindi AddLines, passando una matrice di D2D1_POINT_2F punti, (267, 177), (236, 192), (212, 160), (156, 255) e (346, 255).
Il codice seguente illustra come eseguire questa operazione.
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);
Creare una geometria di percorso per la montagna destra
L'esempio crea quindi un'altra geometria di percorso per la montagna destra con punti (481, 146), (449, 181), (433, 159), (401, 214), (381, 199), (323, 263) e (575, 263). La figura seguente mostra come viene visualizzata la montagna destra.
di montagna
Il codice seguente illustra come eseguire questa operazione.
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);
}
Creare una geometria di percorso per il sole
Nell'esempio viene quindi creata un'altra geometria di percorso per il sole, come illustrato nella figura seguente.
A tale scopo, la geometria del percorso crea un sink e aggiunge una figura per l'arco e una figura per ogni fiamma al sink. Ripetendo la sequenza di BeginFigure, i relativi metodi Add (ad esempio AddBezier) e EndFigure, vengono aggiunte più figure al sink.
Il codice seguente illustra come eseguire questa operazione.
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);
}
Creare una geometria di percorso per il fiume
L'esempio crea quindi un altro percorso geometrico per il fiume che contiene curve di Bézier. La figura seguente mostra come viene visualizzato il fiume.
Il codice seguente illustra come eseguire questa operazione.
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);
}
Eseguire il rendering delle geometrie di percorso sullo schermo
Nel codice seguente viene illustrato come eseguire il rendering delle geometrie di percorso popolate sullo schermo. Disegna e dipinge prima la geometria del sole, poi la geometria della montagna sinistra, quindi la geometria del fiume, e infine la geometria della montagna destra.
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();
L'esempio completo restituisce l'illustrazione seguente.
Argomenti correlati