How to render a text with the stb_truetype library using D3D9 in C/C++? I looked in various forums/sites and in the library's documentation for some example in d3d9 and I didn't find any example.
Asked
Active
Viewed 3,341 times
10
-
2The general answer to all questions of the form "How do I do X with Direct3D 9?" is: *Don't use Direct3D 9, use Direct3D 11 instead*. It's legacy and there's basically no reason to use it at all. See [MSDN](https://learn.microsoft.com/en-us/windows/desktop/directx-sdk--august-2009-) and [this blog post](https://blogs.msdn.microsoft.com/chuckw/2015/08/05/where-is-the-directx-sdk-2015-edition/) – Chuck Walbourn Jul 28 '18 at 17:54
1 Answers
5
One way to do this would be to create a D3D9 texture and then load the rendered text bitmap into it. You can then use the generated texture like any other texture.
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"
IDirect3DTexture9 *LoadTextureFromText(const char *text)
{
IDirect3DTexture9 *d3dTexture = 0;
/* load font file */
long size;
unsigned char* fontBuffer;
FILE* fontFile = fopen("C:\\path\\to\\font.ttf", "rb");
fseek(fontFile, 0, SEEK_END);
size = ftell(fontFile); /* how long is the file ? */
fseek(fontFile, 0, SEEK_SET); /* reset */
fontBuffer = (unsigned char*)malloc(size);
fread(fontBuffer, size, 1, fontFile);
fclose(fontFile);
/* prepare font */
stbtt_fontinfo info;
if (!stbtt_InitFont(&info, fontBuffer, 0))
{
printf("failed\n");
}
int b_w = 512; /* bitmap width */
int b_h = 128; /* bitmap height */
int l_h = 64; /* line height */
/* create a bitmap for the phrase */
unsigned char* bitmap = (unsigned char*)calloc(b_w * b_h, sizeof(unsigned char));
/* calculate font scaling */
float scale = stbtt_ScaleForPixelHeight(&info, l_h);
int x = 0;
int ascent, descent, lineGap;
stbtt_GetFontVMetrics(&info, &ascent, &descent, &lineGap);
ascent *= scale;
descent *= scale;
int i;
for (i = 0; i < strlen(text); ++i)
{
/* get bounding box for character (may be offset to account for chars that dip above or below the line */
int c_x1, c_y1, c_x2, c_y2;
stbtt_GetCodepointBitmapBox(&info, text[i], scale, scale, &c_x1, &c_y1, &c_x2, &c_y2);
/* compute y (different characters have different heights */
int y = ascent + c_y1;
/* render character (stride and offset is important here) */
int byteOffset = x + (y * b_w);
stbtt_MakeCodepointBitmap(&info, bitmap + byteOffset, c_x2 - c_x1, c_y2 - c_y1, b_w, scale, scale, text[i]);
/* how wide is this character */
int ax;
stbtt_GetCodepointHMetrics(&info, text[i], &ax, 0);
x += ax * scale;
/* add kerning */
int kern;
kern = stbtt_GetCodepointKernAdvance(&info, text[i], text[i + 1]);
x += kern * scale;
}
//Create a D3D9 texture and load the generated image. The text bitmap is 1 channel.
D3DXCreateTexture(direct3DDevice, b_w, b_h, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, (LPDIRECT3DTEXTURE9*)&d3dTexture);
D3DLOCKED_RECT rect;
d3dTexture->LockRect(0, &rect, NULL, 0);
memcpy(rect.pBits, bitmap, b_w * b_h);
d3dTexture->UnlockRect(0);
free(fontBuffer);
free(bitmap);
return d3dTexture;
}

mnistic
- 10,866
- 2
- 19
- 33
-
Your example helped me a lot, but I'm having a problem, I'm using ID3DXSprite to draw the texture, the text is drawing, but with a black box, why is this happening? Am I doing it wrong? Code(sorry for posting link, the code is too big to post in the comments): ```paste.ofcode.org/bZ7dwEwqHGdj8KG2xLMSGK``` – cYeR Jul 15 '18 at 05:27
-
You didn't provide full code, I don't know who calls print_text or how the sprite was created. I'm no directx expert but I can take a look if you provide all the code. – mnistic Jul 15 '18 at 12:00
-
D3DX9, D3DX10, and D3DX11 are all deprecated. You should move to using DirectX 11 instead, in which case you can use the ``SpriteFont`` class in the [DirectX Tool Kit](https://github.com/Microsoft/DirectXTK/wiki/Getting-Started) which is open source. See [Living without D3DX](https://blogs.msdn.microsoft.com/chuckw/2013/08/20/living-without-d3dx/). Note that if very high-quality and scalable text is important to you, then you should consider using Direct3D 11 with [DirectWrite](https://learn.microsoft.com/en-us/windows/desktop/DirectWrite/direct-write-portal). – Chuck Walbourn Jul 28 '18 at 17:56