呈现目标、设备和资源
呈现目标只是程序将要绘制的位置。 通常,呈现目标是窗口(特别是窗口的客户端区域)。 它也可以是内存中未显示的位图。 呈现目标由 ID2D1RenderTarget 接口表示。
设备是一种抽象概念,表示实际绘制像素的任何内容。 硬件设备使用 GPU 来提高性能,而软件设备则使用 CPU。 应用程序不会创建设备。 而是在应用程序创建呈现目标时隐式创建设备。 每个呈现器目标都与特定设备(硬件或软件)相关联。
资源是程序用于绘图的对象。 下面是 Direct2D 中定义的一些资源示例:
- Brush。 控制绘制线条和区域的方式。 画笔类型包括纯色画笔和渐变画笔。
- 笔划样式。 控制线条的外观,例如虚线或实线。
- Geometry。 表示线条和曲线的集合。
- Mesh。 由三角形构成的形状。 网格数据可以直接由 GPU 使用,这与几何图形数据不同,在呈现之前必须转换这些数据。
呈现目标也被视为一种资源类型。
某些资源受益于硬件加速。 此类型的资源始终与特定设备(硬件 (GPU) 或软件 (CPU))相关联。 这种类型的资源称为依赖于设备的资源。 画笔和网格是依赖于设备的资源的示例。 如果设备不可用,则必须为新设备重新创建资源。
无论使用什么设备,其他资源都会保留在 CPU 内存中。 这些资源与设备无关,因为它们不与特定设备关联。 当设备发生更改时,无需重新创建独立于设备的资源。 笔划样式和几何图形是独立于设备的资源。
每个资源的 Windows 文档都指出资源是依赖于设备还是独立于设备。 每个资源类型都由派生自 ID2D1Resource 的接口表示。 例如,画笔由 ID2D1Brush 接口表示。
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 接口的指针。
您应在第一条 WM_PAINT 消息之前创建 Direct2D 工厂对象。 WM_CREATE 消息处理程序是创建工厂的好位置:
case WM_CREATE:
if (FAILED(D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory)))
{
return -1; // Fail CreateWindowEx.
}
return 0;
创建 Direct2D 资源
Circle 程序使用以下依赖于设备的资源:
- 与应用程序窗口相关联的呈现目标。
- 用于绘制圆圈的纯色画笔。
每个资源都由 COM 接口表示:
- ID2D1HwndRenderTarget 接口表示呈现目标。
- ID2D1SolidColorBrush 接口表示画笔。
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;
}
若要为窗口创建呈现目标,请在 Direct2D 工厂上调用 ID2D1Factory::CreateHwndRenderTarget 方法。
- 第一个参数指定任何类型的呈现目标都通用的选项。 在这里,我们通过调用帮助程序函数 D2D1::RenderTargetProperties 传递默认选项。
- 第二个参数指定窗口的句柄以及呈现目标的大小(以像素为单位)。
- 第三个参数接收 ID2D1HwndRenderTarget 指针。
若要创建纯色画笔,请在呈现目标上调用 ID2D1RenderTarget::CreateSolidColorBrush 方法。 颜色以 D2D1_COLOR_F 值的形式提供。 有关 Direct2D 中的颜色的详细信息,请参阅 在 Direct2D 中使用颜色。
此外请注意,如果呈现目标已存在,CreateGraphicsResources
该方法将返回 S_OK 而不执行任何操作。 此设计的原因将在下一主题中阐明。
下一步