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)
You loading chars as
FT_Load_Char( face, L'a', FT_LOAD_RENDER );
this means that
and
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 asA
component. I do it in shader.Hope it helps. Happy coding!
update 1
Due to now you are copying 8-bit source,
memcpy
ing 8-bits per pixel, obviously you also need to resize your target (mTexture
) to be same bits per pixel:D3DFMT_A8
(8 bit) instead ofD3DFMT_A8L8
( 8 + 8 = 16 bits).