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

Целевой объект отрисовки — это просто расположение, в котором будет рисовать программа. Как правило, целевым объектом отрисовки является окно (в частности, клиентская область окна). Это также может быть растровое изображение в памяти, которое не отображается. Целевой объект отрисовки представлен интерфейсом ID2D1RenderTarget .

Устройство — это абстракция, представляющая то, что на самом деле рисует пиксели. Аппаратное устройство использует GPU для повышения производительности, а программное устройство использует ЦП. Приложение не создает устройство. Вместо этого устройство создается неявно, когда приложение создает целевой объект отрисовки. Каждый целевой объект отрисовки связан с определенным устройством, либо с оборудованием, либо с программным обеспечением.

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

Ресурс — это объект, который программа использует для рисования. Ниже приведены некоторые примеры ресурсов, определенных в Direct2D:

  • Кисть. Управляет способом нарисовки линий и областей. Типы кистей включают кисти сплошного цвета и градиентные кисти.
  • Стиль штриха. Управляет внешним видом линии, например пунктирной или сплошной.
  • Геометрия. Представляет коллекцию линий и кривых.
  • Сетка. Фигура, сформированная из треугольников. Данные сетки могут использоваться непосредственно GPU, в отличие от геометрических данных, которые необходимо преобразовать перед отрисовкой.

Целевые объекты отрисовки также считаются типом ресурса.

Некоторые ресурсы выигрывают от аппаратного ускорения. Ресурс этого типа всегда связан с определенным устройством, либо с оборудованием (GPU) или программным обеспечением (ЦП). Этот тип ресурса называется зависимым от устройства. Кисти и сетки — это примеры ресурсов, зависящих от устройства. Если устройство становится недоступным, ресурс необходимо создать повторно для нового устройства.

Другие ресурсы хранятся в памяти ЦП независимо от используемого устройства. Эти ресурсы не зависят от устройства, так как они не связаны с определенным устройством. При изменении устройства нет необходимости повторно создавать ресурсы, независимые от устройства. Стили и геометрии штрихов являются независимыми от устройств ресурсами.

В документации MSDN по каждому ресурсу указывается, является ли ресурс зависимым от устройства или независимым от устройства. Каждый тип ресурса представлен интерфейсом, производным от ID2D1Resource. Например, кисти представлены интерфейсом ID2D1Brush .

Объект фабрики Direct2D

Первым шагом при использовании Direct2D является создание экземпляра объекта фабрики Direct2D. В компьютерном программировании фабрика — это объект, который создает другие объекты. Фабрика Direct2D создает следующие типы объектов:

  • Отрисовка целевых объектов.
  • Независимые от устройства ресурсы, такие как стили штрихов и геометрические объекты.

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

Схема, показывающая фабрику direct2d.

Чтобы создать объект фабрики Direct2D, вызовите функцию D2D1CreateFactory .

ID2D1Factory *pFactory = NULL;

HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory);

Первый параметр — это флаг, указывающий параметры создания. Флаг D2D1_FACTORY_TYPE_SINGLE_THREADED означает, что вы не будете вызывать Direct2D из нескольких потоков. Чтобы поддерживать вызовы из нескольких потоков, укажите D2D1_FACTORY_TYPE_MULTI_THREADED. Если программа использует один поток для вызова Direct2D, вариант с одним потоком будет более эффективным.

Второй параметр функции D2D1CreateFactory получает указатель на интерфейс ID2D1Factory .

Необходимо создать объект фабрики Direct2D до первого сообщения WM_PAINT . Обработчик сообщений WM_CREATE является хорошим местом для создания фабрики:

    case WM_CREATE:
        if (FAILED(D2D1CreateFactory(
                D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory)))
        {
            return -1;  // Fail CreateWindowEx.
        }
        return 0;

Создание ресурсов Direct2D

Программа Circle использует следующие зависимые от устройства ресурсы:

  • Целевой объект отрисовки, связанный с окном приложения.
  • Сплошная кисть для рисования круга.

Каждый из этих ресурсов представлен COM-интерфейсом:

Программа Circle хранит указатели на эти интерфейсы в виде переменных-членов MainWindow класса :

ID2D1HwndRenderTarget   *pRenderTarget;
ID2D1SolidColorBrush    *pBrush;

В следующем коде создаются эти два ресурса.

HRESULT MainWindow::CreateGraphicsResources()
{
    HRESULT hr = S_OK;
    if (pRenderTarget == NULL)
    {
        RECT rc;
        GetClientRect(m_hwnd, &rc);

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

        hr = pFactory->CreateHwndRenderTarget(
            D2D1::RenderTargetProperties(),
            D2D1::HwndRenderTargetProperties(m_hwnd, size),
            &pRenderTarget);

        if (SUCCEEDED(hr))
        {
            const D2D1_COLOR_F color = D2D1::ColorF(1.0f, 1.0f, 0);
            hr = pRenderTarget->CreateSolidColorBrush(color, &pBrush);

            if (SUCCEEDED(hr))
            {
                CalculateLayout();
            }
        }
    }
    return hr;
}

Чтобы создать целевой объект отрисовки для окна, вызовите метод ID2D1Factory::CreateHwndRenderTarget в фабрике Direct2D.

  • Первый параметр задает параметры, общие для любого типа целевого объекта отрисовки. Здесь мы передадим параметры по умолчанию, вызвав вспомогащую функцию D2D1::RenderTargetProperties.
  • Второй параметр указывает дескриптор окна плюс размер целевого объекта отрисовки в пикселях.
  • Третий параметр получает указатель ID2D1HwndRenderTarget .

Чтобы создать сплошную кисть, вызовите метод ID2D1RenderTarget::CreateSolidColorBrush в целевом объекте отрисовки. Цвет задается в виде значения D2D1_COLOR_F . Дополнительные сведения о цветах в Direct2D см. в разделе Использование цвета в Direct2D.

Кроме того, обратите внимание, что если целевой объект отрисовки уже существует, CreateGraphicsResources метод возвращает S_OK без каких-либо действий. Причина такого дизайна станет ясной в следующем разделе.

Следующая

Рисование с использованием Direct2D