Sdílet prostřednictvím


Vykreslení pomocí kontextu zařízení Direct2D

V tomto tématu se dozvíte o vytváření kontextu zařízení Direct2D ve Windows 8. Tyto informace platí pro vás, pokud vyvíjíte aplikace pro Windows Store nebo desktopovou aplikaci pomocí Direct2D. Toto téma popisuje účel kontextových objektů zařízení Direct2D, vytvoření tohoto objektu a podrobného průvodce vykreslováním a zobrazením primitiv a obrázků Direct2D. Dozvíte se také o přepínání cílů vykreslování a přidávání efektů do aplikace.

Co je zařízení Direct2D?

K vytvoření kontextu zařízení Direct2D potřebujete zařízení Direct2D a zařízení Direct3D. zařízení Direct2D (představuje ukazatel rozhraní ID2D1Device) představuje adaptér pro zobrazení. Zařízení Direct3D (zveřejňuje ukazatel rozhraní ID3D11Device) je přidruženo k zařízení Direct2D. Každá aplikace musí mít jedno zařízení Direct2D, ale může mít více než jedno zařízení .

Co je kontext zařízení Direct2D?

Kontext zařízení Direct2D (poskytuje ukazatel rozhraní ID2D1DeviceContext) představuje sadu stavových a příkazových vyrovnávacích pamětí, které se používají pro vykreslování cíle. Metody v kontextu zařízení můžete volat k nastavení stavu kanálu a generování příkazů vykreslování pomocí prostředků vlastněných zařízením.

Vykreslování pomocí Direct2D ve Windows 8

Ve Windows 7 a dřívějších verzích použijete ID2D1HwndRenderTarget nebo jiné rozhraní cílového vykreslení k vykreslení na okno nebo povrch. Počínaje Windows 8 nedoporučujeme vykreslování pomocí metod, které spoléhají na rozhraní, jako je ID2D1HwndRenderTarget, protože nebudou fungovat s aplikacemi pro Windows Store. Kontext zařízení můžete použít k vykreslení do Hwnd, pokud chcete vytvořit desktopovou aplikaci a zároveň využívat další funkce kontextu zařízení . Kontext zařízení je však nutný k vykreslení obsahu v aplikacích pro Windows Store pomocí Direct2D.

Proč k vykreslení použít kontext zařízení?

  • Můžete vykreslit aplikace pro Windows Store.
  • Cíl vykreslení můžete kdykoli změnit před vykreslováním, během a po vykreslení. Kontext zařízení zajišťuje, že se volání metod kreslení spustí podle pořadí a použijí se při přepnutí cíle vykreslování.
  • V kontextu zařízení můžete použít více než jeden typ okna. Můžete použít kontext zařízení a DXGI řetěz prohození k přímému vykreslení do Windows::UI::Core::CoreWindow nebo Windows::UI::XAML::SwapChainBackgroundPanel.
  • Kontext zařízení Direct2D můžete použít k vytvoření efektů Direct2D a k vykreslení výstupu obrazového efektu nebo efektového grafu na cílový objekt vykreslování.
  • Můžete mít více kontextů zařízení , což může být užitečné pro zlepšení výkonu ve vícevláknové aplikaci. Další informace najdete v tématu vícevláknové aplikace Direct2D.
  • Kontext zařízení úzce spolupracuje s Direct3D a poskytuje více přístupu k možnostem Direct3D.

Vytvoření kontextu zařízení Direct2D pro vykreslování

Tento kód ukazuje, jak vytvořit zařízení Direct3D11, získat přidružené zařízení DXGI, vytvořit zařízení Direct2Da nakonec vytvořit kontext zařízení Direct2D pro vykreslování.

Tady je diagram volání metody a rozhraní, která tento kód používá.

diagram direct2d a direct3d zařízení a kontextů zařízení.

Poznámka

Tento kód předpokládá, že již máte objekt ID2D1Factory1. Další informace najdete na referenční stránce ID2D1Factory.

 

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

Pojďme si projít kroky v předchozí ukázce kódu.

  1. Získejte ukazatel rozhraní ID3D11Device, který budete potřebovat k vytvoření kontextu zařízení.

    • Deklarujte příznaky vytváření pro nastavení zařízení Direct3D pro podporu BGRA. direct2D vyžaduje pořadí barev BGRA.

    • Deklarujte pole položek D3D_FEATURE_LEVEL představující sadu úrovní funkcí, které bude vaše aplikace podporovat.

      Poznámka

      Direct3D prohledá seznam, dokud nenajde úroveň funkce podporovanou hostitelským systémem.

       

    • Pomocí funkce D3D11CreateDevice vytvořte objekt ID3D11Device objekt, vrátí funkce také ID3D11DeviceContext objekt, ale tento objekt není v tomto příkladu potřeba.

  2. Zeptejte se zařízení Direct3D 11 na jeho rozhraní DXGI Device .

  3. Vytvořte objekt ID2D1Device voláním metody ID2D1Factory::CreateDevice a předáním objektu IDXGIDevice.

  4. Vytvořte ukazatel ID2D1DeviceContext pomocí metody ID2D1Device::CreateDeviceContext.

Výběr cíle

Tento kód ukazuje, jak získat 2rozměrnou texturu Direct3D pro zpětný vyrovnávací paměťový prostor okna a vytvořit bitmapový cíl, který odkazuje na tuto texturu, na kterou vykresluje kontext zařízení Direct2D .

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

Pojďme si projít kroky v předchozím příkladu kódu.

  1. Přidělte strukturu DXGI_SWAP_CHAIN_DESC1 a definujte nastavení pro swap chain .

    Tato nastavení ukazují příklad vytvoření swap řetězce, který může aplikace pro Windows Store používat.

  2. Získejte adaptér, na kterém běží zařízení Direct3D a zařízení DXGI, a získejte objekt IDXGIFactory, který je k nim přidružený. Musíte použít tuto továrnu DXGI k zajištění, že swap řetězce je vytvořen na stejném adaptéru.

  3. Zavolejte metodu IDXGIFactory2::CreateSwapChainForCoreWindow k vytvoření swap chainu. Použijte třídu Windows::UI::CoreWindow pro hlavní okno aplikace pro Windows Store.

    Pokud chcete minimalizovat spotřebu energie, nezapomeňte nastavit maximální latenci rámce na 1.

    Pokud chcete vykreslit obsah Direct2D v aplikaci pro Windows Store, podívejte se na metodu CreateSwapChainForComposition.

  4. Získejte zpětnou vyrovnávací paměť ze swap řetězce . Zadní vyrovnávací paměť zveřejňuje rozhraní ID3D11Texture2D přidělené řetězu prohození

  5. Deklarujte D2D1_BITMAP_PROPERTIES1 strukturu a nastavte hodnoty vlastností. Nastavte formát pixelu na BGRA, protože to je formát, který používají zařízení Direct3D a DXGI.

  6. Získejte zadní vyrovnávací paměť jako IDXGISurface pro předávání do Direct2D. Direct2D nepřijímá přímo ID3D11Texture2D.

    Vytvořte objekt ID2D1Bitmap z výstupního bufferu pomocí metody ID2D1DeviceContext::CreateBitmapFromDxgiSurface.

  7. Nyní je bitmapa Direct2D propojená se zadní vyrovnávací pamětí. Nastavte cíl v kontextu zařízení Direct2D na rastrový obrázek .

Vykreslení a zobrazení

Teď, když máte cílový rastrový obrázek, můžete do něj kreslit primitivy, obrázky, efekty obrázků a text pomocí kontextu zařízení Direct2D. V tomto kódu se dozvíte, jak nakreslit obdélník.

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

Pojďme si projít kroky v předchozím příkladu kódu.

  1. Zavolejte CreateSolidColorBrush, abyste vytvořili štětec pro vyplnění obdélníku.
  2. Před vydáním jakýchkoli příkazů výkresu volejte metodu BeginDraw.
  3. Zavolejte metodu DrawRectangle pro obdélník, který se má nakreslit, a štětec.
  4. Po dokončení vydávání příkazů kreslení volejte metodu EndDraw.
  5. Zobrazte výsledek voláním metody IDXGISwapChain::Present.

Nyní můžete použít kontext zařízení Direct2D k nakreslení primitiv, obrázků, obrazových efektů a textu na obrazovku.