Dela via


Ö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

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.

bild av en flod, berg och solen med hjälp av sökvägsgeometrier

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.

Visar en komplex ritning av en polygon som visar ett berg.

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.

bild av en polygon som visar ett berg

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.

bild av en båge och bézierkurvor som visar solen

** 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.

bild av bezierkurvor som visar en flod

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.

bild av en flod, berg och solen med hjälp av sökvägsgeometrier

Skapa ett enkelt Direct2D-program

Översikt över Geometrier