C++ 复制到d3dtexture的FreeType2字符显示为双字母

C++ 复制到d3dtexture的FreeType2字符显示为双字母,c++,fonts,directx,freetype,C++,Fonts,Directx,Freetype,我最近刚开始使用FreeType库,并开始尝试从缓冲区复制到directx9纹理 然而,尽管从通过加载单个字符而创建的缓冲区中复制,我目前仍会看到两个字母,如下所示: [复制字符“a”的尝试] 以下是我当前的代码: void TexFont::freeTypeSave() { static FT_Library library; /* handle to library */ static FT_Face face; /* handle to f

我最近刚开始使用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);
}
void TexFont::freeTypeSave()
{
静态FT_库;/*库句柄*/
静态FT_Face;/*手柄到面对象*/
if(FT_Init_FreeType(&library)){
NHelper::OutputDebugStringN(“错误”);
}
if(FT_New_Face(库、文本(“font\\arial.ttf”)、0和Face)){
NHelper::OutputDebugStringN(“字体加载失败\n”);
}
否则{
//NHelper::OutputDebugStringN(“字体面:%d\n”,面->num\u面);
}
静态整数误差;
静态单元宽度、高度;
静态int mTtfSize=64;
静态积分mTtfResolution=96;
静态IDirect3DTexture9*mTexture;
静态无符号整数mPixelBytes=2;
静态无符号整数mDataSize=宽度*高度*mPixelBytes;
//大小设置(将字体大小转换为*64)
FT_F26Dot6 ftSize=(FT_F26Dot6)(mTtfSize*(1字形->位图.width;
高度=面->字形->位图.rows;
D3DXCreateTexture(
g_引擎->获取设备(),
宽度,高度,
1, 0,
D3DFMT_A8L8,D3DPOOL_管理,
&织物);
D3DLOCKED_u-RECT lockedRect;
mTexture->LockRect(0,&lockedRect,0,0);
无符号字符*pSrcPixels=face->glyph->bitmap.buffer;
unsigned char*pDestPixels=(unsigned char*)lockedRect.pBits;
对于(UINT i=0;i<高度;++i)
{
//复制一行
memcpy(pDestPixels,pSrcPixels,宽度*2);//每像素2字节(1字节alpha,1字节灰度)
//前进行指针
pSrcPixels+=面->字形->位图.pitch;
pDestPixels+=锁定的选距;
}
NHelper::OutputDebugStringN(“字符宽度:%d,高度:%d\n”,宽度,高度);
mTexture->UnlockRect(0);
D3DXSaveTextureToFileA(“test.png”,D3DXIFF_png,mTexture,0);
//释放面
FT_Done_面(面);
//库关闭
FT_Done_FreeType(库);
}
有没有关于发生了什么事以及我如何解决这个问题的想法

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

--更新--

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

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

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

您可以按如下方式加载字符:

FT\u Load\u Char(面,L'a',FT\u Load\u渲染);

这意味着

默认情况下,图示符在FT\u渲染模式\u正常模式下渲染

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

但您可以复制为16位:

memcpy(pDestPixels,pSrcPixels,宽度*2);//每像素2字节(1字节alpha,1字节灰度)

你真的不需要在任何角色中使用灰度组件来进行适当的渲染(你只需要知道你必须对该像素应用颜色以及颜色的大小)。因此,在加载时将所有角色作为8位掩码。 然后在渲染之前转换为32位图像:在
RGB
组件中应用颜色,并将遮罩设置为
A
组件。我在着色器中执行此操作

希望有帮助。快乐编码

更新1


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

即使在渲染多个角色时,它也会给出类似的结果吗?@Magtheridon96+1我还没有尝试过,但如果我愿意,我会循环使用我在问题中发布的函数,因此我想我会得到相同的结果。+1对于使用最小内存拆分加载的角色并使用着色器应用效果的想法。更改我的
宽度*2
to
width*1
但是给了我一个字形,但是图像大小相同,字形占据了图像的一半。这是预期的行为吗?我会在我的问题中提供一个屏幕截图。我是个白痴,竟然忘了。感谢更新,效果很好!