다음을 통해 공유


경로 기하 도형 개요

이 항목에서는 Direct2D 경로 기하 도형을 사용하여 복잡한 드로잉을 만드는 방법을 설명합니다. 여기에는 다음 섹션이 포함되어 있습니다.

필수 구성 요소

이 개요에서는 간단한 Direct2D 애플리케이션 만들기 설명한 대로 기본 Direct2D 애플리케이션을 만드는 데 익숙하다고 가정합니다. 또한 기하 도형 개요설명된 것처럼 Direct2D 기하 도형의 기본 기능에 익숙하다고 가정합니다.

Direct2D의 경로 기하 도형

경로 기하 도형은 ID2D1PathGeometry 인터페이스로 표시됩니다. 경로 기하 도형을 인스턴스화하려면 ID2D1Factory::CreatePathGeometry 메서드를 호출합니다. 이러한 개체는 호, 곡선 및 선과 같은 세그먼트로 구성된 복잡한 기하학적 그림을 설명하는 데 사용할 수 있습니다. 경로 기하 도형을 그림과 세그먼트로 채우려면 Open 메서드를 호출하여 ID2D1GeometrySink 검색하고 기하 도형 싱크의 메서드를 사용하여 경로 기하 도형에 그림과 세그먼트를 추가합니다.

ID2D1GeometrySink를 사용하여 경로 기하 도형 구성하기

ID2D1GeometrySink 선, 호, 입방형 베지어 곡선 및 이차형 베지어 곡선을 포함할 수 있는 기하학적 경로를 설명합니다.

기하 싱크는 하나 이상의 도형으로 구성됩니다. 각 그림은 하나 이상의 선, 곡선 또는 호 세그먼트로 구성됩니다. 그림을 만들려면 BeginFigure 메서드를 호출하여 그림의 시작점을 전달한 다음 AddLine 및 addBezier등의 Add 메서드를 사용하여 세그먼트를 추가합니다. 세그먼트 추가가 완료되면 EndFigure 메서드를 호출합니다. 이 시퀀스를 반복하여 추가 수치를 만들 수 있습니다. 그림 만들기가 완료되면 Close 메서드를 호출합니다.

예: 복합 그리기 만들기

다음 그림에서는 선, 호 및 베지어 곡선이 있는 복잡한 드로잉을 보여 줍니다. 다음 코드 예제에서는 4개의 경로 기하 도형 개체를 사용하여 드로잉을 만드는 방법을 보여 줍니다. 하나는 왼쪽 산에, 다른 하나는 오른쪽 산에, 다른 하나는 강에, 다른 하나는 조명탄이 있는 태양을 위한 것입니다.

경로 기하 도형을 사용하여 강, 산, 태양의 그림

왼쪽 산에 대한 경로 기하 도형 만들기

이 예제에서는 먼저 다음 그림과 같이 왼쪽 산에 대한 경로 기하 도형을 만듭니다.

산을 보여주는 다각형의 복잡한 드로잉을 표시합니다.

왼쪽 산을 만들기 위해 예제에서는 ID2D1Factory::CreatePathGeometry 메서드를 호출하여 ID2D1PathGeometry만듭니다.

hr = m_pD2DFactory->CreatePathGeometry(&m_pLeftMountainGeometry);

그런 다음 Open 메서드를 사용하여 ID2D1PathGeometry 기하 도형 싱크를 가져와서 pSink 변수에 저장합니다.

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

그런 다음 BeginFigure를 호출하고, D2D1_FIGURE_BEGIN_FILLED 를 전달하여 이 그림이 채워짐을 나타냅니다. 그런 다음 AddLines를 호출하고, D2D1_POINT_2F 점들로 구성된 배열 (267, 177), (236, 192), (212, 160), (156, 255) 및 (346, 255)을 전달합니다.

다음 코드는 이 작업을 수행하는 방법을 보여줍니다.

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

오른쪽 산에 대한 경로 기하 도형 만들기

예제는 이어서 포인트 (481, 146), (449, 181), (433, 159), (401, 214), (381, 199), (323, 263), (575, 263)을 사용하여 오른쪽 산에 대한 또 다른 경로 기하를 생성합니다. 다음 그림에서는 오른쪽 산이 표시되는 방법을 보여 줍니다.

산그림

다음 코드는 이 작업을 수행하는 방법을 보여줍니다.

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

태양에 대한 경로 기하 도형 만들기

그런 이후, 다음 그림과 같이 태양에 대한 또 다른 경로 기하 도형을 생성합니다.

호와 베지어 곡선을 사용하여 태양을 보여주는 그림

이를 위해 경로 기하 도형은 싱크를 만들고 아크에 대한 그림과 각 플레어의 그림을 싱크에 추가합니다. BeginFigure, AddBezier과 같은 Add 메서드, 그리고 EndFigure의 시퀀스를 반복하면, 싱크에 여러 그림을 추가할 수 있습니다.

다음 코드는 이 작업을 수행하는 방법을 보여줍니다.

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

강에 대한 경로 기하 도형 만들기

그런 다음, 베지어 곡선을 포함하는 강에 대한 다른 기하 도형 경로를 만듭니다. 다음 그림에서는 강이 표시되는 방법을 보여 줍니다.

강그림

다음 코드는 이 작업을 수행하는 방법을 보여줍니다.

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

디스플레이에 경로 기하 도형 렌더링

다음 코드에서는 디스플레이에 채워진 경로 기하 도형을 렌더링하는 방법을 보여 있습니다. 먼저 태양 기하 도형, 왼쪽 산악 기하 도형, 강 기하 도형, 그리고 마지막으로 오른쪽 산 기하 도형을 그리고 그립니다.

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

전체 예제에서는 다음 그림을 출력합니다.

경로 기하 도형을 사용하여 강, 산, 태양의 그림

간단한 Direct2D 애플리케이션 만들기

기하 도형 개요