复制到d3dtexture的FreeType2字符显示为双字母(FreeType2 char copied to d3dtexture appears as double letters)

编程入门 行业动态 更新时间:2024-10-27 00:26:10
复制到d3dtexture的FreeType2字符显示为双字母(FreeType2 char copied to d3dtexture appears as double letters)

我最近刚开始使用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); }

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

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

--update--

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

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

一个字形打包在图像的左侧,但图像保持相同的大小。 (该字形只占用图像空间的一半)

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 :

[copy attempt of the character 'a']

The following is my current code:

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.

--update--

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

to memcpy(pDestPixels, pSrcPixels, width * 1); It returns the following:

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位消除锯齿的位图。

但是你复制为16位:

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

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

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

更新1

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

You loading chars as

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

this means that

By default, the glyph is rendered in FT_RENDER_MODE_NORMAL mode

and

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

But you copying as 16-bit:

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

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!

update 1

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).

更多推荐

本文发布于:2023-07-26 02:12:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1269561.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:字母   字符   d3dtexture   char   double

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!