Well I'm no OpenGL expert, but I have written a font unit of my own which makes use of simple textures. I imagine that OpenGL would probably have to use similar techniques. Unless you really want to work with True Type Fonts or other such formats instead.

There are some issues with using traditional Font formats aswell; Usually you don't get the best cross-platform results they usually are not 100% the same at different resolutions and on other systems depending on what fonts and what format you are using.

The texture image approach is much easier and will gaurentee that you'll get exactly 100% the same look on every system and every platform. Plus you can pretty them up more at design time. It does however take more work to create each new font and may take up more space, depending on the font size and number of characters supported in your font's 'character set(s)'.

Here is my own personal FontUnit.pas that I use with JEDI-SDL in all my games:
[pascal]unit FontUnit;


interface

uses
sdl,
sdlutils,

GraphicsUnit;

const
CharSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!?.,:;"' + #39 + #92 + '/|+-=_@#$%^&*()' + #123 + #125 + '[]<>';

type
TFont = class(TObject)
FontData: PSDL_Surface;
FontColor: Cardinal;
CharWidth, CharHeight: Integer;

constructor LoadFromFile(Width, Height, Color: Cardinal; FileName: String);
destructor Free;
procedure DrawText(Dest: PSDL_Surface; X, Y: Integer; Text: String);
function GetTextWidth(Text: String): Cardinal;
end;


implementation


function GetCharNum(ch: Char): Integer;
begin
Result := -1;
if (ch < #32) or
((ch > #95) and (ch < #123)) or
(ch > #125) then
Exit;

case (ch) of
'A' : Result := 1;
'B' : Result := 2;
'C' : Result := 3;
'D' : Result := 4;
'E' : Result := 5;
'F' : Result := 6;
'G' : Result := 7;
'H' : Result := 8;
'I' : Result := 9;
'J' : Result := 10;
'K' : Result := 11;
'L' : Result := 12;
'M' : Result := 13;
'N' : Result := 14;
'O' : Result := 15;
'P' : Result := 16;
'Q' : Result := 17;
'R' : Result := 18;
'S' : Result := 19;
'T' : Result := 20;
'U' : Result := 21;
'V' : Result := 22;
'W' : Result := 23;
'X' : Result := 24;
'Y' : Result := 25;
'Z' : Result := 26;
'0' : Result := 27;
'1' : Result := 28;
'2' : Result := 29;
'3' : Result := 30;
'4' : Result := 31;
'5' : Result := 32;
'6' : Result := 33;
'7' : Result := 34;
'8' : Result := 35;
'9' : Result := 36;
'!' : Result := 37;
'?' : Result := 38;
'.' : Result := 39;
',' : Result := 40;
':' : Result := 41;
';' : Result := 42;
'"' : Result := 43;
#39 : Result := 44;
#92 : Result := 45;
'/' : Result := 46;
'|' : Result := 47;
'+' : Result := 48;
'-' : Result := 49;
'=' : Result := 50;
'_' : Result := 51;
'@' : Result := 52;
'#' : Result := 53;
'$' : Result := 54;
'%' : Result := 55;
'^' : Result := 56;
'&' : Result := 57;
'*' : Result := 58;
'(' : Result := 59;
')' : Result := 60;
#123 : Result := 61;
#125 : Result := 62;
'[' : Result := 63;
']' : Result := 64;
'<' : Result := 65;
'>' : Result := 66;
end;
end;


constructor TFont.LoadFromFile(Width, Height, Color: Cardinal; FileName: String);
begin
CharWidth := Width;
CharHeight := Height;
FontColor := Color;
FontData := LoadImage(FileName, True);
end;
destructor TFont.Free;
begin
SDL_FreeSurface(FontData);
end;
procedure TFont.DrawText(Dest: PSDL_Surface; X, Y: Integer; Text: String);
var
i: Integer;
xChar: Integer;
SrcRect, DestRect: TSDL_Rect;
begin
if (Length(Text) > 0) then
begin
for i := 0 to Length(Text) - 1 do
begin
// Find Character tile
xChar := GetCharNum(Text[i + 1]) - 1;

SrcRect := SDLRect(xChar * CharWidth, 0, CharWidth, CharHeight);
DestRect := SDLRect(X + i * CharWidth, Y, CharWidth, CharHeight);
// Draw Letter
SDL_BlitSurface(FontData, @SrcRect, Dest, @DestRect);
end;
end;
end;
function TFont.GetTextWidth(Text: String): Cardinal;
begin
Result := Length(Text) * CharWidth;
end;

end.[/pascal]

Oh yeah ah--free to use... ..give permission... ...freely distribute... [size=9px]*blah blah*[/size]... err--FREE!