如何使用 Direct2D-DirectWrite 连接 DirectX11 中的后备缓冲区?

How to Connect the backbuffer in DirectX11 using Direct2D-DirectWrite?

如何使用 Direct2D-DirectWrite 在 DirectX11 中连接后台缓冲区?

如何使用 Direct2D-DriectWrite 连接 Dx11 中的 bacbuffer

大家好。

当我使用Direct2D时,可以将DriectWrite连接到Direct2D并写入二维字符。 但在 Dx11 中,似乎无法将 DirectWrite 连接到 Dx11 框架。所以我创建了其他 Direct2D RanderTarget 来绘制二维字符。但在这个解决方案中,fps 直线下降到一半,然后崩溃。所以我需要另一个解决方案 这可以在 Dx11 框架中使用 DriectWrite 吗?

这是我的 Direct2D 初始化函数 ID2D1RenderTarget 和 ID2D1Factory 值

extern ID2D1RenderTarget* Rendtrg;
extern ID2D1Factory* factory;
extern IDXGISurface* pBackBuffer;


//Create BackBuffer
{
    HRESULT hr;

    ID3D11Texture2D* BackBuffer;
    hr = SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer);
    assert(SUCCEEDED(hr));

    hr = Device->CreateRenderTargetView(BackBuffer, NULL, &RTV);
    assert(SUCCEEDED(hr));
    BackBuffer->Release();

    DeviceContext->OMSetRenderTargets(1, &RTV, NULL);
}


//Initailize Direct2D Funtion
HRESULT hr;

hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, factory);

if (FAILED(hr))
    return hr;

hr = SwapChain->GetBuffer(
    0,
    IID_PPV_ARGS(&pBackBuffer)
);

FLOAT dpiX;
FLOAT dpiY;
(*factory)->GetDesktopDpi(&dpiX, &dpiY);

D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties
(
    D2D1_RENDER_TARGET_TYPE_DEFAULT,
    D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
    dpiX,
    dpiY
);

hr = (*factory)->CreateDxgiSurfaceRenderTarget
(
    pBackBuffer,
    &props,
    Rt
);

全局声明(包含在头文件中):

ID2D1RenderTarget* D2DRenderTarget;
IDWriteFactory* DwriteFactory;
ID2D1Factory* D2D1Factory;
IDWriteTextFormat* TextFormat;

CreateD2D() 函数

bool D3D::CreateD2D()
{
    HWND hwnd = getHWND();
    float height, width;
    height = getWindowHeight();
    width = getWindowWidth();

    HRESULT result = S_OK;
    D2D1_SIZE_U size = D2D1::SizeU(width, height);

    // And lets create our D2D factory and DWrite factory at this point as well, that way if any of them fail we'll fail out completely.
    auto options = D2D1_FACTORY_OPTIONS();
    options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
    result = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, options, &D2D1Factory);
    if (FAILED(result)) {
        return false;
    }

    result = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&DwriteFactory));
    if (FAILED(result)) {
        return false;
    }

    if (getDeviceSwapchain() == nullptr)
        return false;

    CComPtr<IDXGISurface1> d2dRT;
    result = getDeviceSwapchain()->GetBuffer(0, IID_PPV_ARGS(&d2dRT));
    if (FAILED(result))
    {
        return false;
    }

    auto d2dRTProps = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), 0, 0);
    result = D2D1Factory->CreateDxgiSurfaceRenderTarget(d2dRT, &d2dRTProps, &D2DRenderTarget);

    if (FAILED(result))
    {
        return false;
    }

    return true;
}

是的,您必须创建一个 D2DRendertarget。我的是 DXGIRenderTarget。然后在你的 D3D11->ClearRenderTargets 函数之后,你将有一个在渲染任何文本或任何东西之前清除你的 D2D 渲染目标。

渲染例程:

  1. 清除您的 D3D11 渲染目标。

  2. 清除您的 D2D1 渲染目标。

        D2DRenderTarget->Clear(D2D1::ColorF(red, green, blue, alpha));
    
  3. 渲染文本、方块、图像等等。

  4. 结束您的 D2D1 渲染。

     D2DRenderTarget->EndDraw();
    
  5. 最后,展示你的D3D11。

     D3DSwapchain->Present(0,0);
    

此外,Microsoft 提供了很多关于如何将 D3D 与 D2D1 交织的有用指示。还有,如何渲染图像和文本。