复制到d3dtexture的FreeType2 char显示为双字母 [英] FreeType2 char copied to d3dtexture appears as double letters

查看:174
本文介绍了复制到d3dtexture的FreeType2 char显示为双字母的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've recently just started using the FreeType library and have started to attempt copying from the buffer into directx9 textures.

尽管从通过加载单个字符而创建的缓冲区中复制,但我现在还是出现了两个字母:

I'm currently getting however double letters appearing despite having copied from a buffer created through loading a single character as so :

[复制字符'a']的尝试

[copy attempt of the character '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);
}

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

Any ideas on what's happening and how I could go around fixing this?

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

Note: changing the font size merely creates a larger image. I still get the same result.

-更新-

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

Trying Drop's suggestion, I tried changing my memcpy(pDestPixels, pSrcPixels, width * 2);

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

一个字形向图像左侧填充,但图像保持相同大小。
(字形仅占用图像空间的一半)

One glyph packed toward the left of the image, yet the image remaining the same size. (the glyph only takes up half of the image space)

推荐答案

您将字符加载为

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

这意味着


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


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

FT_RENDER_MODE_NORMAL This is the default render mode; it corresponds to 8-bit anti-aliased bitmaps.

但是您将其复制为16位:

But you copying as 16-bit:

memcpy(pDestPixels,pSrcPixels,width * 2); //每像素2个字节(1个字节的Alpha,1个字节的灰度级)

您实际上不需要任何字符中的灰度级分量即可进行正确渲染(您只需要知道是否必须将颜色应用于该像素及其数量)。因此,在加载时将所有字符设置为8位掩码。
然后在渲染之前转换为32位图像:在 RGB 组件中应用颜色,并将蒙版设置为 A 组件。我是在着色器中完成的。

You really don't need grayscale component in any character for proper rendering (you just need to know must you apply color to that pixel and how much). So, make all of your characters as 8-bit masks on loading. Then convert to 32-bit image just before rendering: apply your color in RGB components and set mask as A component. I do it in shader.

希望它会有所帮助。祝您编程愉快!

Hope it helps. Happy coding!

更新1

update 1

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

Due to now you are copying 8-bit source, memcpying 8-bits per pixel, obviously you also need to resize your target (mTexture) to be same bits per pixel: D3DFMT_A8 (8 bit) instead of D3DFMT_A8L8 ( 8 + 8 = 16 bits).

这篇关于复制到d3dtexture的FreeType2 char显示为双字母的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆