Edit

kc3-lang/ftgl/src/FTGLTextureFont.cpp

Branch :

  • Show log

    Commit

  • Author : henry
    Date : 2001-11-12 22:28:36
    Hash : d58c7be1
    Message : Refactored texture fonts to ba able to load glyphs on the fly...uses glTexSubImage2D. They are now more in line with the rest of the fonts.

  • src/FTGLTextureFont.cpp
  • #include	"FTGLTextureFont.h"
    #include	"FTGlyphContainer.h"
    #include	"FTTextureGlyph.h"
    
    using namespace std;
    
    //#include "mmgr.h"
    
    inline GLuint NextPowerOf2( GLuint in)
    {
         in -= 1;
    
         in |= in >> 16;
         in |= in >> 8;
         in |= in >> 4;
         in |= in >> 2;
         in |= in >> 1;
    
         return in + 1;
    }
    
    
    FTGLTextureFont::FTGLTextureFont()
    :	maxTextSize(0),
    	textureWidth(0),
    	textureHeight(0),
    	numTextures(0),
    	textMem(0),
    	glyphHeight(0),
    	glyphWidth(0),
    	padding(1),
    	remGlyphs(0),
    	xOffset(0),
    	yOffset(0)
    {
    }
    
    
    FTGLTextureFont::~FTGLTextureFont()
    {
    	glDeleteTextures( numTextures, (const GLuint*)glTextureID);
    }
    
    
    FTGlyph* FTGLTextureFont::MakeGlyph( unsigned int g)
    {
    	FT_Glyph* ftGlyph = face.Glyph( g, FT_LOAD_NO_HINTING);
    	
    	if( ftGlyph)
    	{
    		// Estimate the glyph size size - global bbox
    		glyphHeight = ( charSize.Height()) + padding;
    		glyphWidth = ( charSize.Width()) + padding;
    		
    		// Is there a current texture
    		if( numTextures == 0)
    		{
    			glTextureID[0] = CreateTexture();
    			xOffset = yOffset = padding;
    			++numTextures;
    
    		}
    		
    		// will it fit in the current texture
    		if( xOffset > ( textureWidth - glyphWidth))
    		{
    			xOffset = padding;
    			yOffset += glyphHeight;
    			
    			if( yOffset > ( textureHeight - glyphHeight))
    			{
    				// no - make a new texture
    				glTextureID[numTextures] = CreateTexture();
    				yOffset = padding;
    				++numTextures;
    			}
    		}
    		
    		// yes - load the glyph
    		FTTextureGlyph* tempGlyph = new FTTextureGlyph( *ftGlyph, glTextureID[numTextures - 1],
    															xOffset, yOffset, textureWidth, textureHeight);
    		
    		xOffset += tempGlyph->BBox().x2 - tempGlyph->BBox().x1;
    		
    		--remGlyphs;
    		return tempGlyph;
    	}
    	
    	err = face.Error();
    	return NULL;
    
    }
    
    
    
    
    bool FTGLTextureFont::MakeGlyphList()
    {
    	if( !maxTextSize)
    		glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);
    
    	remGlyphs = numGlyphs;
    
    	FTFont::MakeGlyphList();
    	
    	return !err; // FIXME what err?
    }
    
    
    void FTGLTextureFont::GetSize()
    {
    	//work out the max width. Most likely 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;
    }
    
    
    int FTGLTextureFont::CreateTexture()
    {	
    	// calc the size
    	GetSize();
    	
    	// allocate some mem and clear it to black
    	int totalMem = textureWidth * textureHeight;
    	textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
    	memset( textMem, 0, totalMem);
    
    	// Create the blank texture
    	int textID;
    	glGenTextures( 1, (GLuint*)&textID);
    
    	glPixelStorei( GL_UNPACK_ALIGNMENT, 1); //What does this do exactly?
    	glBindTexture( GL_TEXTURE_2D, textID);
    	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, textMem);
    
    	delete [] textMem;
    
    	return textID;
    }
    
    
    void FTGLTextureFont::render( const char* string)
    {	
    	glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
    	
    	glEnable(GL_BLEND);
     	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
     	
     	FTFont::render( string);
    
    	glPopAttrib();
    }
    
    
    void FTGLTextureFont::render( const wchar_t* string)
    {	
    	glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
    	
    	glEnable(GL_BLEND);
     	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
     	
     	FTFont::render( string);
    	
    	glPopAttrib();
    }