DEATHSHADOW'S
MADNESS
Madness and You, Perfect together!

  1. Top of Page
  2. Main Menu
  3. Page Content
  4. Page Extras
  5. Bottom of Page

Drawing Glyphs

Since we have our kerning data loaded in an array, and our image bound to a texture, it's time to draw a character. First we need to scale our start/end of a character into a 2d float vector 0..1 to 'slide' the part of the texture we want to show into place. To do this I just take the byte value of a character, mod it by 32 and then divide it by 32, and that's our start on the X axis. The Y axis is just a integer divide by 32, minus one (since we have no 0..31 row), and divide by three (the number of rows in our image).


    tsX:=(ord(ch) mod 32)/32; 
    tsY:=((ord(ch) div 32)-1)/3;

From our starting coordinate we need to figure out the end. When I loaded the font I made two variables, charAddWdith and charAddHeight, specially scaled as our pixel width minus one, so that we don't accidentally show a row of pixels from the next character in the image.


    { texture2f scale values }
    charAddWidth:=(charWidth-1)/sourceWidth;
    charAddHeight:=(charHeight-1)/sourceHeight;

Making our end coordinates easy enough to figure out, just add the above to values.


    teX:=tsX+charAddWidth;
    teY:=tsY+charAddHeight;

Next up we need the rendering coordinates. First we need to perform the kerning. I've got a variable defined that holds the kerning data of the last character, or zero's if we've not drawn one or decided to reposition the current 'cursor' location. First, a comparison routine:


function kernCompare(prev,this:tglKernedChar):glFloat;
var
  t:word;
  n,test:glFloat;
begin
  n:=-999;
  for t:=0 to 2 do begin
    test:=prev[t+3]+this[t];
    if test>n then n:=test;
  end;
  kernCompare:=n;
end;

Which we'll call to figure out our new rendering position. I store these in another set of variables should I decide to modify them further, and as with the texture coordingate we have a scaled width and height pre-calculated from when we loaded the font. At this point we'll have calculated all the math, so we can update our last kerned character to the current one.


    renderX+=(
      kernCompare(lastKern,kernTable[ord(ch)]) +
      charSpacing
    )*charScale;

    vsX:=renderX;
    vsY:=renderY;
    veX:=renderX+charScaleWidth;
    veY:=renderY+charScaleHeight;

    lastKern:=kernTable[ord(ch)];

Now that we have all our values, we can call openGL to render the glyph. I unbind the texture when done just so that I don't accidentally have something render in the last character elsewhere in my code.


    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
    glBindTexture(GL_TEXTURE_2D,texture);
    glBegin(GL_QUADS);
      glTexCoord2f(tsX,tsY);
      glVertex3f(vsX,vsY,renderZ);
      glTexCoord2f(teX,tsY);
      glVertex3f(veX,vsY,renderZ);
      glTexCoord2f(teX,teY);
      glVertex3f(veX,veY,renderZ);
      glTexCoord2f(tsX,teY);
      glVertex3f(vsX,veY,renderZ);
    glEnd;
    glBindTexture(GL_TEXTURE_2D,0);

  1. Top of Page
  2. Main Menu
  3. Page Content
  4. Page Extras
  5. Bottom of Page