首页 > 解决方案 > 如何使用 Direct2D-DirectWrite 连接 DirectX11 中的后台缓冲区?

问题描述

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

如何将 Dx11 中的 bacbuffer 与 Direct2D-DriectWrite 连接

大家好。

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

这是我的 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
);

标签: cdirectx-11direct2d

解决方案


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

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 相互连接提供了许多有用的指示。另外,如何渲染图像和文本。


推荐阅读