资源类型
Direct2D中有两种类型的资源,设备无关资源和设备相关资源,设备无关的资源可以一次创建,永久使用(在程序生存期内),且通常创建于系统内存中,设备相关的资源和设备有相同的生命周期,一旦设备丢失,则资源也需重建。这类资源一般在显存中创建。
设备无关的资源包括
- ID2D1DrawingStateBlock
- ID2D1Factory
- ID2D1Geometry及继承自它的接口
- ID2D1GeometrySink和ID2D1SimplifiedGeometrySink
- ID2D1StrokeStyle
设备相关的资源包括
- ID2D1Brush及继承自它的接口
- ID2D1Layer
- ID2D1RenderTarget及继承自它的接口
创建顺序
通常来说,先创建设备无关的资源,再创建设备相关的资源,因为ID2D1Factory是设备无关的资源,也是所有其他D2D资源的创建者。包括ID2D1RenderTarget。
一个案例
先看下面的代码,这段代码创建窗口,然后调用函数CreateDeviceIndependentResources创建设备无关的资源,其中包括ID2D1Factory。
HWND hwnd = CreateWindowEx(NULL,
L"DirectWrite Hello, World", // window class name
L"Draw Text", // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
600, // initial x size
600, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
CreateDeviceIndependentResources(hwnd);
下面这段代码响应WM_PAINT消息,调用Render函数来绘制字体。
switch (message)
{
case WM_PAINT:
Render(hwnd);
ValidateRect(hwnd, NULL) ;
return 0 ;
Render函数中调用CreateDeviceDependentResources,该函数创建设备相关的资源,包括ID2D1RenderTarget。
VOID Render(HWND hwnd)
{
// Create device dependent resources
CreateDeviceDependentResources(hwnd);
g_pRT->BeginDraw();
g_pRT->SetTransform(D2D1::IdentityMatrix());
g_pRT->Clear(D2D1::ColorF(D2D1::ColorF::White));
DrawText(hwnd);
g_pRT->EndDraw();
}
这段代码是有问题的,因为CreateDeviceDependentResources在CreateDeviceIndependentResources之前被调用了,这是因为在调用函数UpdateWindow时,系统就发出了WM_PAINT消息,从而激发Render函数被调用,继而CreateDeviceDependentResources函数被调用。但是这时CreateDeviceIndependentResources还未被调用,所以导致ID2D1Factory还不存在的时候,ID2D1RenderTarget就要创建,这肯定是错误的,因为后者是由前者创建的。
修复
将CreateDeviceIndependentResources放到函数UpdateWindow之前调用。这样,在UpdateWindw函数发出WM_PAINT消息时,ID2D1Factory已经创建好了,所以ID2D1RenderTarget也可以顺利被创建。
http://www.cnblogs.com/graphics/archive/2012/09/15/2686125.html