Panoramica delle destinazioni di rendering

Una destinazione di rendering è una risorsa che eredita dall'interfaccia ID2D1RenderTarget . Una destinazione di rendering crea risorse per il disegno ed esegue operazioni di disegno effettive. Questo argomento descrive i diversi tipi di destinazioni di rendering Direct2D e come usarli.

Destinazioni di rendering

Una destinazione di rendering è una risorsa che eredita dall'interfaccia ID2D1RenderTarget . Una destinazione di rendering crea risorse per il disegno ed esegue operazioni di disegno effettive. Esistono diversi tipi di destinazioni di rendering che possono essere usate per eseguire il rendering della grafica nei modi seguenti:

  • Gli oggetti ID2D1HwndRenderTarget eseguono il rendering del contenuto in una finestra.
  • Rendering degli oggetti ID2D1DCRenderTarget in un contesto di dispositivo GDI.
  • Gli oggetti di destinazione di rendering bitmap eseguono il rendering del contenuto in una bitmap fuori schermo.
  • DxGI esegue il rendering degli oggetti di destinazione in una superficie DXGI da usare con Direct3D.

Poiché una destinazione di rendering è associata a un dispositivo di rendering specifico, è una risorsa dipendente dal dispositivo e smette di funzionare se il dispositivo viene rimosso.

Funzionalità di destinazione di rendering

È possibile specificare se una destinazione di rendering usa l'accelerazione hardware e se il rendering dello schermo remoto viene eseguito da un computer locale o remoto. Le destinazioni di rendering possono essere configurate per il rendering con alias o antialiased. Per il rendering di scene con un numero elevato di primitive, uno sviluppatore può anche eseguire il rendering di grafica 2D in modalità con alias e usare l'anti-aliasing D3D per ottenere una maggiore scalabilità.

Le destinazioni di rendering possono anche raggruppare le operazioni di disegno in livelli rappresentati dall'interfaccia ID2D1Layer . I livelli sono utili per raccogliere le operazioni di disegno da comporre insieme durante il rendering di un frame. Per alcuni scenari, questo può essere un'alternativa utile per il rendering a una destinazione di rendering bitmap e quindi riusare il contenuto della bitmap, in quanto i costi di allocazione per il layering sono inferiori a quelli di un OGGETTO ID2D1BitmapRenderTarget.

Le destinazioni di rendering possono creare nuove destinazioni di rendering compatibili con se stesse, utili per il rendering intermedio dello schermo, mantenendo al tempo stesso le varie proprietà di destinazione di rendering impostate sull'originale.

È anche possibile eseguire il rendering usando GDI in una destinazione di rendering Direct2D chiamando QueryInterface su una destinazione di rendering per ID2D1GdiInteropRenderTarget, che dispone di metodi GetDC e ReleaseDC su di esso che possono essere usati per recuperare un contesto di dispositivo GDI. Il rendering tramite GDI è possibile solo se la destinazione di rendering è stata creata con il flag D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE impostato. Ciò è utile per le applicazioni che eseguono principalmente il rendering con Direct2D, ma hanno un modello di estendibilità o altri contenuti legacy che richiedono la possibilità di eseguire il rendering con GDI. Per altre informazioni, vedere Panoramica dell'interoperabilità Direct2D e GDI.

Eseguire il rendering delle risorse di destinazione

Analogamente a una factory, una destinazione di rendering può creare risorse di disegno. Tutte le risorse create da una destinazione di rendering sono risorse dipendenti dal dispositivo (proprio come la destinazione di rendering). Una destinazione di rendering può creare i tipi di risorse seguenti:

  • Bitmap
  • Pennelli
  • Livelli
  • Mesh

Comandi di disegno

Per eseguire il rendering del contenuto, utilizzare i metodi di disegno di destinazione di rendering. Prima di iniziare a disegnare, chiamare il metodo ID2D1RenderTarget::BeginDraw . Al termine del disegno, chiamare il metodo ID2D1RenderTarget::EndDraw . Tra queste chiamate si usano i metodi Draw e Fill per eseguire il rendering delle risorse di disegno. La maggior parte dei metodi Draw e Fill accetta una forma (una primitiva o una geometria) e un pennello per riempire o delineare la forma.

Le destinazioni di rendering forniscono metodi per ritagliare, applicare maschere di opacità e trasformare lo spazio delle coordinate.

Direct2D usa un sistema di coordinate sinistrorso: i valori positivi dell'asse x procedono verso destra e i valori positivi dell'asse y proseguono verso il basso.

Gestione degli errori

I comandi di disegno di destinazione di rendering non indicano se l'operazione richiesta ha avuto esito positivo. Per verificare se sono presenti errori di disegno, chiamare il metodo Flush della destinazione di rendering o EndDraw per ottenere un valore HRESULT.

Esempio: Eseguire il rendering del contenuto in una finestra

Nell'esempio seguente viene utilizzato il metodo CreateHwndRenderTarget per creare un oggetto ID2D1HwndRenderTarget.

RECT rc;
GetClientRect(m_hwnd, &rc);

D2D1_SIZE_U size = D2D1::SizeU(
    rc.right - rc.left,
    rc.bottom - rc.top
    );

// Create a Direct2D render target.
hr = m_pD2DFactory->CreateHwndRenderTarget(
    D2D1::RenderTargetProperties(),
    D2D1::HwndRenderTargetProperties(m_hwnd, size),
    &m_pRenderTarget
    );

Nell'esempio seguente viene usato ID2D1HwndRenderTarget per disegnare testo nella finestra.

//  Called whenever the application needs to display the client
//  window. This method writes "Hello, World"
//
//  Note that this function will automatically discard device-specific
//  resources if the Direct3D device disappears during function
//  invocation, and will recreate the resources the next time it's
//  invoked.
//
HRESULT DemoApp::OnRender()
{
    HRESULT hr;

    hr = CreateDeviceResources();

    if (SUCCEEDED(hr))
    {
        static const WCHAR sc_helloWorld[] = L"Hello, World!";

        // Retrieve the size of the render target.
        D2D1_SIZE_F renderTargetSize = m_pRenderTarget->GetSize();

        m_pRenderTarget->BeginDraw();

        m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());

        m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));

        m_pRenderTarget->DrawText(
            sc_helloWorld,
            ARRAYSIZE(sc_helloWorld) - 1,
            m_pTextFormat,
            D2D1::RectF(0, 0, renderTargetSize.width, renderTargetSize.height),
            m_pBlackBrush
            );

        hr = m_pRenderTarget->EndDraw();

        if (hr == D2DERR_RECREATE_TARGET)
        {
            hr = S_OK;
            DiscardDeviceResources();
        }
    }

    return hr;
}

Il codice è stato omesso da questo esempio.