Direct2D中资源的创建顺序

资源类型

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也可以顺利被创建。

你可能感兴趣的:(DI)