Aracılığıyla paylaş


Direct2D cihaz bağlamını kullanarak nasıl işleme yapılır

Bu konuda, Windows 8'de Direct2Dcihaz bağlamı oluşturma hakkında bilgi edinacaksınız. Bu bilgiler, Direct2D kullanarak Windows Mağazası uygulamaları veya masaüstü uygulaması geliştiriyorsanız sizin için geçerlidir. Bu konu başlığında Direct2D cihaz bağlam nesnelerinin amacı, bu nesnenin nasıl oluşturulacağı ve Direct2D temel öğelerini ve görüntülerini işleme ve görüntüleme hakkında adım adım kılavuz açıklanmaktadır. İşleme hedeflerini değiştirme ve uygulamanıza efekt ekleme hakkında da bilgi edineceksiniz.

Direct2D cihazı nedir?

Direct2D cihaz bağlamı oluşturmak için bir Direct2D cihazına ve Direct3D cihazına ihtiyacınız vardır. Direct2D aygıt (ID2D1Device arabirim işaretçisini sunarak) bir görüntü bağdaştırıcısını temsil eder. Direct3D aygıtı (ID3D11Aygıt arabirim işaretçisini gösterir) bir Direct2D aygıtıyla ilişkilendirilir. Her uygulamanın birDirect2D cihazı olmalıdır, ancak birden fazlacihazı olabilir.

Direct2D cihaz bağlamı nedir?

Direct2Dcihaz bağlamı, (ID2D1DeviceContext arabirim işaretçisini sunar) hedefe işlemek için kullandığınız durum ve komut arabellekleri kümesini temsil eder. İşlem hattı durumunu ayarlamak ve bir cihazın sahip olduğu kaynakları kullanarak işleme komutları oluşturmak için cihaz bağlamında yöntemleri çağırabilirsiniz.

Windows 8'de Direct2D ile işleme

Windows 7 ve önceki sürümlerde, bir pencereye veya yüzeye işlemek için ID2D1HwndRenderTarget veya başka bir işleme hedef arabirimi kullanırsınız. Windows 8'den başlayarak, ID2D1HwndRenderTarget gibi arabirimleri kullanan yöntemleri kullanarak işleme yapmanızı önermeyiz çünkü bunlar Windows Mağazası uygulamalarıyla çalışmaz. Bir masaüstü uygulaması oluşturmak ve cihaz bağlamının ek özelliklerinden yararlanmaya devam etmek istiyorsanız, Hwnd'a işlemek için cihaz bağlamı kullanabilirsiniz. Ancak, cihaz bağlamıDirect2Dile bir Windows Mağazası uygulamalarında içerik işlemek için gereklidir.

İşlemek için neden bir cihaz bağlamı kullanmalısınız?

İşleme için Direct2D cihaz bağlamı oluşturma

Buradaki kodda Direct3D11 cihazı oluşturma, ilişkili DXGI cihazını alma,direct2D cihazı oluşturma ve son olarak işleme için Direct2D cihaz bağlamı oluşturma gösterilmektedir.

Burada yöntem çağrılarının ve bu kodun kullandığı arabirimlerin diyagramı yer alır.

Direct2d ve Direct3d cihazları ve cihaz bağlamları diyagramı .

Not alın

Bu kodda zaten id2D1Factory1bir nesneniz olduğu varsayılır. Daha fazla bilgi için ID2D1Factory başvuru sayfasınabakın.

 

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

Yukarıdaki kod örneğindeki adımları inceleyelim.

  1. Bir ID3D11Device arabirimi işaretçisi alın; cihaz bağlamını oluşturmak için buna ihtiyacınız olacak.

    • BGRA desteğine uygun Direct3D donanımını ayarlamak için oluşturma ayarlarını belirtin. Direct2D BGRA renk sırası gerektirir.

    • Uygulamanızın destekleyeceği özellik düzeyleri kümesini temsil eden bir D3D_FEATURE_LEVEL girdileri dizisi bildirin.

      Not

      Direct3D, ana bilgisayar sistemi tarafından desteklenen özellik düzeyini bulana kadar listenizde arar.

       

    • ID3D11Device nesnesi oluşturmak için D3D11CreateDevice işlevini kullanın; işlev ayrıca bir ID3D11DeviceContext nesnesi döndürür, ancak bu örnek için bu nesne gerekli değildir.

  2. Direct3D 11 cihazınıDXGI Cihaz arabirimi için sorgula.

  3. ID2D1Factory::CreateDevice yöntemini çağırıp IDXGIDevice nesnesini geçirerek ID2D1Device nesnesi oluşturun.

  4. ID2D1Device::CreateDeviceContext yöntemini kullanarak bir ID2D1DeviceContext işaretçisi oluşturun.

Hedef seçme

Buradaki kod, pencere arka arabelleği için 2 boyutlu Direct3D doku nasıl edinebileceğinizi ve Direct2D cihaz bağlamı işlenen bu dokuya bağlanan bir bit eşlem hedefi oluşturmayı gösterir.

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

Önceki kod örneğindeki adımları inceleyelim.

  1. DXGI_SWAP_CHAIN_DESC1 bir yapı ayırın vetakas zincirinin ayarlarını tanımlayın.

    Bu ayarlar, bir Windows Mağazası uygulamasının kullanabileceği bir takas zincirinin nasıl oluşturulacağını gösteren bir örnek gösterir.

  2. Direct3D cihazı ve DXGI Cihazı üzerinde çalışıyorsa, o bağdaştırıcıyı alın ve onlarla ilişkilendirilmiş olan IDXGIFactory nesnesini alın. Bu DXGI fabrikasını, takas zincirinin aynı bağdaştırıcı üzerinde oluşturulduğundan emin olmak için kullanmanız gerekir.

  3. Takas zincirini oluşturmak için IDXGIFactory2::CreateSwapChainForCoreWindow yöntemini çağırın. Windows Mağazası uygulamasının ana penceresi için Windows::UI::CoreWindow sınıfını kullanın.

    Güç tüketimini en aza indirmek için maksimum kare gecikme süresini 1 olarak ayarladığınızdan emin olun.

    Direct2D içeriğini bir Windows Mağazası uygulamasında işlemek istiyorsanız CreateSwapChainForComposition yöntemine bakın.

  4. takas zinciri'den geri arabelleği alın. Arka arabellek, takas zinciri tarafından ayrılan ID3D11Texture2D arayüzünü gözler önüne serer

  5. bir D2D1_BITMAP_PROPERTIES1 yapısı bildirin ve özellik değerlerini ayarlayın. BGRA olarak piksel biçimini ayarlayın çünkü bu, Direct3D cihazı ve DXGI cihazı tarafından kullanılan biçimdir.

  6. Direct2D'ye geçirmek için IDXGISurface olarak geri arabelleği alın. Direct2D, ID3D11Texture2D'ü doğrudan kabul etmez.

    ID2D1DeviceContext::CreateBitmapFromDxgiSurface yöntemini kullanarak arka arabellekten bir ID2D1Bitmap nesnesi oluşturun.

  7. Artık Direct2D bit eşlem arka arabelleğe bağlıdır. Hedefi bitmapüzerinde Direct2D cihaz bağlamı olarak ayarlayın.

İşleme ve görüntüleme nasıl yapılır

Elinizde bir hedef bit eşlem olduğuna göre, Direct2D cihaz bağlamıkullanarak temel öğeler, resimler, resim efektleri ve metin çizebilirsiniz. Buradaki kod, dikdörtgen çizmeyi gösterir.

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

Önceki kod örneğindeki adımları inceleyelim.

  1. Dikdörtgeni boyamak için bir fırça oluşturmak için CreateSolidColorBrushçağırın.
  2. Herhangi bir çizim komutu vermeden önce BeginDraw yöntemini çağırın.
  3. Çizilecek dikdörtgeni ve fırçayı DrawRectangle yöntemini çağırın.
  4. Çizim komutlarını yazmayı bitirdikten sonra EndDraw yöntemini çağırın.
  5. IDXGISwapChain::Present yöntemini çağırarak sonucu görüntüleyin.

Artık Direct2D cihaz bağlamını kullanabilir ekrana temel öğeler, görüntüler, görüntü efektleri ve metinler çizebilirsiniz.