Windows 8 대한 Direct2D 빠른 시작

Direct2D는 2D 그래픽을 만들기 위한 네이티브 코드 즉시 모드 API입니다. 이 항목에서는 Direct2D를 사용하여 Windows::UI::Core::CoreWindow에 그리는 방법을 보여 줍니다.

이 항목에는 다음과 같은 섹션이 포함되어 있습니다.

간단한 사각형 그리기

GDI를 사용하여 사각형을 그리려면 다음 코드와 같이 WM_PAINT 메시지를 처리할 수 있습니다.

switch(message)
{

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            BeginPaint(hwnd, &ps);

            // Obtain the size of the drawing area.
            RECT rc;
            GetClientRect(
                hwnd,
                &rc
            );          

            // Save the original object
            HGDIOBJ original = NULL;
            original = SelectObject(
                ps.hdc,
                GetStockObject(DC_PEN)
            );

            // Create a pen.            
            HPEN blackPen = CreatePen(PS_SOLID, 3, 0);

            // Select the pen.
            SelectObject(ps.hdc, blackPen);

            // Draw a rectangle.
            Rectangle(
                ps.hdc, 
                rc.left + 100, 
                rc.top + 100, 
                rc.right - 100, 
                rc.bottom - 100);   

            DeleteObject(blackPen);

            // Restore the original object
            SelectObject(ps.hdc, original);

            EndPaint(hwnd, &ps);
        }
        return 0;

// Code for handling other messages. 

Direct2D를 사용하여 동일한 사각형을 그리는 코드는 유사합니다. 그리기 리소스를 만들고, 그릴 셰이프를 설명하고, 도형을 그린 다음, 그리기 리소스를 해제합니다. 다음 섹션에서는 이러한 각 단계를 자세히 설명합니다.

1단계: Direct2D 헤더 포함

애플리케이션에 필요한 헤더 외에도 d2d1.h 및 d2d1_1.h 헤더를 포함합니다.

2단계: ID2D1Factory1 만들기

Direct2D 예제에서 수행하는 첫 번째 작업 중 하나는 ID2D1Factory1을 만드는 것입니다.

DX::ThrowIfFailed(
        D2D1CreateFactory(
            D2D1_FACTORY_TYPE_SINGLE_THREADED,
            __uuidof(ID2D1Factory1),
            &options,
            &m_d2dFactory
            )
        );

ID2D1Factory1 인터페이스는 Direct2D를 사용하기 위한 시작점입니다. ID2D1Factory1을 사용하여 Direct2D 리소스를 만듭니다.

팩터리를 만들 때 다중 스레드인지 아니면 단일 스레드인지 지정할 수 있습니다. 다중 스레드 팩터리에 대한 자세한 내용은 ID2D1Factory 참조 페이지의 설명을 참조하세요. 이 예제에서는 단일 스레드 팩터리를 만듭니다.

일반적으로 애플리케이션은 팩터리를 한 번 만들고 애플리케이션 수명 동안 유지해야 합니다.

3단계: ID2D1Device 및 ID2D1DeviceContext 만들기

팩터리를 만든 후 이를 사용하여 Direct2D 디바이스를 만든 다음 디바이스를 사용하여 Direct2D 디바이스 컨텍스트를 만듭니다. 이러한 Direct2D 개체를 만들려면 Direct3D 11 디바이스 , DXGI 디바이스DXGI 스왑 체인이 있어야 합니다. 필요한 필수 구성 요소를 만드는 방법에 대한 자세한 내용은 디바이스 및 디바이스 컨텍스트 를 참조하세요.


    // Obtain the underlying DXGI device of the Direct3D11.1 device.
    DX::ThrowIfFailed(
        m_d3dDevice.As(&dxgiDevice)
        );

    // Obtain the Direct2D device for 2-D rendering.
    DX::ThrowIfFailed(
        m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice)
        );

    // And get its corresponding device context object.
    DX::ThrowIfFailed(
        m_d2dDevice->CreateDeviceContext(
            D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
            &m_d2dContext
            )
        );

디바이스 컨텍스트는 그리기 작업을 수행하고 브러시와 같은 디바이스 종속 그리기 리소스를 만들 수 있는 디바이스입니다. 또한 디바이스 컨텍스트를 사용하여 렌더링 대상으로 사용할 ID2D1Bitmap 을 DXGI 표면에 연결합니다. 디바이스 컨텍스트는 다양한 유형의 대상에 렌더링할 수 있습니다.

여기서 코드는 CoreWindow로 렌더링되는 DXGI 스왑 체인에 연결되는 비트맵의 속성을 선언합니다. ID2D1DeviceContext::CreateBitmapFromDxgiSurface 메서드는 DXGI 표면에서 Direct2D 표면을 가져옵니다. 이렇게 하면 대상 ID2D1Bitmap 에 렌더링된 모든 항목이 스왑 체인의 표면에 렌더링됩니다.

Direct2D 화면이 있으면 ID2D1DeviceContext::SetTarget 메서드를 사용하여 활성 렌더링 대상으로 설정합니다.

    // Now we set up the Direct2D render target bitmap linked to the swapchain. 
    // Whenever we render to this bitmap, it will be directly rendered to the 
    // swapchain associated with the window.
    D2D1_BITMAP_PROPERTIES1 bitmapProperties = 
        BitmapProperties1(
            D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
            PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
            m_dpi,
            m_dpi
            );

    // Direct2D needs the dxgi version of the backbuffer surface pointer.
    ComPtr<IDXGISurface> dxgiBackBuffer;
    DX::ThrowIfFailed(
        m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer))
        );

    // Get a D2D surface from the DXGI back buffer to use as the D2D render target.
    DX::ThrowIfFailed(
        m_d2dContext->CreateBitmapFromDxgiSurface(
            dxgiBackBuffer.Get(),
            &bitmapProperties,
            &m_d2dTargetBitmap
            )
        );

    // So now we can set the Direct2D render target.
    m_d2dContext->SetTarget(m_d2dTargetBitmap.Get());

4단계: 브러시 만들기

공장과 마찬가지로 디바이스 컨텍스트는 그리기 리소스를 만들 수 있습니다. 이 예제에서 디바이스 컨텍스트는 브러시를 만듭니다.

ComPtr<ID2D1SolidColorBrush> pBlackBrush;
DX::ThrowIfFailed(
   m_d2dContext->CreateSolidColorBrush(
        D2D1::ColorF(D2D1::ColorF::Black),
        &pBlackBrush
        )
);

브러시는 도형의 스트로크 또는 기하 도형 채우기와 같은 영역을 그리는 개체입니다. 이 예제의 브러시는 미리 정의된 단색 검은색으로 영역을 그립니다.

Direct2D는 선형 및 방사형 그라데이션을 그리기 위한 그라데이션 브러시, 비트맵 및 패턴으로 그리기 위한 비트맵 브러시, 렌더링된 이미지로 그리기 위한 이미지 브러시인 Windows 8 시작하여 다른 유형의 브러시도 제공합니다.

일부 그리기 API는 도형을 채우기 위한 윤곽선 및 브러시를 그리기 위한 펜을 제공합니다. Direct2D는 서로 다릅니다. 펜 개체를 제공하지는 않지만 윤곽선을 그리고 도형을 채우는 브러시를 사용합니다. 윤곽선을 그릴 때 ID2D1StrokeStyle 인터페이스를 사용하거나 경로 쓰다듬기 작업을 제어하는 브러시를 사용하여 ID2D1StrokeStyle1 인터페이스를 Windows 8 시작합니다.

브러시는 만든 렌더링 대상과 동일한 리소스 도메인의 다른 렌더링 대상에서만 사용할 수 있습니다. 일반적으로 브러시를 한 번 만들어 만든 렌더링 대상의 수명 동안 유지해야 합니다. ID2D1SolidColorBrush 는 고독한 예외입니다. 만드는 것이 상대적으로 저렴하기 때문에 눈에 띄는 성능 적중 없이 프레임을 그릴 때마다 ID2D1SolidColorBrush 를 만들 수 있습니다. 단일 ID2D1SolidColorBrush 를 사용하고 사용할 때마다 색이나 불투명도를 변경할 수도 있습니다.

5단계: 사각형 그리기

다음으로, 디바이스 컨텍스트를 사용하여 사각형을 그립니다.

 
m_d2dContext->BeginDraw();

m_d2dContext->DrawRectangle(
    D2D1::RectF(
        rc.left + 100.0f,
        rc.top + 100.0f,
        rc.right - 100.0f,
        rc.bottom - 100.0f),
        pBlackBrush);

DX::ThrowIfFailed(
    m_d2dContext->EndDraw()
);

DX::ThrowIfFailed(
    m_swapChain->Present1(1, 0, &parameters);
);

DrawRectangle 메서드는 그릴 사각형과 사각형의 윤곽선을 그리는 데 사용할 브러시라는 두 개의 매개 변수를 사용합니다. 필요에 따라 스트로크 너비, 대시 패턴, 선 조인 및 끝 캡 옵션을 지정할 수도 있습니다.

그리기 명령을 실행하기 전에 BeginDraw 메서드를 호출해야 하며 그리기 명령 실행을 완료한 후 EndDraw 메서드를 호출해야 합니다. EndDraw 메서드는 그리기 명령이 성공했는지 여부를 나타내는 HRESULT를 반환합니다. 성공하지 못하면 ThrowIfFailed 도우미 함수가 예외를 throw합니다.

IDXGISwapChain::P resent 메서드는 버퍼 표면을 화면 표면으로 교환하여 결과를 표시합니다.

예제 코드

이 항목의 코드는 Direct2D 애플리케이션의 기본 요소를 보여줍니다. 간단히 하기 위해 토픽은 잘 작성된 애플리케이션의 특징인 애플리케이션 프레임워크 및 오류 처리 코드를 생략합니다.