Deathshadow's Madness
Madness and you, perfect together

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);