Edit

kc3-lang/ftgl/src/FTGLTextureFont.cpp

Branch :

  • Show log

    Commit

  • Author : henry
    Date : 2001-08-20 21:44:00
    Hash : aded3122
    Message : Gerards fixes to compile under Linux

  • src/FTGLTextureFont.cpp
  • #include	"GL/gl.h"
    
    #include	"FTGLTextureFont.h"
    #include	"FTGlyphContainer.h"
    #include	"FTGL.h"
    #include	"FTTextureGlyph.h"
    
    
    typedef unsigned long	UInt32; // a mac thing?
    
    
    inline UInt32 NextPowerOf2( UInt32 in)
    {
         in -= 1;
    
         in |= in >> 16;
         in |= in >> 8;
         in |= in >> 4;
         in |= in >> 2;
         in |= in >> 1;
    
         return in + 1;
    }
    
    
    FTGLTextureFont::FTGLTextureFont()
    :	numTextures(1),
    	textMem(0),
    	padding(1),
    	tempGlyph(0),
    	maxTextSize(0),
    	textureWidth(0),
    	textureHeight(0),
    	glyphHeight(0),
    	glyphWidth(0)
    {}
    
    
    FTGLTextureFont::~FTGLTextureFont()
    {
    	glDeleteTextures( numTextures, (const GLuint*)glTextureID);
    }
    
    
    bool FTGLTextureFont::MakeGlyphList()
    {
    	if( !maxTextSize)
    		glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);
    	
    	glyphHeight = ( charSize.Height()) + padding;
    	glyphWidth = ( charSize.Width()) + padding;
    	
    	GetSize();
    	int totalMem;
    	
    	if( textureHeight > maxTextSize)
    	{
    		numTextures = static_cast<int>( textureHeight / maxTextSize) + 1;
    		if( numTextures > 15)
    			numTextures = 15;
    		
    		int heightRemain = NextPowerOf2( textureHeight % maxTextSize);
    		totalMem = ((maxTextSize * ( numTextures - 1)) + heightRemain) * textureWidth;
    
    		glGenTextures( numTextures, (GLuint*)&glTextureID[0]);
    
    		textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
    		std::memset( textMem, 0, totalMem);
    			
    		int glyphNum = 0;
    		unsigned char* currTextPtr = textMem;
    		
    		for( int x = 0; x < numTextures - 1; ++x)
    		{
    			glyphNum = FillGlyphs( glyphNum, glTextureID[x], textureWidth, maxTextSize, currTextPtr);
    			
    			CreateTexture( x, textureWidth, maxTextSize, currTextPtr);
    			
    			currTextPtr += ( textureWidth * maxTextSize);
    			++glyphNum;
    		}
    		
    		glyphNum = FillGlyphs( glyphNum, glTextureID[numTextures - 1], textureWidth, heightRemain, currTextPtr);
    		CreateTexture( numTextures - 1, textureWidth, heightRemain, currTextPtr);
    	}
    	else
    	{
    		textureHeight = NextPowerOf2( textureHeight);
    		totalMem = textureWidth * textureHeight;
    		
    		glGenTextures( numTextures, (GLuint*)&glTextureID[0]);
    
    		textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
    		std::memset( textMem, 0, totalMem);
    
    		FillGlyphs( 0, glTextureID[0], textureWidth, textureHeight, textMem);
    		CreateTexture( 0, textureWidth, textureHeight, textMem);
    	}
    
    	delete [] textMem;
    	return !err;
    }
    
    
    int FTGLTextureFont::FillGlyphs( int glyphStart, int id, int width, int height, unsigned char* textdata)
    {
    	FT_Face* ftFace = face.Face();
    	
    	int currentTextX = padding;
    	int currentTextY = padding;// + padding;
    	
    	float currTextU = (float)padding / (float)width;
    	float currTextV = (float)padding / (float)height;
    	
    //	numGlyphs = 256; // FIXME hack
    	int n;
    	
    	for( n = glyphStart; n <= numGlyphs; ++n)
    	{
    		err = FT_Load_Glyph( *ftFace, n, FT_LOAD_NO_HINTING); // FT_LOAD_DEFAULT
    		FT_Glyph ftGlyph;
    		
    		err = FT_Get_Glyph( (*ftFace)->glyph, &ftGlyph);
    	
    		unsigned char* data = textdata + (( currentTextY * width) + currentTextX);
    		
    		currTextU = (float)currentTextX / (float)width;
    		
    		tempGlyph = new FTTextureGlyph( ftGlyph, n, id, data, width, height, currTextU, currTextV);
    		glyphList->Add( tempGlyph);
    		
    		currentTextX += glyphWidth;
    		if( currentTextX > ( width - glyphWidth))
    		{
    			currentTextY += glyphHeight;
    			if( currentTextY > ( height - glyphHeight))
    				return n;
    				
    			currentTextX = padding;
    			currTextV = (float)currentTextY / (float)height;
    		}
    	}
    
    	return n;
    }
    
    
    void FTGLTextureFont::GetSize()
    {
    	//work out the max width. Most likely maxTextSize!
    	textureWidth = NextPowerOf2( numGlyphs * glyphWidth);
    	if( textureWidth > maxTextSize)
    	{
    		textureWidth = maxTextSize;
    	}
    	
    	int h = static_cast<int>( textureWidth / glyphWidth);
    	textureHeight = (( numGlyphs / h) + 1) * glyphHeight;
    }
    
    
    void FTGLTextureFont::CreateTexture( int id, int width, int height, unsigned char* data)
    {
    	glPixelStorei( GL_UNPACK_ALIGNMENT, 1); //What does this do exactly?
    	glBindTexture( GL_TEXTURE_2D, glTextureID[id]);
    	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
    	glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
    }
    
    
    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
     	
    	glBindTexture( GL_TEXTURE_2D, FTTextureGlyph::activeTextureID);
    
     	// QUADS are faster!? Less function call overhead?
     	glBegin( GL_QUADS);
     		FTFont::render( string);
     	glEnd();
    	
    	glPopAttrib();
    }