Delen via


Direct2D-snelstartgids voor Windows 8

Direct2D is een native-code, immediate-mode API voor het maken van 2D-graphics. In dit onderwerp wordt uitgelegd hoe u Direct2D gebruikt om te tekenen op een Windows::UI::Core::CoreWindow.

Dit onderwerp bevat de volgende secties:

Een eenvoudige rechthoek tekenen

Als u een rechthoek wilt tekenen met GDI-, kunt u het WM_PAINT bericht afhandelen, zoals wordt weergegeven in de volgende code.

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. 

De code voor het tekenen van dezelfde rechthoek met Direct2D is vergelijkbaar: hiermee worden tekenresources gemaakt, wordt een shape beschreven die moet worden getekend, wordt de shape getekend en worden vervolgens de tekenresources vrijgegeven. In de volgende secties wordt elk van deze stappen gedetailleerd beschreven.

Stap 1: Direct2D-header opnemen

Naast de headers die vereist zijn voor de toepassing, neemt u de d2d1.h- en d2d1_1.h-headers op.

Stap 2: een ID2D1Factory1 maken

Een van de eerste dingen die een Direct2D-voorbeeld doet, is het maken van een ID2D1Factory1-.

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

De ID2D1Factory1 interface is het startpunt voor het gebruik van Direct2D; gebruik een ID2D1Factory1 om Direct2D-resources te maken.

Wanneer u een fabriek maakt, kunt u specificeren of deze multi-threaded of single-threaded moet zijn. (Zie de opmerkingen op de referentiepagina van ID2D1Factoryvoor meer informatie over multithreaded factory's. In dit voorbeeld wordt een factory met één thread gemaakt.

Over het algemeen moet uw toepassing de fabriek eenmaal maken en deze gedurende de levensduur van de toepassing behouden.

Stap 3: een ID2D1Device en een ID2D1DeviceContext maken

Nadat u een fabriek hebt gemaakt, gebruikt u het om een Direct2D-apparaat te maken en gebruikt u vervolgens het apparaat om een Direct2D-apparaatcontext te maken. Als u deze Direct2D-objecten wilt maken, moet u een Direct3D 11-apparaat hebben, een DXGI-apparaaten een DXGI-wisselketen. Zie apparaten en apparaatcontexten voor informatie over het creëren van de benodigde voorwaarden.


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

Een apparaatcontext is een apparaat dat tekenbewerkingen kan uitvoeren en apparaatafhankelijke tekenresources zoals borstels kan maken. U gebruikt ook de apparaatcontext om een ID2D1Bitmap te koppelen aan een DXGI-oppervlak om te gebruiken als renderdoel. De apparaatcontext kan worden weergegeven voor verschillende typen doelen.

De code hier declareert de eigenschappen voor een bitmap die is gekoppeld aan een DXGI-swap chain die wordt weergegeven op een CoreWindow-. De ID2D1DeviceContext::CreateBitmapFromDxgiSurface methode haalt een Direct2D-oppervlak op van het DXGI-oppervlak. Hierdoor wordt alles wat wordt weergegeven op de doel-ID2D1Bitmap weergegeven op het oppervlak van de wisselketen.

Zodra u het Direct2D-oppervlak hebt, gebruikt u de methode ID2D1DeviceContext::SetTarget om deze in te stellen als het actieve renderdoel.

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

Stap 4: Een borstel maken

Net als een fabriek kan een apparaatcontext tekenbronnen maken. In dit voorbeeld maakt de apparaatcontext een pensel.

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

Een borstel is een object dat een gebied schildert, zoals de lijn van een vorm of de opvulling van een geometrie. De kwast in dit voorbeeld schildert een gebied met een vooraf gedefinieerde effen kleur, zwart.

Direct2D biedt ook andere soorten borstels: kleurovergangsborstels voor het schilderen van lineaire en radiale kleurovergangen, een bitmapborstel voor het schilderen met bitmaps en patronen, en vanaf Windows 8, een afbeeldingsborstel voor het schilderen met een gerenderde afbeelding.

Sommige teken-API's bieden pennen voor tekenkaders en borstels voor het vullen van vormen. Direct2D is anders: het biedt geen penobject, maar maakt gebruik van een penseel voor het tekenen van contouren en het vullen van vormen. Wanneer u overzichten tekent, gebruikt u de ID2D1StrokeStyle interface, of vanaf Windows 8 de ID2D1StrokeStyle1 interface, met een kwast om padstreekbewerkingen te beheren.

Een penseel kan alleen worden gebruikt met het renderdoel dat het heeft gecreëerd en met andere renderdoelen binnen hetzelfde resourcedomein. Over het algemeen moet u eenmaal penselen maken en deze behouden gedurende de levensduur van het renderdoelobject dat ze heeft aangemaakt. ID2D1SolidColorBrush de enige uitzondering is; omdat het relatief goedkoop is om te maken, kunt u een ID2D1SolidColorBrush maken telkens wanneer u een frame tekent, zonder merkbare prestatietreffers. Je kunt ook één ID2D1SolidColorBrush gebruiken en de kleur of transparantie ervan wijzigen telkens wanneer je deze gebruikt.

Stap 5: De rechthoek tekenen

Gebruik vervolgens de apparaatcontext om de rechthoek te tekenen.

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

De methode DrawRectangle heeft twee parameters: de rechthoek die moet worden getekend en de kwast die moet worden gebruikt om de omtrek van de rechthoek te schilderen. U kunt desgewenst ook de opties voor lijnbreedte, streepjespatroon, lijnverbinding en eindkap opgeven.

U moet de methode BeginDraw aanroepen voordat u tekenopdrachten uitgeeft en u moet de methode EndDraw aanroepen nadat u klaar bent met het uitgeven van tekenopdrachten. De methode EndDraw retourneert een HRESULT- die aangeeft of de tekenopdrachten zijn geslaagd. Als het niet lukt, genereert de helperfunctie ThrowIfFailed een uitzondering.

De IDXGISwapChain::Present methode verwisselt het bufferoppervlak met het schermoppervlak om het resultaat weer te geven.

Voorbeeldcode

De code in dit onderwerp bevat de basiselementen van een Direct2D-toepassing. Kortom, het onderwerp laat het toepassingsframework en de code voor foutafhandeling weg die kenmerkend is voor een goed geschreven toepassing.