Freigeben über


Pfadgeometrien – Übersicht

In diesem Thema wird beschrieben, wie Sie mithilfe von Direct2D-Pfadgeometrien komplexe Zeichnungen erstellen. Es enthält die folgenden Abschnitte.

Voraussetzungen

In dieser Übersicht wird davon ausgegangen, dass Sie mit dem Erstellen grundlegender Direct2D-Anwendungen vertraut sind, wie in " Erstellen einer einfachen Direct2D-Anwendung" beschrieben. Es wird auch davon ausgegangen, dass Sie mit den grundlegenden Features von Direct2D-Geometrien vertraut sind, wie in der Geometries Overview beschrieben.

Pfadgeometrien in Direct2D

Pfadgeometrien werden durch die ID2D1PathGeometry-Schnittstelle dargestellt. Rufen Sie zum Instanziieren einer Pfadgeometrie die ID2D1Factory::CreatePathGeometry-Methode auf. Diese Objekte können verwendet werden, um komplexe geometrische Figuren zu beschreiben, die aus Segmenten wie Bogen, Kurven und Linien bestehen. Rufen Sie zum Auffüllen einer Pfadgeometrie mit Abbildungen und Segmenten die Open-Methode auf, um eine ID2D1GeometrySink abzurufen, und verwenden Sie die Methoden des Geometrie-Senkens, um der Pfadgeometrie Zahlen und Segmente hinzuzufügen.

Verwendung einer ID2D1GeometrySink zum Auffüllen einer Pfadgeometrie

ID2D1GeometrySink beschreibt einen geometrischen Pfad, der Linien, Bögen, kubische Bézierkurven und quadratische Bézierkurven enthalten kann.

Eine Geometriesenke besteht aus einer oder mehreren Figuren. Jede Abbildung besteht aus einem oder mehreren Linien-, Kurven- oder Bogensegmenten. Rufen Sie zum Erstellen einer Abbildung die BeginFigure-Methode auf, übergeben Sie den Ausgangspunkt der Abbildung, und verwenden Sie dann die Add-Methoden (z. B. AddLine und AddBezier), um Segmente hinzuzufügen. Wenn Sie mit dem Hinzufügen von Segmenten fertig sind, rufen Sie die EndFigure-Methode auf. Sie können diese Sequenz wiederholen, um zusätzliche Zahlen zu erstellen. Wenn Sie mit dem Erstellen von Abbildungen fertig sind, rufen Sie die Close-Methode auf.

Beispiel: Erstellen einer komplexen Zeichnung

Die folgende Abbildung zeigt eine komplexe Zeichnung mit Linien, Bogen und Bézierkurven. Das folgende Codebeispiel zeigt, wie Sie die Zeichnung mithilfe von vier Pfadgeometrieobjekten erstellen, eines für den linken Berg, eines für den rechten Berg, eine für den Fluss und eine für die Sonne mit Leuchteffekten.

Abbildung eines Flusses, berges und der Sonne mithilfe von Pfadgeometrien

Erstellen einer Pfadgeometrie für den linken Berg

Im Beispiel wird zunächst eine Pfadgeometrie für den linken Berg erstellt, wie in der folgenden Abbildung dargestellt.

Zeigt eine komplexe Zeichnung eines Polygons, das einen Berg zeigt.

Zum Erstellen des linken Bergs ruft das Beispiel die ID2D1Factory::CreatePathGeometry-Methode auf, um eine ID2D1PathGeometry zu erstellen.

hr = m_pD2DFactory->CreatePathGeometry(&m_pLeftMountainGeometry);

Das Beispiel verwendet dann die Methode Open , um eine Geometriesenke von einer ID2D1PathGeometry zu erhalten und speichert sie in der Variablen pSink .

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

Anschließend wird BeginFigure aufgerufen und D2D1_FIGURE_BEGIN_FILLED übergeben, was angibt, dass dieses Objekt gefüllt ist. Dann wird AddLines aufgerufen, wobei ein Array von D2D1_POINT_2F-Punkten, (267, 177), (236, 192), (212, 160), (156, 255) und (346, 255) übergeben wird.

Der folgende Code zeigt, wie dies funktioniert.

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

Erstellen einer Pfadgeometrie für den rechten Berg

Anschließend wird eine weitere Pfadgeometrie für den rechten Berg mit Punkten (481, 146), (449, 181), (433, 159), (401, 214), (381, 199), (323, 263) und (575, 263) erstellt. Die folgende Abbildung zeigt, wie der rechte Berg angezeigt wird.

Abbildung eines Polygons, das einen Berg zeigt

Der folgende Code zeigt, wie dies funktioniert.

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

Erstellen einer Pfadgeometrie für die Sonne

Das Beispiel erstellt dann eine weitere Pfadgeometrie für die Sonne, wie in der folgenden Abbildung gezeigt.

Illustration eines Bogens und von Bezier-Kurven, die die Sonne zeigen

Zu diesem Zweck erstellt die Pfadgeometrie eine Senke und fügt der Senke eine Figur für den Bogen und eine Figur für jede Fackel hinzu. Durch die Wiederholung der Sequenz von BeginFigure, seiner Add (wie AddBezier) Methoden und EndFigurewerden mehrere Figuren zur Senke hinzugefügt.

Der folgende Code zeigt, wie dies funktioniert.

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

Erstellen einer Pfadgeometrie für den Fluss

Ein weiteres Beispiel erstellt dann einen Geometriepfad für den Fluss, der Bezierkurven enthält. Die folgende Abbildung zeigt, wie der Fluss angezeigt wird.

Abbildung von Bézierkurven, die einen Fluss zeigen

Der folgende Code zeigt, wie dies funktioniert.

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

Rendern der Pfadgeometrien auf dem Display

Der folgende Code zeigt, wie die aufgefüllten Pfadgeometrien auf dem Display gerendert werden. Es zeichnet zuerst die Sonnengeometrie, neben der linken Berggeometrie, dann die Flussgeometrie und schließlich die rechte Berggeometrie.

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

Im vollständigen Beispiel wird die folgende Abbildung ausgegeben.

Abbildung eines Flusses, berges und der Sonne mithilfe von Pfadgeometrien

Erstellen einer einfachen Direct2D-Anwendung

übersicht über Geometrien