1
votes

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

How to connect bacbuffer in Dx11 with Direct2D-DriectWrite

Hello guys.

When I used Direct2D, It was possible to connect DriectWrite to Direct2D and write 2d characters. But in Dx11, it seems unable to connect DirectWrite to Dx11 framework. So I create other Direct2D RanderTarget to draw 2d characters. but in this solution fps plummeted to half, and crashes. so i need another solution Is this possible to use DriectWrite in Dx11 framwork?

Here is my Direct2D Init Function ID2D1RenderTarget & ID2D1Factory Value

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
);
1

1 Answers

1
votes

Global Declarations (included in header file):

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

CreateD2D() function

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;
}

Yes, you're going to have to create a D2DRendertarget. Mine is DXGIRenderTarget. Then after your D3D11->ClearRenderTargets function, you're going to have a to clear your D2D Render Target before rendering any text or whatever.

Rendering routine:

  1. Clear your D3D11 Render Target.

  2. Clear Your D2D1 Render Target.

        D2DRenderTarget->Clear(D2D1::ColorF(red, green, blue, alpha));
    
  3. Render text, squares, images, whatever.

  4. End Your D2D1 Rendering.

     D2DRenderTarget->EndDraw();
    
  5. Finally, Present your D3D11.

     D3DSwapchain->Present(0,0);
    

Also, Microsoft gives a lot of helpful pointers on how to interlope D3D with D2D1. Also, how to render images and text as well.