How do you draw text in DirectX 12?
Asked Answered
M

5

7

This is a follow-up question of How do you draw text in DirectX 11?

In Direct3D-12, things got much more complex and since it's new I couldn't find any suitable libraries online.

I'm building a basic Direct3D12 FPS Test application, and I like to display the FPS data on screen with my rendered image.

Millennium answered 4/4, 2016 at 4:31 Comment(0)
P
9

The general answer to questions like this is "if you have to ask, then you probably should be using DirectX 11." DirectX 12 is a graphics expert API that provide immense control, and is not particularly concerned with ease-of-use for novices. See this thread for more thoughts in this vein.

With that out of the way, one option is to use device interop and Direct2D/DirectWrite. See Working with Direct3D 11, Direct3D 10 and Direct2D.

UPDATE: DirectX Tool Kit for DirectX 12 is now available. It includes a SpriteFont / SpriteBatch implementation that will draw text on Direct3D 12 render targets. See this tutorial.

Poly answered 4/4, 2016 at 5:48 Comment(0)
L
4

Pure DirectX 12, then you need to load the font glyph data into a vertex buffer and render with a vertex shader and pixel shader. You mentioned libraries online, will this is expert stuff and fortunately James Stanard at Microsoft release a how to with their open source MiniEngine project. He handles multiple fonts, antialiasing, and drop shadows in DirectX 12.

Find the project files at GitHub https://github.com/Microsoft/DirectX-Graphics-Samples/tree/master/MiniEngine and check out Textrender.h and Textrender.cpp

Leclair answered 14/6, 2016 at 1:28 Comment(0)
C
1

If you want maximum feature set with minimum work you probably should go with DirectWrite on top of a D3D11 interop device, like Chuck said in his answer.

If you want to roll your own high performance text rendering you may want to take a look at the text renderer in the miniengine example repository on github, it has some interesting ideas.

Crifasi answered 13/5, 2016 at 21:18 Comment(0)
D
-1

Unfortunately the only ways have already been described. Interface with DirectWrite or create your glyph file system.

What you are doing is importing a texture file with glyphs on it, cutting out small squares around each character from the glyph texture file, and then gluing it all together to form a string. It results in some faster drawing (in some case).

I think the approach to this as referenced by the others is slightly outdated and destined to fail. Direct3D11 had the same lack of text drawing support as Direct3D12 (perhaps misinformation on that). It was Direct3D9 which had the built in text drawing support, which nonetheless worked fine, and later supported sprite batch drawing where you could render all text in one sprite.

It seems backwards to state that you simply "need to know" or "are not an expert" to implement such a basic yet tedious system. Such a system is destined to fail in the same way why no one wants to use Assembly to code something they can code in C and onward.

The D3D11 and D3D12 math library also suffers from the same failures. To define and convert vectors you are better off including D3D9X math or custom math structures because the newer methods included are so backwards. "Someone" made it and must like it, but I remember making a complaint showing how easy it is to do vector operations before vs afterward, it nearly doubles or triples the amount of lines needed to perform basic vectors operation and conversions, not even counting the amount of references and learning time you would need to see how someone else's lib works. It seems to be a big failure presented by mathematicians who were never good at programming.

Duck answered 14/7, 2017 at 22:16 Comment(0)
M
-1

Drawing text in DirectX 12 is incredibly difficult compared to earlier versions.

I present the refactored text rendering code from DirectX Tool Kit (aka DirectXTK12). I chose this ToolKit because I think it is the most popular among beginners, and my code can be useful to more people.

Everything unnecessary has been removed, connections have been "straightened" to flat code, all options have been removed, asynchrony has been removed, only for Windows. Headers only, no global variables, no external dependencies, macro-free. Tested for memory and resource leaks. The depth of the call stack is no more than two, so as not to get lost. Many variable names have been retained and many old comments remain; this will help people who know ToolKit navigate the code.

There is usage.cpp in the repository as a complete and working example of use. The example code is also chosen to be as simple as possible; this is the minimum possible set of calls to launch shaders. The author of the code in which text drawing is built in is PrzemyslawZaworski, thanks to him.

The usage consists of two calls:

  1. To initialize a context object:
    auto ctx = Plain::fontWorks( mDevice, mCommandQueue );
  1. To display text in a frame using context:
    auto holder = Plain::drawWorks( ctx, text );

the returned result of drawWorks must be saved until the current drawing cycle completes.

The text can be displayed in the desired coordinates and selected color, deeper one call: you can change the scale and all those things that the DrawString function from DirectXTK12 provided. A hardcoded font of the Arial family is used, size 28, generated via DirectXTK12\MakeSpriteFont.exe, included as a header with a data array.

I like to display the FPS data on screen with my rendered image

The text in the example outputs FPS as stated in the question.

Here is the entire project in the repo https://github.com/Alex0vSky/MinimalDx12DrawText

Great for educational purposes due to its flatness and simplicity. I wonder how complex DirectX 13 will become...

Mellman answered 18/10, 2023 at 20:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.