Partager via


Vue d’ensemble des géométries de chemin

Cette rubrique explique comment utiliser les géométries de chemin Direct2D pour créer des dessins complexes. Elle contient les sections suivantes.

Prérequis

Cette vue d’ensemble suppose que vous êtes familiarisé avec la création d’applications Direct2D de base, comme décrit dans Créer une application Direct2D simple. Il suppose également que vous êtes familiarisé avec les fonctionnalités de base des géométries Direct2D, comme décrit dans vue d’ensemble des géométries.

Géométries de chemin dans Direct2D

Les géométries de chemin d’accès sont représentées par l’interface ID2D1PathGeometry . Pour instancier une géométrie de chemin d’accès, appelez la méthode ID2D1Factory::CreatePathGeometry . Ces objets peuvent être utilisés pour décrire des figures géométriques complexes composées de segments tels que des arcs, des courbes et des lignes. Pour remplir une géométrie de chemin avec des figures et des segments, appelez la méthode Open pour récupérer un ID2D1GeometrySink et utilisez les méthodes du récepteur geometry pour ajouter des figures et des segments à la géométrie de chemin.

Utilisation d’un ID2D1GeometrySink pour remplir une géométrie de chemin d’accès

ID2D1GeometrySink décrit un chemin géométrique qui peut contenir des lignes, des arcs, des courbes de Bézier cubiques et des courbes de Bézier quadratique.

Un récepteur geometry se compose d’une ou plusieurs figures. Chaque figure est composée d’une ou plusieurs lignes, courbes ou segments d’arc. Pour créer une figure, appelez la méthode BeginFigure , en passant le point de départ de la figure, puis utilisez ses méthodes Add (telles que AddLine et AddBezier) pour ajouter des segments. Lorsque vous avez terminé d’ajouter des segments, appelez la méthode EndFigure . Vous pouvez répéter cette séquence pour créer des figures supplémentaires. Lorsque vous avez terminé de créer des figures, appelez la méthode Close .

Exemple : Créer un dessin complexe

L’illustration suivante montre un dessin complexe avec des lignes, des arcs et des courbes de Bézier. L’exemple de code qui suit montre comment créer le dessin à l’aide de quatre objets géométriques de chemin, un pour la montagne de gauche, un pour la montagne de droite, un pour la rivière et un pour le soleil avec des éruptions.

illustration d’une rivière, des montagnes et du soleil, en utilisant des géométries de chemin

Créer une géométrie de chemin pour la montagne gauche

L’exemple crée d’abord une géométrie de chemin pour la montagne gauche, comme illustré dans l’illustration suivante.

Affiche un dessin complexe d’un polygone qui montre une montagne.

Pour créer la montagne de gauche, l’exemple appelle la méthode ID2D1Factory::CreatePathGeometry pour créer une id2D1PathGeometry.

hr = m_pD2DFactory->CreatePathGeometry(&m_pLeftMountainGeometry);

L’exemple utilise ensuite la méthode Open pour obtenir un récepteur geometry à partir d’un ID2D1PathGeometry et le stocker dans la variable pSink .

ID2D1GeometrySink *pSink = NULL;
hr = m_pLeftMountainGeometry->Open(&pSink);

L’exemple appelle ensuite BeginFigure, en passant D2D1_FIGURE_BEGIN_FILLED qui indique que cette figure est remplie, puis appelle AddLines, en passant un tableau de points D2D1_POINT_2F , (267, 177), (236, 192), (212, 160), (156, 255) et (346, 255).

Le code suivant montre comment procéder.

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);

Créer une géométrie de chemin pour la montagne droite

L’exemple crée ensuite une autre géométrie de chemin pour la montagne droite avec des points (481, 146), (449, 181), (433, 159), (401, 214), (381, 199), (323, 263) et (575, 263). L’illustration suivante montre comment la montagne droite est affichée.

illustration d’un polygone qui montre une montagne

Le code suivant montre comment procéder.

        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);
       }

Créer une géométrie de chemin pour le soleil

L’exemple remplit ensuite une autre géométrie de chemin pour le soleil, comme illustré dans l’illustration suivante.

illustration d’un arc et des courbes de béziers qui montrent le soleil

Pour ce faire, la géométrie de chemin crée un récepteur et ajoute une figure pour l’arc et une figure pour chaque poussée au récepteur. En répétant la séquence de BeginFigure, ses méthodes Add (comme AddBezier) et EndFigure, plusieurs figures sont ajoutées au récepteur.

Le code suivant montre comment procéder.

        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);
       }

Créer une géométrie de chemin pour la rivière

L’exemple crée ensuite un autre chemin géométrique pour la rivière qui contient des courbes de Béziers. L’illustration suivante montre comment la rivière est affichée.

illustration de courbes de béziers qui montrent une rivière

Le code suivant montre comment procéder.

        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);
            }

Afficher les géométries de chemin d’accès sur l’affichage

Le code suivant montre comment restituer les géométries de chemin d’accès renseignées sur l’affichage. Il dessine et peint d’abord la géométrie du soleil, ensuite la géométrie de montagne gauche, puis la géométrie fluviale, et enfin la géométrie de montagne droite.

 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’exemple complet génère l’illustration suivante.

illustration d’une rivière, des montagnes et du soleil, en utilisant des géométries de chemin

Créer une simple application Direct2D

Vue d’ensemble des géométries