Fonts

I am using freetype library (from www.freetype.org)) to display freetype fonts. I want to apply RGBA texture image to the font. How to apply the RGBA texture image to the font? Here I am giving some code from freetype library. Please check the code and give response if is there any possibilty to apply texture to the font.

FTGlyph* FTGLTextureFont::MakeGlyph( unsigned int glyphIndex)
{
FT_Glyph* ftGlyph = face.Glyph( glyphIndex, FT_LOAD_NO_HINTING);

if( ftGlyph)
{
    glyphHeight = static_cast<int>( charSize.Height());
    glyphWidth = static_cast<int>( charSize.Width());
    
    if( numTextures == 0)
    {
        glTextureID[0] = [b]CreateTexture()[/b];
        xOffset = yOffset = padding;
        ++numTextures;
    }
    
    if( xOffset > ( textureWidth - glyphWidth))
    {
        xOffset = padding;
        yOffset += glyphHeight;
        
        if( yOffset > ( textureHeight - glyphHeight))
        {
            glTextureID[numTextures] = [b]CreateTexture()[/b];
            ++numTextures;
            yOffset = padding;
        }
    }
    
    FTTextureGlyph* tempGlyph = new FTTextureGlyph( *ftGlyph, glTextureID[numTextures - 1],
                                                    xOffset, yOffset, textureWidth, textureHeight);
    xOffset += static_cast<int>( tempGlyph->BBox().upperX - tempGlyph->BBox().lowerX + padding);
    
    --remGlyphs;
    return tempGlyph;
}

err = face.Error();
return NULL;

}

void FTGLTextureFont::CalculateTextureSize()
{
if( !maxTextSize)
{
glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);
}

textureWidth = NextPowerOf2( (remGlyphs * glyphWidth) + ( padding * 2));
if( textureWidth > maxTextSize)
{
    textureWidth = maxTextSize;
}

int h = static_cast<int>( (textureWidth - ( padding * 2)) / glyphWidth);
    
textureHeight = NextPowerOf2( (( numGlyphs / h) + 1) * glyphHeight);
textureHeight = textureHeight > maxTextSize ? maxTextSize : textureHeight;

}

GLuint FTGLTextureFont::CreateTexture()
{
CalculateTextureSize();

int totalMemory = textureWidth * textureHeight;
unsigned char* textureMemory = new unsigned char[totalMemory];
memset( textureMemory, 0, totalMemory);

GLuint textID;
glGenTextures( 1, (GLuint*)&textID);

glBindTexture( GL_TEXTURE_2D, textID);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, textureMemory);

delete [] textureMemory;

return textID;

}

And here is another class methods:
FTTextureGlyph::FTTextureGlyph( FT_Glyph glyph, int id, int xOffset, int yOffset, GLsizei width, GLsizei height)
: FTGlyph( glyph),
destWidth(0),
destHeight(0),
glTextureID(id),
activeTextureID(0)
{
err = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, 0, 1);
if( err | | glyph->format != ft_glyph_format_bitmap)
{
return;
}

FT_BitmapGlyph  bitmap = ( FT_BitmapGlyph)glyph;
FT_Bitmap*      source = &bitmap->bitmap;

destWidth  = source->width;
destHeight = source->rows;

//
if( destWidth && destHeight)
{
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);

    glBindTexture( GL_TEXTURE_2D, glTextureID);
    glTexSubImage2D( GL_TEXTURE_2D, 0, xOffset, yOffset, destWidth, destHeight, GL_ALPHA, GL_UNSIGNED_BYTE, source->buffer);

    glPopClientAttrib();
}

// 0
// ±—+
// | |
// | |
// | |
// ±—+
// 1

uv[0].x = static_cast<float>(xOffset) / static_cast<float>(width);
uv[0].y = static_cast<float>(yOffset) / static_cast<float>(height);
uv[1].x = static_cast<float>( xOffset + destWidth) / static_cast<float>(width);
uv[1].y = static_cast<float>( yOffset + destHeight) / static_cast<float>(height);

pos.x = bitmap->left;
pos.y = bitmap->top;

FT_Done_Glyph( glyph);

}

float FTTextureGlyph::Render( const FTPoint& pen)
{
glGetIntegerv( GL_TEXTURE_2D_BINDING_EXT, &activeTextureID);
if( activeTextureID != glTextureID)
{
glBindTexture( GL_TEXTURE_2D, (GLuint)glTextureID);
}

glBegin( GL_QUADS);
    glTexCoord2f( uv[0].x, uv[0].y);
    glVertex2f( pen.x + pos.x,             pen.y + pos.y);

    glTexCoord2f( uv[0].x, uv[1].y);
    glVertex2f( pen.x + pos.x,             pen.y + pos.y - destHeight);

    glTexCoord2f( uv[1].x, uv[1].y);
    glVertex2f( pen.x + destWidth + pos.x, pen.y + pos.y - destHeight);
    
    glTexCoord2f( uv[1].x, uv[0].y);
    glVertex2f( pen.x + destWidth + pos.x, pen.y + pos.y);
glEnd();

return advance;

}

[This message has been edited by ramana (edited 12-17-2003).]

What’s wrong with your code? What’s your problem?

I want to map RGBA image to the font. Through glTexImage2D I pass GL_ALPHA only, but I need to map RGBA image. How to map that one?

Originally posted by ramana:
I want to map RGBA image to the font. Through glTexImage2D I pass GL_ALPHA only, but I need to map RGBA image. How to map that one?

Rather than look too closely at the FTGL code you using, it’d be worth winding back a little to what what FreeType provides you with and what FTGL does with it.

FreeType generates polygonal, bitmap or greyscale image glyphs, FTGL can wrap each of these types, the later greyscale is mapped to texture mapped quads as an alpha texture.

To produce a RGBA texture you two options:

  1. build the RGBA image yourself by combining your RGB image with the greyscale from FreeType.

  2. multi-texturing, leave FTGL to set up the alpha texture, but add you own texture as a second texture unit.

Robert.

Thank you Robert I will try this one.

I replace the glTexSubImage2D(…) and glTexImage2D(…) in the above code with the following statements:
glTexSubImage2D( GL_TEXTURE_2D, 0, xOffset, yOffset, destWidth, destHeight, GL_RGBA, GL_UNSIGNED_BYTE, source->buffer);

glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureMemory);

Here source->buffer and textureMemory contains RGBA images.

But it won’t displays the RGBA font it only displays the font with single color. I already allocated required space for the textureMemory to fit the RGBA image. Why it won’t displays RGBA fonts?

[This message has been edited by ramana (edited 12-19-2003).]

[This message has been edited by ramana (edited 12-19-2003).]

Sorry, I got it I replaced GL_RGB8 with GL_RGBA.

glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureMemory);

Again, Thank you Robert.