Краткое руководство по Direct2D
Direct2D — это API родного кода с непосредственным режимом для создания 2D-графики. В этом разделе показано, как использовать Direct2D в типичном приложении Win32 для рисования на HWND.
Примечание
Если вы хотите создать приложение Магазина Windows, использующее Direct2D, ознакомьтесь с кратким руководством по Direct2D для Windows 8.
В этом разделе содержатся следующие разделы:
- рисование простого прямоугольника
- Шаг 1: Включение заголовка Direct2D
- шаг 2. Создание ID2D1Factory
- шаг 3. Создайте объект ID2D1HwndRenderTarget
- Шаг 4: Создайте кисть
- шаг 5. Рисование прямоугольника
- шаг 6. Выпуск ресурсов
- создание простого приложения Direct2D
- связанные темы
Чтобы нарисовать прямоугольник с помощью 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 аналогичен: он создает ресурсы рисования, описывает фигуру для рисования, рисует фигуру, а затем освобождает ресурсы рисования. В разделах, приведенных ниже, подробно описаны все эти шаги.
Помимо заголовков, необходимых для приложения Win32, включите заголовок d2d1.h.
Одним из первых действий, которые выполняет любой пример Direct2D, является создание ID2D1Factory.
ID2D1Factory* pD2DFactory = NULL;
HRESULT hr = D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
&pD2DFactory
);
ИнтерфейсID2D1Factory является отправной точкой для использования Direct2D; используйте ID2D1Factory для создания ресурсов Direct2D.
При создании фабрики можно указать, является ли она многопоточной или однопоточной. (Дополнительные сведения о многопоточных фабриках см. в примечаниях на справочной странице ID2D1Factory.) В этом примере создается однопоточная фабрика.
В общем случае приложение должно создать фабрику один раз и сохранить ее в течение всего времени существования приложения.
После создания фабрики используйте ее для создания целевого объекта отрисовки.
// 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. При получении этой ошибки необходимо повторно создать целевой объект отрисовки (и все созданные ресурсы).
Как и фабрика, объект рендеринга может создавать ресурсы для рисования. В этом примере рендер-таргет создает кисть.
ID2D1SolidColorBrush* pBlackBrush = NULL;
if (SUCCEEDED(hr))
{
pRT->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black),
&pBlackBrush
);
}
Кисть — это объект, который рисует область, например штрих или заливку формы. Кисть в этом примере красит область с предопределенным сплошным цветом, черным.
Direct2D также предоставляет другие типы кистей: градиентные кисти для рисования линейных и радиальных градиентов, а также битовую кисть для рисования с растровыми изображениями и шаблонами.
Некоторые API рисования предоставляют ручки для рисования контуров и кистей для заполнения фигур. Direct2D отличается: он не предоставляет объект пера, но использует кисть для рисования контуров и заливки фигур. При рисовании контуров используйте интерфейс ID2D1StrokeStyle с кистью для управления операциями нанесения штрихов на пути.
Кисть может использоваться только с целевым объектом отрисовки, создавшим его, и с другими целевыми объектами отрисовки в том же ресурсном домене. Как правило, кисти следует создавать один раз и сохранять на протяжении всего времени существования рендеринг-цели, которая их создала. ID2D1SolidColorBrush является исключением. так как это относительно недорого для создания, вы можете создать ID2D1SolidColorBrush каждый раз, когда вы рисуете кадр, без каких-либо заметных ударов по производительности. Вы также можете использовать один ID2D1SolidColorBrush и просто изменять его цвет при каждом использовании.
Затем используйте целевой объект отрисовки для рисования прямоугольника.
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, указывающий, были ли команды рисования успешными.
Если нет больше кадров для рисования или при получении ошибки D2DERR_RECREATE_TARGET, отпустите целевой объект отрисовки и все созданные устройства.
SafeRelease(pRT);
SafeRelease(pBlackBrush);
Когда ваше приложение завершит работу с ресурсами Direct2D (например, когда оно собирается завершить работу), освободите фабрику Direct2D.
SafeRelease(pD2DFactory);
В коде этого раздела показаны основные элементы приложения Direct2D. Для краткости в этом разделе опущены упоминания о платформе приложений и коде обработки ошибок, которые характерны для хорошо написанного приложения. Более подробное пошаговое руководство по созданию простого приложения Direct2D и демонстрация рекомендаций по проектированию см. в статье Создание простого приложения Direct2D.