Поделиться через


Обзор целевых объектов отрисовки

Целевой объект отрисовки — это ресурс, который наследуется от интерфейса ID2D1RenderTarget . Целевой объект отрисовки создает ресурсы для рисования и выполняет фактические операции рисования. В этом разделе описываются различные типы целевых объектов отрисовки Direct2D и способы их использования.

Отрисовка целевых объектов

Целевой объект отрисовки — это ресурс, который наследуется от интерфейса ID2D1RenderTarget . Целевой объект отрисовки создает ресурсы для рисования и выполняет фактические операции рисования. Существует несколько типов целевых объектов отрисовки, которые можно использовать для отрисовки графики следующими способами:

  • Объекты ID2D1HwndRenderTarget отображают содержимое в окне.
  • Объекты ID2D1DCRenderTarget отображаются в контексте устройства GDI.
  • Точечного рисунка целевые объекты отображают содержимое в растровом рисунке вне экрана.
  • Отрисовка целевых объектов DXGI отрисовывается на поверхности DXGI для использования с Direct3D.

Так как целевой объект отрисовки связан с определенным устройством отрисовки, он является ресурсом, зависящим от устройства, и перестает работать при удалении устройства.

Отрисовка целевых функций

Вы можете указать, использует ли целевой объект отрисовки аппаратное ускорение и отображается ли удаленный дисплей на локальном или удаленном компьютере. Целевые объекты отрисовки можно настроить для отрисовки с псевдонимом или с антиалиазной отрисовкой. Для отрисовки сцен с большим количеством примитивов разработчик может также отрисовывать двухмерную графику в режиме псевдонима и использовать d3D сглаживание с несколькими шаблонами для достижения большей масштабируемости.

Целевые объекты отрисовки также могут группировать операции рисования в слои, представленные интерфейсом ID2D1Layer . Слои полезны для сбора операций рисования, которые необходимо объединить при отрисовке кадра. В некоторых сценариях это может быть полезной альтернативой отрисовке целевого объекта отрисовки растрового изображения, а затем повторного использования содержимого растрового рисунка, так как затраты на распределение на слои ниже, чем для ID2D1BitmapRenderTarget.

Целевые объекты отрисовки могут создавать новые целевые объекты отрисовки, совместимые с самими собой, что полезно для промежуточной отрисовки за кадром, сохраняя при этом различные свойства целевого объекта отрисовки, заданные в исходном объекте.

Кроме того, можно выполнить отрисовку с помощью GDI в целевом объекте отрисовки Direct2D, вызвав QueryInterface в целевом объекте отрисовки для ID2D1GdiInteropRenderTarget, который содержит методы GetDC и ReleaseDC , которые можно использовать для получения контекста устройства GDI. Отрисовка через GDI возможна только в том случае, если целевой объект отрисовки был создан с установленным флагом D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE . Это полезно для приложений, которые в основном отрисовываются с помощью Direct2D, но имеют модель расширяемости или другое устаревшее содержимое, требующее возможности отрисовки с помощью GDI. Дополнительные сведения см. в статье Общие сведения о взаимодействии Direct2D и GDI.

Отрисовка целевых ресурсов

Как и фабрика, целевой объект отрисовки может создавать ресурсы рисования. Все ресурсы, созданные целевым объектом отрисовки, зависят от устройства (как и целевой объект отрисовки). Целевой объект отрисовки может создавать следующие типы ресурсов:

  • Растровые изображения
  • Кисти
  • Слои
  • Сетки

Команды рисования

Для отрисовки содержимого используются методы рисования целевых объектов. Перед началом рисования вызовите метод ID2D1RenderTarget::BeginDraw . Завершив рисование, вызовите метод ID2D1RenderTarget::EndDraw . Между этими вызовами используются методы Draw и Fill для отрисовки ресурсов рисования. Большинство методов рисования и заливки принимают форму (примитивную или геометрическую) и кисть для заполнения или структурирования фигуры.

Целевые объекты отрисовки предоставляют методы для обрезки, применения масок непрозрачности и преобразования координатного пространства.

Direct2D использует левую систему координат: положительные значения оси X переходит вправо, а положительные значения оси Y — вниз.

Обработка ошибок

Команды отрисовки целевого рисунка не указывают, была ли запрошена операция успешной. Чтобы узнать, есть ли ошибки рисования, вызовите метод Flush целевого объекта отрисовки или метод EndDraw , чтобы получить HRESULT.

Пример. Отрисовка содержимого в окно

В следующем примере используется метод CreateHwndRenderTarget для создания 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
    );

В следующем примере для рисования текста в окне используется ID2D1HwndRenderTarget .

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

Код в этом примере опущен.