Main Page | Directories | File List | File Members

FTGLTextureFont.cpp

Go to the documentation of this file.
00001 #include <string> // For memset
00002 
00003 #include "FTGLTextureFont.h"
00004 #include "FTTextureGlyph.h"
00005 
00006 
00007 inline GLuint NextPowerOf2( GLuint in)
00008 {
00009      in -= 1;
00010 
00011      in |= in >> 16;
00012      in |= in >> 8;
00013      in |= in >> 4;
00014      in |= in >> 2;
00015      in |= in >> 1;
00016 
00017      return in + 1;
00018 }
00019 
00020 
00021 FTGLTextureFont::FTGLTextureFont( const char* fontname)
00022 :   FTFont( fontname),
00023     maxTextSize(0),
00024     textureWidth(0),
00025     textureHeight(0),
00026     glyphHeight(0),
00027     glyphWidth(0),
00028     padding(3),
00029     xOffset(0),
00030     yOffset(0)
00031 {
00032     remGlyphs = numGlyphs = face.GlyphCount();
00033 }
00034 
00035 
00036 FTGLTextureFont::FTGLTextureFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
00037 :   FTFont( pBufferBytes, bufferSizeInBytes),
00038     maxTextSize(0),
00039     textureWidth(0),
00040     textureHeight(0),
00041     glyphHeight(0),
00042     glyphWidth(0),
00043     padding(3),
00044     xOffset(0),
00045     yOffset(0)
00046 {
00047     remGlyphs = numGlyphs = face.GlyphCount();
00048 }
00049 
00050 
00051 FTGLTextureFont::~FTGLTextureFont()
00052 {
00053     glDeleteTextures( textureIDList.size(), (const GLuint*)&textureIDList[0]);
00054 }
00055 
00056 
00057 FTGlyph* FTGLTextureFont::MakeGlyph( unsigned int glyphIndex)
00058 {
00059     FT_GlyphSlot ftGlyph = face.Glyph( glyphIndex, FT_LOAD_NO_HINTING);
00060     
00061     if( ftGlyph)
00062     {
00063         glyphHeight = static_cast<int>( charSize.Height());
00064         glyphWidth = static_cast<int>( charSize.Width());
00065         
00066         if( textureIDList.empty())
00067         {
00068             textureIDList.push_back( CreateTexture());
00069             xOffset = yOffset = padding;
00070         }
00071         
00072         if( xOffset > ( textureWidth - glyphWidth))
00073         {
00074             xOffset = padding;
00075             yOffset += glyphHeight;
00076             
00077             if( yOffset > ( textureHeight - glyphHeight))
00078             {
00079                 textureIDList.push_back( CreateTexture());
00080                 yOffset = padding;
00081             }
00082         }
00083         
00084         FTTextureGlyph* tempGlyph = new FTTextureGlyph( ftGlyph, textureIDList[textureIDList.size() - 1],
00085                                                         xOffset, yOffset, textureWidth, textureHeight);
00086         xOffset += static_cast<int>( tempGlyph->BBox().upperX - tempGlyph->BBox().lowerX + padding);
00087         
00088         --remGlyphs;
00089         return tempGlyph;
00090     }
00091     
00092     err = face.Error();
00093     return NULL;
00094 }
00095 
00096 
00097 void FTGLTextureFont::CalculateTextureSize()
00098 {
00099     if( !maxTextSize)
00100     {
00101         glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);
00102     }
00103     
00104     textureWidth = NextPowerOf2( (remGlyphs * glyphWidth) + ( padding * 2));
00105     if( textureWidth > maxTextSize)
00106     {
00107         textureWidth = maxTextSize;
00108     }
00109     
00110     int h = static_cast<int>( (textureWidth - ( padding * 2)) / glyphWidth);
00111         
00112     textureHeight = NextPowerOf2( (( numGlyphs / h) + 1) * glyphHeight);
00113     textureHeight = textureHeight > maxTextSize ? maxTextSize : textureHeight;
00114 }
00115 
00116 
00117 GLuint FTGLTextureFont::CreateTexture()
00118 {   
00119     CalculateTextureSize();
00120     
00121     int totalMemory = textureWidth * textureHeight;
00122     unsigned char* textureMemory = new unsigned char[totalMemory];
00123     memset( textureMemory, 0, totalMemory);
00124 
00125     GLuint textID;
00126     glGenTextures( 1, (GLuint*)&textID);
00127 
00128     glBindTexture( GL_TEXTURE_2D, textID);
00129     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00130     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00131     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00132     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00133 
00134     glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, textureMemory);
00135 
00136     delete [] textureMemory;
00137 
00138     return textID;
00139 }
00140 
00141 
00142 bool FTGLTextureFont::FaceSize( const unsigned int size, const unsigned int res)
00143 {
00144     if( !textureIDList.empty())
00145     {
00146         glDeleteTextures( textureIDList.size(), (const GLuint*)&textureIDList[0]);
00147         remGlyphs = numGlyphs = face.GlyphCount();
00148     }
00149 
00150     return FTFont::FaceSize( size, res);
00151 }
00152 
00153 
00154 void FTGLTextureFont::Render( const char* string)
00155 {   
00156     glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
00157     
00158     glEnable(GL_BLEND);
00159     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
00160     
00161     FTFont::Render( string);
00162 
00163     glPopAttrib();
00164 }
00165 
00166 
00167 void FTGLTextureFont::Render( const wchar_t* string)
00168 {   
00169     glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
00170     
00171     glEnable(GL_BLEND);
00172     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
00173     
00174     FTFont::Render( string);
00175     
00176     glPopAttrib();
00177 }
00178 

Generated on Mon Sep 5 05:29:33 2005 for FTGL by  doxygen 1.4.4