Render Targets Overview

A render target is a resource that inherits from the ID2D1RenderTarget interface. A render target creates resources for drawing and performs actual drawing operations. This topic describes the different types of Direct2D render targets and how to use them.

Render Targets

A render target is a resource that inherits from the ID2D1RenderTarget interface. A render target creates resources for drawing and performs actual drawing operations. There are several kinds of render targets that can be used to render graphics in the following ways:

  • ID2D1HwndRenderTarget objects render content to a window.
  • ID2D1DCRenderTarget objects render to a GDI device context.
  • Bitmap render target objects render content to an off-screen bitmap.
  • DXGI render target objects render to a DXGI surface for use with Direct3D.

Because a render target is associated with a particular rendering device, it is a device-dependent resource and ceases to function if the device is removed.

Render Target Features

You can specify whether a render target uses hardware acceleration and whether remote display is rendered by a local or a remote computer. Render targets can be set up for aliased or antialiased rendering. For rendering scenes with a large number of primitives, a developer can also render 2-D graphics in aliased mode and use D3D multisample antialiasing to achieve greater scalability.

Render targets can also group drawing operations into layers represented by the ID2D1Layer interface. Layers are useful for collecting drawing operations to be composited together when rendering a frame. For some scenarios, this can be a useful alternative to rendering to a bitmap render target, and then reusing the bitmap contents, as allocation costs for layering are lower than for an ID2D1BitmapRenderTarget.

Render targets can create new render targets that are compatible with themselves, which is useful for intermediate off-screen rendering while retaining the various render-target properties that were set on the original.

It is also possible to render using GDI on a Direct2D render target by calling QueryInterface on a render target for ID2D1GdiInteropRenderTarget, which has GetDC and ReleaseDC methods on it that can be used to retrieve a GDI device context. Rendering via GDI is possible only if the render target was created with the D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE flag set. This is useful for applications that are primarily rendering with Direct2D but have an extensibility model or other legacy content that requires the ability to render with GDI. For more information, see the Direct2D and GDI Interoperation Overview.

Render Target Resources

Like a factory, a render target can create drawing resources. Any resources created by a render target are device-dependent resources (just like the render target). A render target can create the following types of resources:

  • Bitmaps
  • Brushes
  • Layers
  • Meshes

Drawing Commands

To render content, you use the render target drawing methods. Before you begin drawing, you call the ID2D1RenderTarget::BeginDraw method. After you finished drawing, you call the ID2D1RenderTarget::EndDraw method. Between these calls, you use Draw and Fill methods to render drawing resources. Most Draw and Fill methods take a shape (either a primitive or a geometry) and a brush for filling or outlining the shape.

Render targets provide methods for clipping, applying opacity masks, and transforming the coordinate space.

Direct2D uses a left-handed coordinate system: positive x-axis values proceed to the right and positive y-axis values proceed downward.

Error Handling

Render target drawing commands do not indicate whether the requested operation was successful. To find out whether there are drawing errors, call the render target Flush method or EndDraw method to obtain an HRESULT.

Example: Render Content to a Window

The following example uses the CreateHwndRenderTarget method to create an 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
    );

The next example uses the ID2D1HwndRenderTarget to draw text to the window.

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

Code has been omitted from this example.