Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render text in directx9 with stb_truetype?

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.

like image 539
cYeR Avatar asked Jul 11 '18 02:07

cYeR


People also ask

Is there a way to render a font in DirectX?

You could create a bitmap font render, which can ranged from "very simple" to "very complicated". For a simple way, there is this example, that although is in Managed DirectX, can easily be done in C++/DirectX 9. Bitmap Fonts.

Can imgui use STB_TrueType for font rendering?

Bookmark this question. Show activity on this post. Since ImGui builds on top of stb_truetype for its font rendering, I thought it could be nicer to use its already built font-processing capabilities ( ImGui::GetIO ().Fonts ), and render with those, instead of using stb_truetype directly.

What is STB_TrueType?

A header-only library for rendering text in pure SDL2 with STB_Truetype. This caches glyphs as they are drawn allowing for fast text rendering. It also provides a couple of easy ways to render a string to texture for even faster text rendering. New (2021)! Can also render in bgfx with bgfxFrontend.h!

How to create a text texture from a bitmap?

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.


1 Answers

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;
}
like image 122
mnistic Avatar answered Oct 03 '22 04:10

mnistic