Delen via


Renderen met behulp van een Direct2D-apparaatcontext

In dit onderwerp vindt u informatie over het maken van Direct2Dapparaatcontext in Windows 8. Deze informatie is van toepassing op u als u Windows Store-apps of een desktop-app ontwikkelt met Direct2D. In dit onderwerp wordt het doel van Direct2D-apparaatcontextobjecten beschreven, hoe u dat object maakt en een stapsgewijze handleiding voor het weergeven en weergeven van Direct2D-primitieven en -afbeeldingen. U leert ook over het schakelen tussen renderdoelen en het toevoegen van effecten aan uw app.

Wat is een Direct2D-apparaat?

U hebt een Direct2D-apparaat en een Direct3D-apparaat nodig om een Direct2D-apparaatcontext te maken. Een Direct2D-apparaat (toont een ID2D1Device interfaceaanwijzer) vertegenwoordigt een weergaveadapter. Een Direct3D-apparaat (toont een ID3D11Device interfaceaanwijzer) is gekoppeld aan een Direct2D-apparaat. Elke app moet één Direct2D-apparaat hebben, maar kan meer dan één apparaat hebben.

Wat is een Direct2D-apparaatcontext?

Een Direct2Dapparaatcontext (geeft een ID2D1DeviceContext interfaceaanwijzer weer) vertegenwoordigt een set status- en opdrachtbuffers die u gebruikt om naar een doel te renderen. U kunt methoden aanroepen in de apparaatcontext om de pijplijnstatus in te stellen en renderingopdrachten te genereren met behulp van de resources die eigendom zijn van een apparaat.

Rendering met Direct2D in Windows 8

In Windows 7 en eerder gebruikt u een ID2D1HwndRenderTarget of een andere renderdoelinterface om naar een venster of oppervlak te renderen. Vanaf Windows 8 wordt het niet aanbevolen om rendering te maken met behulp van methoden die afhankelijk zijn van interfaces zoals ID2D1HwndRenderTarget omdat ze niet werken met Windows Store-apps. U kunt een apparaatcontext gebruiken om weer te geven op een Hwnd als u een desktop-app wilt maken en toch wilt profiteren van de extra functies van de apparaatcontext. De apparaatcontext is echter vereist om inhoud weer te geven in een Windows Store-app met Direct2D-.

Waarom een apparaatcontext gebruiken om weer te geven?

Een Direct2D-apparaatcontext maken voor rendering

De code hier laat zien hoe u een Direct3D11-apparaat maakt, het bijbehorende DXGI-apparaat opzoekt, een Direct2D-apparaat maakten ten slotte de Context van het Direct2D--apparaat maakt voor rendering.

Hier volgt een diagram van de methode-aanroepen en de interfaces die door deze code worden gebruikt.

diagram van direct2d- en direct3d-apparaten en apparaatcontexten.

Notitie

In deze code wordt ervan uitgegaan dat u al een ID2D1Factory1--object hebt. Zie de referentiepagina ID2D1Factoryvoor meer informatie.

 

    // This flag adds support for surfaces with a different color channel ordering than the API default.
    // You need it for compatibility with Direct2D.
    UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
    
    // This array defines the set of DirectX hardware feature levels this app  supports.
    // The ordering is important and you should  preserve it.
    // Don't forget to declare your app's minimum required feature level in its
    // description.  All apps are assumed to support 9.1 unless otherwise stated.
    D3D_FEATURE_LEVEL featureLevels[] = 
    {
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
        D3D_FEATURE_LEVEL_9_3,
        D3D_FEATURE_LEVEL_9_2,
        D3D_FEATURE_LEVEL_9_1
    };

    // Create the DX11 API device object, and get a corresponding context.
    ComPtr<ID3D11Device> device;
    ComPtr<ID3D11DeviceContext> context;

    DX::ThrowIfFailed(
        D3D11CreateDevice(
            nullptr,                    // specify null to use the default adapter
            D3D_DRIVER_TYPE_HARDWARE,
            0,                          
            creationFlags,              // optionally set debug and Direct2D compatibility flags
            featureLevels,              // list of feature levels this app can support
            ARRAYSIZE(featureLevels),   // number of possible feature levels
            D3D11_SDK_VERSION,          
            &device,                    // returns the Direct3D device created
            &m_featureLevel,            // returns feature level of device created
            &context                    // returns the device immediate context
            )
        );

    ComPtr<IDXGIDevice> dxgiDevice;
    // Obtain the underlying DXGI device of the Direct3D11 device.
    DX::ThrowIfFailed(
        device.As(&dxgiDevice)
        );

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

    // Get Direct2D device's corresponding device context object.
    DX::ThrowIfFailed(
        m_d2dDevice->CreateDeviceContext(
            D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
            &m_d2dContext
            )
        );

Laten we de stappen in het voorgaande codevoorbeeld doorlopen.

  1. Verkrijg een ID3D11Device-interfaceaanwijzer die nodig is om de apparaatcontext te maken.

    • Declareer de creatievlaggen om het Direct3D apparaat in te stellen voor BGRA-ondersteuning. Direct2D- vereist BGRA-kleurvolgorde.

    • Declareer een matrix van D3D_FEATURE_LEVEL vermeldingen die de set functieniveaus vertegenwoordigen die door uw app worden ondersteund.

      Notitie

      Direct3D zoekt in uw lijst totdat het functieniveau wordt gevonden dat wordt ondersteund door het hostsysteem.

       

    • Gebruik de functie D3D11CreateDevice om een ID3D11Device--object te maken. De functie retourneert ook een ID3D11DeviceContext-object, maar dat object is niet nodig voor dit voorbeeld.

  2. Voer een query uit op het Direct3D 11-apparaat voor de interface van het DXGI-apparaat.

  3. Maak een ID2D1Device--object door de methode ID2D1Factory::CreateDevice aan te roepen en het IDXGIDevice--object door te geven.

  4. Maak een ID2D1DeviceContext aanwijzer met behulp van de ID2D1Device::CreateDeviceContext methode.

Een doel selecteren

De code hier laat zien hoe u de tweedimensionale Direct3D textuur voor de backbuffer van het venster kunt ophalen en een bitmapdoel maakt dat is gekoppeld aan deze textuur, waarop de context van het Direct2D-apparaat rendert.

        // Allocate a descriptor.
        DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
        swapChainDesc.Width = 0;                           // use automatic sizing
        swapChainDesc.Height = 0;
        swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // this is the most common swapchain format
        swapChainDesc.Stereo = false; 
        swapChainDesc.SampleDesc.Count = 1;                // don't use multi-sampling
        swapChainDesc.SampleDesc.Quality = 0;
        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        swapChainDesc.BufferCount = 2;                     // use double buffering to enable flip
        swapChainDesc.Scaling = DXGI_SCALING_NONE;
        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // all apps must use this SwapEffect
        swapChainDesc.Flags = 0;

        // Identify the physical adapter (GPU or card) this device is runs on.
        ComPtr<IDXGIAdapter> dxgiAdapter;
        DX::ThrowIfFailed(
            dxgiDevice->GetAdapter(&dxgiAdapter)
            );

        // Get the factory object that created the DXGI device.
        ComPtr<IDXGIFactory2> dxgiFactory;
        DX::ThrowIfFailed(
            dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory))
            );

        // Get the final swap chain for this window from the DXGI factory.
        DX::ThrowIfFailed(
            dxgiFactory->CreateSwapChainForCoreWindow(
                device.Get(),
                reinterpret_cast<IUnknown*>(m_window),
                &swapChainDesc,
                nullptr,    // allow on all displays
                &m_swapChain
                )
            );

        // Ensure that DXGI doesn't queue more than one frame at a time.
        DX::ThrowIfFailed(
            dxgiDevice->SetMaximumFrameLatency(1)
            );

    // Get the backbuffer for this window which is be the final 3D render target.
    ComPtr<ID3D11Texture2D> backBuffer;
    DX::ThrowIfFailed(
        m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer))
        );

    // Now we set up the Direct2D render target bitmap linked to the swapchain. 
    // Whenever we render to this bitmap, it is directly rendered to the 
    // swap chain 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_IGNORE),
            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
            )
        );

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

Laten we de stappen in het voorgaande codevoorbeeld doorlopen.

  1. Wijs een DXGI_SWAP_CHAIN_DESC1 structuur toe en definieer de instellingen voor de wisselketen.

    Deze instellingen laten een voorbeeld zien van het maken van een wisselketen die door een Windows Store-app kan worden gebruikt.

  2. Haal de adapter op waarop het Direct3D-apparaat en het DXGI-apparaat worden uitgevoerd en haal het IDXGIFactory--object dat eraan is gekoppeld. U moet deze DXGI-fabriek gebruiken om ervoor te zorgen dat de wisselketen op dezelfde adapter wordt gemaakt.

  3. Roep de IDXGIFactory2::CreateSwapChainForCoreWindow methode aan om de swap chain te maken. Gebruik de Windows::UI::CoreWindow klasse voor het hoofdvenster van een Windows Store-app.

    Zorg ervoor dat u de maximale framelatentie instelt op 1 om het energieverbruik te minimaliseren.

    Als u Direct2D-inhoud in een Windows Store-app wilt weergeven, raadpleegt u de methode CreateSwapChainForComposition.

  4. Haal de achterbuffer op uit de wisselketen. De back-buffer maakt een ID3D11Texture2D--interface beschikbaar die is toegewezen door de swapchain

  5. Declareer een D2D1_BITMAP_PROPERTIES1 struct en stel de eigenschapswaarden in. Stel de pixelindeling in op BGRA, omdat dit de indeling is die het Direct3D-apparaat en het DXGI-apparaat gebruiken.

  6. Haal de achterbuffer op als een IDXGISurface om door te geven aan Direct2D. Direct2D aanvaardt niet direct een ID3D11Texture2D.

    Maak een ID2D1Bitmap-object vanuit de backbuffer met behulp van de ID2D1DeviceContext::CreateBitmapFromDxgiSurface-methode.

  7. De Direct2D-bitmap is nu gekoppeld aan de backbuffer. Stel het doel in op de Direct2D-apparaatcontext op de bitmap.

Hoe te renderen en weergeven

Nu u een doelbitmap hebt, kunt u er primitieven, afbeeldingen, afbeeldingseffecten en tekst in tekenen met behulp van de Direct2D-apparaatcontext. De code hier laat zien hoe u een rechthoek tekent.

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

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

Laten we de stappen in het voorgaande codevoorbeeld doorlopen.

  1. Roep de CreateSolidColorBrush aan om een kwast te maken om de rechthoek te schilderen.
  2. Roep de methode BeginDraw aan voordat u tekenopdrachten uitgeeft.
  3. Roep de DrawRectangle methode aan om de rechthoek te tekenen en de kwast.
  4. Roep de methode EndDraw aan nadat u klaar bent met het uitgeven van tekenopdrachten.
  5. Geef het resultaat weer door de methode IDXGISwapChain::Present aan te roepen.

U kunt nu de context van het Direct2D-apparaat gebruiken primitieven, afbeeldingen, afbeeldingseffecten en tekst naar het scherm tekenen.