microsoft / DirectXTK12

The DirectX Tool Kit (aka DirectXTK12) is a collection of helper classes for writing DirectX 12 code in C++
https://walbourn.github.io/directx-tool-kit-for-directx-12/
MIT License
1.47k stars 393 forks source link

Drawing text #68

Closed shoshiberko closed 4 years ago

shoshiberko commented 4 years ago

I tried to use DirectXTK12 in order to draw text in Directx12. The text is actually drawn, but the problem is that the memory increases, with each execution of the line: m_spriteBatch->End(); In the Render code, until eventually the program crashes. Your help will be much appreciated @walbourn .

My code:

Init the font once:

HRESULT CGrDxDevice::InitFonts()
{

    if(m_graphicsMemory==nullptr)//singelton, initializes only in the first time, --------need to be thread safe
        m_graphicsMemory = std::make_unique <DirectX::GraphicsMemory>(m_D3dDevice.Get());
    m_resourceDescriptors = std::make_unique<DescriptorHeap>(m_D3dDevice.Get(),
                                                                D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
                                                                D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
                                                                Descriptors::Count);

    ResourceUploadBatch resourceUpload(m_D3dDevice.Get());

    resourceUpload.Begin();

    m_font = std::make_unique<SpriteFont>(m_D3dDevice.Get(), resourceUpload, 
        L"\\Fonts\\myfile.spritefont", //L"myfile.spritefont",
        m_resourceDescriptors->GetCpuHandle(Descriptors::MyFont),
        m_resourceDescriptors->GetGpuHandle(Descriptors::MyFont));

    RenderTargetState rtState(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_D32_FLOAT);

    SpriteBatchPipelineStateDescription pd(rtState);
    m_spriteBatch = std::make_unique<SpriteBatch>(m_D3dDevice.Get(), resourceUpload, pd);

    auto uploadResourcesFinished = resourceUpload.End(m_CommandQueue.Get());
    uploadResourcesFinished.wait();

    //In Game.cpp, add to the TODO of CreateResources:
    D3D12_VIEWPORT viewport = { 0.0f, 0.0f,
    static_cast<float>(m_ViewPort.Width), static_cast<float>(m_ViewPort.Height),
    D3D12_MIN_DEPTH, D3D12_MAX_DEPTH };
    m_spriteBatch->SetViewport(viewport);

    //m_fontPos.x = viewport.Width / 2.f;
    //m_fontPos.y = viewport.Height / 2.f;
    return S_OK;
}

Render

BOOL CGrDxDevice::DrawD3DFontText(DWORD fontID,const CString& text,float x,float y,float z,D3DCOLOR color,DWORD flags /*= 0*/)
{

    ////fonts--------------s
    D3D12_VIEWPORT viewport = { 0.0f, 0.0f,
                                static_cast<float>(m_ViewPort.Width), static_cast<float>(m_ViewPort.Height),
                                D3D12_MIN_DEPTH, D3D12_MAX_DEPTH };

    m_spriteBatch->SetViewport(viewport);

    ID3D12DescriptorHeap* heaps[] = { m_resourceDescriptors->Heap() };
    m_CommandList->SetDescriptorHeaps(_countof(heaps), heaps);

    m_spriteBatch->Begin(m_CommandList.Get());

    DirectX::SimpleMath::Vector2 origin = m_font->MeasureString(text) / 2.f;

    //color
    XMFLOAT4 xm_color(GetRValue(color), GetGValue(color), GetBValue(color), 1);////alpha
    XMVECTOR vec_color= XMLoadFloat4(&xm_color);

    XMVECTOR position = XMVectorSet(x, y, z, 1.0f);
    DirectX::SimpleMath::Vector2 fontPos(0, 0); 

    //DirectX::SimpleMath::Vector2 m_fontPos;
    m_font->DrawString(m_spriteBatch.get(), text,
                        fontPos, vec_color/*Colors::White*/, 0.f, origin);

    m_spriteBatch->End();
    ////fonts--------------e

    return TRUE;
}

In destructor destroys font's elements :

//fonts----s
m_font.reset();
m_resourceDescriptors.reset();
m_spriteBatch.reset();
m_graphicsMemory.reset();
//fonts----e

The BUG:

image

image

walbourn commented 4 years ago

Many of the DirectX Tool Kit classes rely on GraphicsMemory to manage temporary space for dynamic submission.

The most likely cause is that you are failing to call Commit on the GraphicsMemory instance after your Present. See the wiki.

shoshiberko commented 4 years ago

Thank you @walbourn, it works!!! In the same issue, when the spriteFont in size 10, the font's quality in the render image isn't good, is there a way to do it better?

walbourn commented 4 years ago

Raster fonts generally require you pick a size that's a good match for your resolution.

If you need higher quality text drawing, you should look at Direct2D/DirectWrite interop which is a vector-font solution.