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

Direct2D — это API прямого кода для создания двухD-графики. В этом разделе показано, как использовать 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 структуры, определяет параметры удаленного отображения, указывает, следует ли принудительно преобразовать целевой объект отрисовки в программное или аппаратное обеспечение, а также разрешение на дюйм. Код в этом примере использует вспомогательную функцию 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