Back to index

supertuxkart  0.5+dfsg1
BMF_BitmapFont.cpp
Go to the documentation of this file.
00001 
00036 #include <string.h>
00037 
00038 #if defined(WIN32) || defined(__APPLE__)
00039        #ifdef WIN32
00040         #if !defined(__CYGWIN32__)
00041         #pragma warning(disable:4244)
00042         #endif /* __CYGWIN32__ */
00043               #include <windows.h>
00044               #include <GL/gl.h>
00045        #else // WIN32
00046               // __APPLE__ is defined
00047               #include <AGL/gl.h>
00048        #endif // WIN32
00049 #else // defined(WIN32) || defined(__APPLE__)
00050        #include <GL/gl.h>
00051 #endif // defined(WIN32) || defined(__APPLE__)
00052 
00053 #include "BMF_BitmapFont.h"
00054 
00055 
00056 BMF_BitmapFont::BMF_BitmapFont(BMF_FontData* fontData)
00057 : m_fontData(fontData)
00058 {
00059 }
00060 
00061 
00062 BMF_BitmapFont::~BMF_BitmapFont(void)
00063 {
00064 }
00065 
00066 
00067 void BMF_BitmapFont::drawString(const char* str)
00068 {
00069        if (!str)
00070               return;
00071 
00072        GLint alignment;
00073        unsigned char c;
00074               
00075        glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
00076        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00077 
00078        while ((c = (unsigned char) *str++)) {
00079               BMF_CharData & cd = m_fontData->chars[c];
00080               
00081               if (cd.data_offset==-1) {
00082                      GLubyte nullBitmap = 0;
00083               
00084                      glBitmap(1, 1, 0, 0, cd.advance, 0, &nullBitmap);       
00085               } else {
00086                      GLubyte *bitmap = &m_fontData->bitmap_data[cd.data_offset];
00087               
00088                      glBitmap(cd.width, cd.height, cd.xorig, cd.yorig, cd.advance, 0, bitmap);
00089               }
00090        }
00091 
00092        glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
00093 }
00094 
00095 
00096 int BMF_BitmapFont::getStringWidth(char* str)
00097 {
00098        unsigned char c;
00099        int length = 0;
00100 
00101        while ((c = (unsigned char) *str++)) {
00102               length += m_fontData->chars[c].advance;
00103        }
00104        
00105        return length;
00106 }
00107 
00108 void BMF_BitmapFont::getBoundingBox(int & xMin, int & yMin, int & xMax, int & yMax)
00109 {
00110        xMin = m_fontData->xmin;
00111        yMin = m_fontData->ymin;
00112        xMax = m_fontData->xmax;
00113        yMax = m_fontData->ymax;
00114 }
00115 
00116 int BMF_BitmapFont::getTexture()
00117 {
00118        int fWidth = m_fontData->xmax - m_fontData->xmin;
00119        int fHeight = m_fontData->ymax - m_fontData->ymin;
00120        
00121        if (fWidth>=16 || fHeight>=16) {
00122               return -1;
00123        }
00124        
00125        int cRows = 16, cCols = 16;
00126        int cWidth = 16, cHeight = 16;
00127        int iWidth = cCols*cWidth;
00128        int iHeight = cRows*cHeight;
00129        GLubyte *img = new GLubyte [iHeight*iWidth];
00130        GLuint texId;
00131 
00132        int baseLine = -(m_fontData->ymin);
00133        
00134        memset(img, 0, iHeight*iWidth);
00135        for (int i = 0; i<256; i++) {
00136               BMF_CharData & cd = m_fontData->chars[i];
00137               
00138               if (cd.data_offset != -1) {
00139                      int cellX = i%16;
00140                      int cellY = i/16;
00141                      
00142                      for (int y = 0; y<cd.height; y++) {
00143                             GLubyte* imgRow = &img[(cellY*cHeight + y + baseLine - cd.yorig)*iWidth];
00144                             GLubyte* chrRow = &m_fontData->bitmap_data[cd.data_offset + ((cd.width+7)/8)*y];
00145 
00146                             for (int x = 0; x<cd.width; x++) {
00147                                    GLubyte* imgPxl = &imgRow[(cellX*cWidth + x - cd.xorig)];
00148                                    int byteIdx = x/8;
00149                                    int bitIdx = 7 - (x%8);
00150                                    
00151                                    if (chrRow[byteIdx]&(1<<bitIdx)) {
00152                                           imgPxl[0] = 255;
00153                                    }
00154                             }
00155                      }
00156               }
00157        }
00158        
00159        glGenTextures(1, &texId);
00160        
00161        glBindTexture(GL_TEXTURE_2D, texId);
00162 
00163        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA4, iWidth, iHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, img);
00164        if (glGetError()) {
00165               glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE4_ALPHA4, iWidth, iHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, img);
00166        }
00167        
00168        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00169        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00170        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00171        
00172        delete [] img;
00173        
00174        return texId;
00175 }
00176 
00177 void BMF_BitmapFont::drawStringTexture(char *str, float x, float y, float z)
00178 {
00179        unsigned char c;
00180        float pos = 0;
00181        
00182        int baseLine = -(m_fontData->ymin);
00183 
00184        glBegin(GL_QUADS);
00185        while ((c = (unsigned char) *str++)) {
00186               BMF_CharData & cd = m_fontData->chars[c];
00187               
00188               if (cd.data_offset != -1) {
00189                      float cellX = (c%16)/16.0;
00190                      float cellY = (c/16)/16.0;
00191               
00192                      glTexCoord2f(cellX + 1.0/16.0, cellY);
00193                      glVertex3f(x + pos + 16.0, -baseLine + y + 0.0, z);
00194 
00195                      glTexCoord2f(cellX + 1.0/16.0, cellY + 1.0/16.0);
00196                      glVertex3f(x + pos + 16.0, -baseLine + y + 16.0, z);
00197 
00198                      glTexCoord2f(cellX, cellY + 1.0/16.0);
00199                      glVertex3f(x + pos + 0.0, -baseLine + y + 16.0, z);
00200 
00201                      glTexCoord2f(cellX, cellY);
00202                      glVertex3f(x + pos + 0.0, -baseLine + y + 0.0, z);
00203               }
00204               
00205               pos += cd.advance;
00206        }
00207        glEnd();
00208 }