c++ - 如何使用 stb_truetype 在 directx9 中渲染文本?

标签 c++ c directx directx-9

如何在 C/C++ 中使用 D3D9 使用 stb_truetype 库渲染文本?我在各种论坛/站点和图书馆的文档中查看了 d3d9 中的一些示例,但没有找到任何示例。

最佳答案

执行此操作的一种方法是创建 D3D9 纹理,然后将渲染的文本位图加载到其中。然后,您可以像使用任何其他纹理一样使用生成的纹理。

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

关于c++ - 如何使用 stb_truetype 在 directx9 中渲染文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51276586/

相关文章:

关于 if 语句和 strcmp 与字符串的混淆

python - 使用 fgets 导致缓冲区溢出

c++ - D3DXMatrixTransformation2D 行为怪异

c++ - 从模板文件生成代码

c++ - 从 fstream 读取整行,包括空格

c - 错误 :request for member 'id' in something not a structure or union

c++ - 纹理不适用于我的 3d Cube directX

C++ 返回语句奇怪的行为?

c++ - 寻找高级 C++ SSL 库

directx - Direct3D:从 IDirect3DSurface9(默认池)获取系统内存位图的有效方法?