경로 기하 도형 개요

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

사전 요구 사항

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

Direct2D의 경로 기하 도형

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

ID2D1GeometrySink를 사용하여 경로 기하 도형 채우기

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

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

예: 복잡한 그리기 만들기

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

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

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

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

산을 보여 주는 다각형의 복잡한 그림을 표시합니다.

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

hr = m_pD2DFactory->CreatePathGeometry(&m_pLeftMountainGeometry);

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

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

그런 다음 그림이 채워짐을 나타내는 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 등의 추가 메서드 및 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 애플리케이션 만들기

기하 도형 개요