Main Page | Class Hierarchy | Data Structures | File List | Data Fields | Globals

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* fontFilePath)
00022 :   FTFont( fontFilePath),
00023     maximumGLTextureSize(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     maximumGLTextureSize(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( !maximumGLTextureSize)
00100     {
00101         glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maximumGLTextureSize);
00102         assert(maximumGLTextureSize); // If you hit this then you have an invalid OpenGL context.
00103     }
00104     
00105     textureWidth = NextPowerOf2( (remGlyphs * glyphWidth) + ( padding * 2));
00106     textureWidth = textureWidth > maximumGLTextureSize ? maximumGLTextureSize : textureWidth;
00107     
00108     int h = static_cast<int>( (textureWidth - ( padding * 2)) / glyphWidth);
00109         
00110     textureHeight = NextPowerOf2( (( numGlyphs / h) + 1) * glyphHeight);
00111     textureHeight = textureHeight > maximumGLTextureSize ? maximumGLTextureSize : textureHeight;
00112 }
00113 
00114 
00115 GLuint FTGLTextureFont::CreateTexture()
00116 {   
00117     CalculateTextureSize();
00118     
00119     int totalMemory = textureWidth * textureHeight;
00120     unsigned char* textureMemory = new unsigned char[totalMemory];
00121     memset( textureMemory, 0, totalMemory);
00122 
00123     GLuint textID;
00124     glGenTextures( 1, (GLuint*)&textID);
00125 
00126     glBindTexture( GL_TEXTURE_2D, textID);
00127     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00128     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00129     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00130     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00131 
00132     glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, textureMemory);
00133 
00134     delete [] textureMemory;
00135 
00136     return textID;
00137 }
00138 
00139 
00140 bool FTGLTextureFont::FaceSize( const unsigned int size, const unsigned int res)
00141 {
00142     if( !textureIDList.empty())
00143     {
00144         glDeleteTextures( textureIDList.size(), (const GLuint*)&textureIDList[0]);
00145         textureIDList.clear();
00146         remGlyphs = numGlyphs = face.GlyphCount();
00147     }
00148 
00149     return FTFont::FaceSize( size, res);
00150 }
00151 
00152 
00153 void FTGLTextureFont::Render( const char* string)
00154 {   
00155     glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
00156     
00157     glEnable(GL_BLEND);
00158     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
00159 
00160     FTTextureGlyph::ResetActiveTexture();
00161     
00162     FTFont::Render( string);
00163 
00164     glPopAttrib();
00165 }
00166 
00167 
00168 void FTGLTextureFont::Render( const wchar_t* string)
00169 {   
00170     glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
00171     
00172     glEnable(GL_BLEND);
00173     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
00174     
00175     FTTextureGlyph::ResetActiveTexture();
00176     
00177     FTFont::Render( string);
00178     
00179     glPopAttrib();
00180 }
00181 

Generated on Sun Dec 5 22:24:06 2004 for FTGL by doxygen 1.3.6