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


Краткое руководство по Direct2D

Direct2D — это API родного кода с непосредственным режимом для создания 2D-графики. В этом разделе показано, как использовать Direct2D в типичном приложении Win32 для рисования на HWND.

Заметка

Если вы хотите создать приложение Магазина Windows, использующее Direct2D, ознакомьтесь с кратким руководством по Direct2D для Windows 8.

 

В этом разделе содержатся следующие разделы:

Рисование простого прямоугольника

Чтобы нарисовать прямоугольник с помощью GDI, можно обработать сообщение WM_PAINT, как показано в следующем коде.

switch(message)
{

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            BeginPaint(hwnd, &ps);

            // Obtain the size of the drawing area.
            RECT rc;
            GetClientRect(
                hwnd,
                &rc
            );          

            // Save the original object
            HGDIOBJ original = NULL;
            original = SelectObject(
                ps.hdc,
                GetStockObject(DC_PEN)
            );

            // Create a pen.            
            HPEN blackPen = CreatePen(PS_SOLID, 3, 0);

            // Select the pen.
            SelectObject(ps.hdc, blackPen);

            // Draw a rectangle.
            Rectangle(
                ps.hdc, 
                rc.left + 100, 
                rc.top + 100, 
                rc.right - 100, 
                rc.bottom - 100);   

            DeleteObject(blackPen);

            // Restore the original object
            SelectObject(ps.hdc, original);

            EndPaint(hwnd, &ps);
        }
        return 0;

// Code for handling other messages. 

Код для рисования одного прямоугольника с Direct2D аналогичен: он создает ресурсы рисования, описывает фигуру для рисования, рисует фигуру, а затем освобождает ресурсы рисования. В разделах, приведенных ниже, подробно описаны все эти шаги.

Шаг 1. Включите заголовок Direct2D

Помимо заголовков, необходимых для приложения Win32, включите заголовок d2d1.h.

Шаг 2. Создание ID2D1Factory

Одним из первых действий, которые выполняет любой пример Direct2D, является создание ID2D1Factory.

ID2D1Factory* pD2DFactory = NULL;
HRESULT hr = D2D1CreateFactory(
    D2D1_FACTORY_TYPE_SINGLE_THREADED,
    &pD2DFactory
    );

ИнтерфейсID2D1Factory является отправной точкой для использования Direct2D; используйте ID2D1Factory для создания ресурсов Direct2D.

При создании фабрики можно указать, является ли она многопоточной или однопоточной. (Дополнительные сведения о многопоточных фабриках см. в примечаниях на справочной странице ID2D1Factory.) В этом примере создается однопоточная фабрика.

В общем случае приложение должно создать фабрику один раз и сохранить ее в течение всего времени существования приложения.

Шаг 3. Создание ID2D1HwndRenderTarget

После создания фабрики используйте ее для создания целевого объекта отрисовки.



// Obtain the size of the drawing area.
RECT rc;
GetClientRect(hwnd, &rc);

// Create a Direct2D render target          
ID2D1HwndRenderTarget* pRT = NULL;          
HRESULT hr = pD2DFactory->CreateHwndRenderTarget(
    D2D1::RenderTargetProperties(),
    D2D1::HwndRenderTargetProperties(
        hwnd,
        D2D1::SizeU(
            rc.right - rc.left,
            rc.bottom - rc.top)
    ),
    &pRT
);

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

По возможности целевой объект отрисовки использует GPU для ускорения операций отрисовки и создания ресурсов рисования. В противном случае целевой объект отрисовки использует ЦП для обработки инструкций по отрисовке и создания ресурсов. (Это поведение можно изменить с помощью флагов D2D1_RENDER_TARGET_TYPE при создании целевого объекта отрисовки.)

Метод createHwndRenderTargetпринимает три параметра. Первый параметр, D2D1_RENDER_TARGET_PROPERTIES структуры, указывает параметры удаленного отображения, следует ли принудительно отображать целевой объект отрисовки на программное обеспечение или оборудование, а также DPI. Код в этом примере использует D2D1::RenderTargetProperties вспомогательную функцию для принятия свойств целевых объектов отрисовки по умолчанию.

Второй параметр, структуру D2D1_HWND_RENDER_TARGET_PROPERTIES, указывает HWND, в которую отображается содержимое, начальный размер целевого объекта отрисовки (в пикселях) и параметров презентации. В этом примере вспомогательная функция D2D1::HwndRenderTargetProperties используется для указания HWND и начального размера. В нем используются параметры презентации по умолчанию.

Третий параметр — это адрес указателя, который получает целевую ссылку на отрисовку.

При создании целевого объекта отрисовки и аппаратного ускорения вы выделяете ресурсы на GPU компьютера. Создав целевой объект отрисовки один раз и сохраняя его как можно дольше, вы получаете преимущества производительности. Приложение должно создавать целевые объекты отрисовки один раз и удерживать их на протяжении всего времени работы приложения или до получения сообщения об ошибке D2DERR_RECREATE_TARGET. При получении этой ошибки необходимо повторно создать целевой объект отрисовки (и все созданные ресурсы).

Шаг 4. Создание кисти

Как и фабрика, объект рендеринга может создавать ресурсы для рисования. В этом примере рендер-таргет создает кисть.

ID2D1SolidColorBrush* pBlackBrush = NULL;
if (SUCCEEDED(hr))
{
            
    pRT->CreateSolidColorBrush(
        D2D1::ColorF(D2D1::ColorF::Black),
        &pBlackBrush
        ); 
}

Кисть — это объект, который рисует область, например штрих или заливку формы. Кисть в этом примере красит область с предопределенным сплошным цветом, черным.

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

Некоторые API рисования предоставляют ручки для рисования контуров и кистей для заполнения фигур. Direct2D отличается: он не предоставляет объект пера, но использует кисть для рисования контуров и заливки фигур. При рисовании контуров используйте интерфейс ID2D1StrokeStyle с кистью для управления операциями нанесения штрихов на пути.

Кисть может использоваться только с целевым объектом отрисовки, создавшим его, и с другими целевыми объектами отрисовки в том же ресурсном домене. Как правило, кисти следует создавать один раз и сохранять на протяжении всего времени существования рендеринг-цели, которая их создала. ID2D1SolidColorBrush является исключением. так как это относительно недорого для создания, вы можете создать ID2D1SolidColorBrush каждый раз, когда вы рисуете кадр, без каких-либо заметных ударов по производительности. Вы также можете использовать один ID2D1SolidColorBrush и просто изменять его цвет при каждом использовании.

Шаг 5. Рисование прямоугольника

Затем используйте целевой объект отрисовки для рисования прямоугольника.

 
pRT->BeginDraw();

pRT->DrawRectangle(
    D2D1::RectF(
        rc.left + 100.0f,
        rc.top + 100.0f,
        rc.right - 100.0f,
        rc.bottom - 100.0f),
        pBlackBrush);

HRESULT hr = pRT->EndDraw();  

Метод DrawRectangle принимает два параметра: прямоугольник для рисования, а также кисть, которая будет использоваться для рисования контура прямоугольника. При необходимости можно также указать ширину штриха, шаблон дефиса, соединение линии и конечные параметры крышки.

Перед выполнением команд рисования необходимо вызвать метод BeginDraw, и после завершения выполнения команд рисования необходимо вызвать метод EndDraw. Метод EndDraw возвращает HRESULT, указывающий, были ли команды рисования успешными.

Шаг 6. Выпуск ресурсов

Если нет больше кадров для рисования или при получении ошибки D2DERR_RECREATE_TARGET, отпустите целевой объект отрисовки и все созданные устройства.

 
SafeRelease(pRT);
SafeRelease(pBlackBrush);

Когда ваше приложение завершит работу с ресурсами Direct2D (например, когда оно собирается завершить работу), освободите фабрику Direct2D.

 
SafeRelease(pD2DFactory);

Создание простого приложения Direct2D

В коде этого раздела показаны основные элементы приложения Direct2D. Для краткости в этом разделе опущены упоминания о платформе приложений и коде обработки ошибок, которые характерны для хорошо написанного приложения. Более подробное пошаговое руководство по созданию простого приложения Direct2D и демонстрация рекомендаций по проектированию см. в статье Создание простого приложения Direct2D.

создание простого приложения Direct2D