0
\$\begingroup\$

I need to render some special text in my game. Currently I can render any text that use classic letters of english alphabet, but I have some problems with special alphabets.

How do I render text: I am using a simple program called Hiero that makes bitmap form fonts. It looks like this.

Simple bitmap created by Hiero

It also generates a file with some informations about font (positioning)

info face "Verdana" size 23 bold 0 italic 0 charset "" unicode 0 stretchH 100 smooth 1 aa 1 padding 3,3,3,3 spacing 0,0
common lineHeight 35 base 24 scaleW 256 scaleH 256 pages 1 packed 0
page id 0 file "VerdanaDIA.png"
chars count 123
char id 32   x 0     y 0     width 0     height 0     xoffset 0     yoffset 24    xadvance 14     page 0  chnl 0
char id 253   x 0     y 0     width 19     height 32     xoffset -2     yoffset 1    xadvance 20     page 0  chnl 0
char id 381   x 19     y 0     width 22     height 31     xoffset -2     yoffset -3    xadvance 22     page 0  chnl 0
char id 221   x 41     y 0     width 21     height 31     xoffset -3     yoffset -3    xadvance 20     page 0  chnl 0
char id 218   x 62     y 0     width 21     height 31     xoffset -1     yoffset -3    xadvance 23     page 0  chnl 0
char id 356   x 83     y 0     width 22     height 31     xoffset -3     yoffset -3    xadvance 20     page 0  chnl 0
char id 352   x 105     y 0     width 20     height 31     xoffset -1     yoffset -3    xadvance 22     page 0  chnl 0
char id 344   x 125     y 0     width 21     height 31     xoffset -1     yoffset -3    xadvance 22     page 0  chnl 0
char id 211   x 146     y 0     width 24     height 31     xoffset -2     yoffset -3    xadvance 24     page 0  chnl 0
char id 327   x 170     y 0     width 21     height 31     xoffset -1     yoffset -3    xadvance 23     page 0  chnl 0
char id 205   x 191     y 0     width 14     height 31     xoffset -1     yoffset -3    xadvance 16     page 0  chnl 0
char id 201   x 205     y 0     width 20     height 31     xoffset -1     yoffset -3    xadvance 21     page 0  chnl 0
char id 270   x 225     y 0     width 23     height 31     xoffset -1     yoffset -3    xadvance 24     page 0  chnl 0
char id 268   x 0     y 32     width 22     height 31     xoffset -2     yoffset -3    xadvance 22     page 0  chnl 0
char id 193   x 22     y 32     width 23     height 31     xoffset -3     yoffset -3    xadvance 22     page 0  chnl 0
char id 41   x 45     y 32     width 15     height 31     xoffset -2     yoffset 2    xadvance 16     page 0  chnl 0
char id 40   x 60     y 32     width 14     height 31     xoffset -1     yoffset 2    xadvance 16     page 0  chnl 0
char id 366   x 74     y 32     width 21     height 30     xoffset -1     yoffset -2    xadvance 23     page 0  chnl 0
char id 36   x 95     y 32     width 18     height 30     xoffset -1     yoffset 2    xadvance 21     page 0  chnl 0
char id 124   x 113     y 32     width 10     height 30     xoffset 1     yoffset 2    xadvance 16     page 0  chnl 0
char id 125   x 123     y 32     width 18     height 30     xoffset 0     yoffset 2    xadvance 21     page 0  chnl 0
char id 123   x 141     y 32     width 18     height 30     xoffset -1     yoffset 2    xadvance 21     page 0  chnl 0
char id 93   x 159     y 32     width 14     height 30     xoffset -1     yoffset 2    xadvance 16     page 0  chnl 0
char id 91   x 173     y 32     width 14     height 30     xoffset 0     yoffset 2    xadvance 16     page 0  chnl 0
char id 106   x 187     y 32     width 15     height 30     xoffset -4     yoffset 3    xadvance 14     page 0  chnl 0
char id 367   x 202     y 32     width 19     height 29     xoffset -1     yoffset -1    xadvance 21     page 0  chnl 0
char id 357   x 221     y 32     width 17     height 29     xoffset -2     yoffset -1    xadvance 15     page 0  chnl 0
char id 92   x 238     y 32     width 17     height 29     xoffset -2     yoffset 2    xadvance 16     page 0  chnl 0
char id 47   x 0     y 63     width 17     height 29     xoffset -3     yoffset 2    xadvance 16     page 0  chnl 0
char id 64   x 17     y 63     width 27     height 28     xoffset -1     yoffset 3    xadvance 29     page 0  chnl 0
char id 81   x 44     y 63     width 24     height 28     xoffset -2     yoffset 4    xadvance 24     page 0  chnl 0
char id 382   x 68     y 63     width 18     height 27     xoffset -2     yoffset 1    xadvance 18     page 0  chnl 0
char id 250   x 86     y 63     width 19     height 27     xoffset -1     yoffset 1    xadvance 21     page 0  chnl 0
char id 353   x 105     y 63     width 18     height 27     xoffset -2     yoffset 1    xadvance 18     page 0  chnl 0
char id 345   x 123     y 63     width 17     height 27     xoffset -2     yoffset 1    xadvance 16     page 0  chnl 0
char id 243   x 140     y 63     width 20     height 27     xoffset -2     yoffset 1    xadvance 20     page 0  chnl 0
char id 328   x 160     y 63     width 19     height 27     xoffset -1     yoffset 1    xadvance 21     page 0  chnl 0
char id 237   x 179     y 63     width 12     height 27     xoffset -2     yoffset 1    xadvance 12     page 0  chnl 0
char id 233   x 191     y 63     width 20     height 27     xoffset -2     yoffset 1    xadvance 20     page 0  chnl 0
char id 269   x 211     y 63     width 18     height 27     xoffset -2     yoffset 1    xadvance 18     page 0  chnl 0
char id 225   x 229     y 63     width 19     height 27     xoffset -2     yoffset 1    xadvance 20     page 0  chnl 0
char id 271   x 0     y 92     width 25     height 26     xoffset -2     yoffset 2    xadvance 21     page 0  chnl 0
char id 121   x 25     y 92     width 19     height 26     xoffset -2     yoffset 7    xadvance 20     page 0  chnl 0
char id 113   x 44     y 92     width 19     height 26     xoffset -2     yoffset 7    xadvance 20     page 0  chnl 0
char id 112   x 63     y 92     width 19     height 26     xoffset -1     yoffset 7    xadvance 20     page 0  chnl 0
char id 108   x 82     y 92     width 10     height 26     xoffset -1     yoffset 2    xadvance 12     page 0  chnl 0
char id 107   x 92     y 92     width 19     height 26     xoffset -1     yoffset 2    xadvance 20     page 0  chnl 0
char id 104   x 111     y 92     width 19     height 26     xoffset -1     yoffset 2    xadvance 21     page 0  chnl 0
char id 103   x 130     y 92     width 19     height 26     xoffset -2     yoffset 7    xadvance 20     page 0  chnl 0
char id 102   x 149     y 92     width 16     height 26     xoffset -2     yoffset 2    xadvance 14     page 0  chnl 0
char id 100   x 165     y 92     width 19     height 26     xoffset -2     yoffset 2    xadvance 20     page 0  chnl 0
char id 98   x 184     y 92     width 19     height 26     xoffset -1     yoffset 2    xadvance 20     page 0  chnl 0
char id 127   x 203     y 92     width 25     height 25     xoffset 0     yoffset 3    xadvance 29     page 0  chnl 0
char id 35   x 228     y 92     width 22     height 25     xoffset -1     yoffset 3    xadvance 25     page 0  chnl 0

Then I load it to my game as a texture and render quads textured with correct part (that I know form file) of this texture (with some transparency, color, ...). This all works perfectly.

I have no problems with render text like:

Hi, my name is Kevin. 

but when I translate this to my language:

Čau, mé jméno je Kevin.

Now letters like Č and é are not rendered.

This is my TextRender Class:

class TextRender
{
    private:
    GLuint fontdata;
    int size;
    int chardata[300][8];
    int charcount;
    float cursorx, cursory;
    public:
    void CREATE(string name)
    {
        cursorx=0;
        cursory=0;
        string prefix;
        charcount=0;
        string count="count";
        string sz="size";
        string fnt=".fnt";
        string bmp=".bmp";
        string finalname=name+fnt;
        string finalname2=name+bmp;
        ifstream data(finalname.c_str());
            while(data>>prefix) if(prefix==sz) break;
            data>>size;
            while(data>>prefix) if(prefix==count) break;
            data>>charcount;
            charcount++;
            for(int i=0;i<charcount;i++)
            {
                data>>prefix>>prefix>>chardata[i][0]>>prefix>>chardata[i][1]>>prefix>>chardata[i][2]>>prefix>>chardata[i][3]>>prefix>>chardata[i][4]>>prefix>>chardata[i][5]>>prefix>>chardata[i][6]>>
                prefix>>chardata[i][7]>>prefix>>prefix>>prefix>>prefix;
            } //Loads info about current character
        data.close();

        char jmeno[1000];
        strcpy(jmeno,finalname2.c_str());

        TEXTURA pismo(jmeno,256,0,230,230,230,0); //Creates texture

        glGenTextures(1,&fontdata);
        glBindTexture(GL_TEXTURE_2D,fontdata);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,256, 256,0, GL_RGBA, GL_UNSIGNED_BYTE, pismo.tex256);
    }

    void RenderCharAtPosition(float x,float y, char znak)
        {
            glBindTexture(GL_TEXTURE_2D,fontdata);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glColor3f(1,1,1);
            for(int i=0;i<charcount;i++)
            {
                if(znak==chardata[i][0])
                {
                    glBegin(GL_QUADS);
                        glTexCoord2f(chardata[i][1]/256.0,chardata[i][2]/256.0);
                        glVertex2f(x,y);
                        glTexCoord2f((chardata[i][1]+chardata[i][3])/256.0,chardata[i][2]/256.0);
                        glVertex2f(x+chardata[i][3],y);
                        glTexCoord2f((chardata[i][1]+chardata[i][3])/256.0,(chardata[i][2]+chardata[i][4])/256.0);
                        glVertex2f(x+chardata[i][3],y+chardata[i][4]);
                        glTexCoord2f(chardata[i][1]/256.0,(chardata[i][2]+chardata[i][4])/256.0);
                        glVertex2f(x,y+chardata[i][4]);
                    glEnd();
                    break;
                }
            }
            glDisable(GL_BLEND);
        }
};

I propably figured out where is the problem, I just don´t know how to solve it. Some of the characters ID are much larger than 256 and thats the max value that can char hold.

\$\endgroup\$
2
\$\begingroup\$

The codes you have are unicode characters code.

When you use unicode chars, you have to use integers instead of chars for glyph indexing.

And therefore get the unicode representation of each letter from the strings you want to convert for a lookup on the glyph array.

Be aware that with bitmap fonts, it's very difficult to cover the whole unicode universe, at least because there will be a lot of bitmaps to store all glyphs.

\$\endgroup\$
  • 1
    \$\begingroup\$ Not to mention dealing with combining characters and other Unicode goodies. \$\endgroup\$ – Nicol Bolas Dec 25 '15 at 3:12
0
\$\begingroup\$

I'm using the freetype library for international text in my opengl project. This library gives me transparent bitmaps, wich I upload as separate opengl textures and storing id for every symbol I need.

Of course I use more bytes to store my strings of text.

Hope this helps.

\$\endgroup\$
0
\$\begingroup\$

primitive asembly glut it's F char:

GLubyte letterF[ 16 ] =
{
    0xC0, // 11000000
    0xC0, // 11000000
    0xC0, // 11000000
    0xC0, // 11000000
    0xC0, // 11000000
    0xC0, // 11000000
    0xC0, // 11000000
    0xFC, // 11111100
    0xFC, // 11111100
    0xC0, // 11000000
    0xC0, // 11000000
    0xC0, // 11000000
    0xC0, // 11000000
    0xC0, // 11000000
    0xFF, // 11111111
    0xFF  // 11111111
};


......
glBitmap( 8, 16, 0, 0, 0, 0, letterF );
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.