4

我最近刚刚开始使用 FreeType 库并开始尝试从缓冲区复制到 directx9 纹理。

尽管从通过加载单个字符创建的缓冲区复制,但我目前正在出现双字母,如下所示:

在此处输入图像描述

[尝试复制字符'a']

以下是我当前的代码:

void TexFont::freeTypeSave()
{
    static FT_Library  library;   /* handle to library     */
    static FT_Face     face;      /* handle to face object */

    if (FT_Init_FreeType(&library)) {
        NHelper::OutputDebugStringN("error");
    }

    if (FT_New_Face(library,TEXT("Fonts\\arial.ttf"),0,&face)) {
        NHelper::OutputDebugStringN("font load failed\n");
    }
    else {
        //NHelper::OutputDebugStringN("font faces: %d \n", face->num_faces);
    }

    static int error;
    static UINT width, height;
    static int mTtfSize = 64;
    static int mTtfResolution = 96;

    static IDirect3DTexture9* mTexture;
    static unsigned int mPixelBytes = 2;
    static unsigned int mDataSize = width * height * mPixelBytes;

    // size settings (convert font size to *64)
    FT_F26Dot6 ftSize = (FT_F26Dot6)(mTtfSize * (1 << 6));
    error=FT_Set_Char_Size(face, ftSize, 0, mTtfResolution, mTtfResolution);

    // load glyph + render
    error = FT_Load_Char( face, L'a', FT_LOAD_RENDER );
    if (error) 
        NHelper::OutputDebugStringN("could not load char");

    // start copy procedure
    width = face->glyph->bitmap.width;
    height = face->glyph->bitmap.rows;

    D3DXCreateTexture(
        g_engine->getDevice(),
        width, height,
        1, 0,
        D3DFMT_A8L8, D3DPOOL_MANAGED,
        &mTexture);

    D3DLOCKED_RECT lockedRect;
    mTexture->LockRect(0, &lockedRect,0, 0);   

    unsigned char* pSrcPixels = face->glyph->bitmap.buffer;
    unsigned char* pDestPixels = (unsigned char*)lockedRect.pBits;

    for(UINT i = 0; i < height; ++i)
    {
        //copy a row
        memcpy(pDestPixels, pSrcPixels, width * 2); //2 bytes per pixel (1byte alpha, 1byte greyscale)

        //advance row pointers
        pSrcPixels += face->glyph->bitmap.pitch;
        pDestPixels += lockedRect.Pitch;
    }
    NHelper::OutputDebugStringN("char width: %d, height: %d \n", width, height);

    mTexture->UnlockRect(0);

    D3DXSaveTextureToFileA("test.png",D3DXIFF_PNG, mTexture, 0);

    // release face
    FT_Done_Face(face);

    // library shutdown
    FT_Done_FreeType(library);
}

关于正在发生的事情以及如何解决此问题的任何想法?

注意:更改字体大小只会创建更大的图像。我仍然得到相同的结果。

- 更新 -

尝试 Drop 的建议,我尝试改变我的memcpy(pDestPixels, pSrcPixels, width * 2);

它返回memcpy(pDestPixels, pSrcPixels, width * 1);以下内容:

在此处输入图像描述

一个字形挤在图像的左侧,但图像的大小保持不变。(字形只占图像空间的一半)

4

1 回答 1

1

您将字符加载为

FT_Load_Char( face, L'a', FT_LOAD_RENDER );

意味着

默认情况下,字形以FT_RENDER_MODE_NORMAL模式呈现

FT_RENDER_MODE_NORMAL这是默认的渲染模式;它对应于 8 位抗锯齿位图。

但是你复制为 16 位:

memcpy(pDestPixels, pSrcPixels, width * 2); //2 bytes per pixel (1byte alpha, 1byte greyscale)

您真的不需要任何字符中的灰度组件来进行正确渲染(您只需要知道必须将颜色应用于该像素以及应用多少)。因此,在加载时将所有字符设置为 8 位掩码。然后在渲染之前转换为 32 位图像:在RGB组件中应用您的颜色并将掩码设置为A组件。我在着色器中做。

希望能帮助到你。快乐编码!

更新 1

由于现在您正在复制 8 位源,memcpy每像素 8 位,显然您还需要将目标 ( mTexture) 调整为每像素相同的位:D3DFMT_A8(8 位) 而不是D3DFMT_A8L8(8 + 8 = 16 位)。

于 2013-05-12T16:30:56.280 回答