Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Este tópico descreve como usar geometrias de caminho Direct2D para criar desenhos complexos. Contém as seguintes secções.
- Pré-requisitos
- Geometrias de Caminho no Direct2D
- Usando um ID2D1GeometrySink para preencher uma geometria de trajeto
- exemplo: Criar um desenho complexo
- Tópicos relacionados
Pré-requisitos
Esta visão geral pressupõe que você esteja familiarizado com a criação de aplicativos Direct2D básicos, conforme descrito em Criar um aplicativo Direct2D simples. Ele também pressupõe que você esteja familiarizado com os recursos básicos das geometrias Direct2D, conforme descrito no Geometries Overview.
Geometrias de caminho no Direct2D
As geometrias de caminho são representadas pela interface ID2D1PathGeometry. Para instanciar uma geometria de caminho, chame o ID2D1Factory::CreatePathGeometry método. Esses objetos podem ser usados para descrever figuras geométricas complexas compostas por segmentos como arcos, curvas e linhas. Para preencher uma geometria de caminho com figuras e segmentos, chame o método Open para recuperar umID2D1GeometrySinke use os métodos do coletor de geometria para adicionar figuras e segmentos à geometria do caminho.
Usando um ID2D1GeometrySink para preencher uma geometria de caminho
ID2D1GeometrySink descreve um caminho geométrico que pode conter linhas, arcos, curvas cúbicas de Bezier e curvas quadráticas de Bezier.
Um receptáculo de geometria consiste em uma ou mais figuras. Cada figura é composta por uma ou mais linhas, curvas ou segmentos de arco. Para criar uma figura, chame o método BeginFigure, passando o ponto de partida da figura e, em seguida, use seus métodos Add (como AddLine e AddBezier) para adicionar segmentos. Quando terminar de adicionar segmentos, chame o método EndFigure. Você pode repetir essa sequência para criar figuras adicionais. Quando terminar de criar figuras, chame o método Close.
Exemplo: Criar um desenho complexo
A ilustração a seguir mostra um desenho complexo com linhas, arcos e curvas de Bezier. O exemplo de código a seguir mostra como criar o desenho usando quatro objetos de geometria de caminho, um para a montanha esquerda, um para a montanha direita, um para o rio e um para o sol com labaredas.
Criar uma geometria de percurso para a montanha à esquerda
O exemplo primeiro cria uma geometria de caminho para a montanha esquerda, conforme mostrado na ilustração a seguir.
Para criar a montanha esquerda, o exemplo chama o método ID2D1Factory::CreatePathGeometry para criar um ID2D1PathGeometry.
hr = m_pD2DFactory->CreatePathGeometry(&m_pLeftMountainGeometry);
O exemplo utiliza o método Open para obter um coletor de geometria de um ID2D1PathGeometry e armazena-o na variável pSink.
ID2D1GeometrySink *pSink = NULL;
hr = m_pLeftMountainGeometry->Open(&pSink);
O exemplo então chama BeginFigure, passando D2D1_FIGURE_BEGIN_FILLED que indica que esta figura está preenchida e, em seguida, chama AddLines, passando uma matriz de D2D1_POINT_2F pontos, (267, 177), (236, 192), (212, 160), (156, 255) e (346, 255).
O código a seguir mostra como fazer isso.
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);
Criar uma geometria de trajeto para a montanha à direita
O exemplo então cria outra geometria de caminho para a montanha direita com pontos (481, 146), (449, 181), (433, 159), (401, 214), (381, 199), (323, 263) e (575, 263). A ilustração a seguir mostra como a montanha certa é exibida.
O código a seguir mostra como fazer isso.
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);
}
Criar uma geometria de caminho para o Sol
O exemplo então popula outra geometria de caminho para o sol, conforme mostrado na ilustração a seguir.
Para fazer isso, a geometria do caminho cria um coletor e adiciona ao coletor uma figura para o arco e uma figura para cada flare. Repetindo a sequência de BeginFigure, seus métodos Add (como AddBezier) e EndFigure, várias figuras são adicionadas ao coletor.
O código a seguir mostra como fazer isso.
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);
}
Criar uma geometria de caminho para o rio
O exemplo então cria outro caminho de geometria para o rio que contém curvas de Bezier. A ilustração a seguir mostra como o rio é exibido.
O código a seguir mostra como fazer isso.
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);
}
Renderizar as geometrias de caminho na tela
O código a seguir mostra como renderizar as geometrias de trajeto preenchidas no ecrã. Primeiro desenha e pinta a geometria do sol, depois a geometria da montanha esquerda, em seguida a geometria do rio e, finalmente, a geometria da montanha direita.
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();
O exemplo completo produz a ilustração a seguir.
Tópicos relacionados