You probably wondered in early days how to add word wrap and line returns to your opengl text routines, basicly this is just what you want, this function will draw a text and wrap it by character (not words!) to fir the width you want.

Code:
Procedure DrawFont(x, y, mx, my: single; const text: string; fontn, wordwrap: integer);
var
i: integer;
b: byte;
cw: integer;
ta, tb, tc, td: single;
va, vb, vc, vd: single;

// current left edge
L: single;
// skip this much of characters from being parsed
SK: integer;

procedure wrap;
begin
cw:= 0;
L:= L + (FontGeo[32].H * my);
end;

procedure EatColor; // changes font color depending on keyword
begin
if text[i + 2] = 'W' then glcolor3f(1, 1, 1);
if text[i + 2] = 'N' then glcolor3f(0, 0, 0);
if text[i + 2] = 'R' then glcolor3f(1, 0, 0);
if text[i + 2] = 'G' then glcolor3f(0, 1, 0);
if text[i + 2] = 'B' then glcolor3f(0, 0, 1);
SK:= 2; // skip 2 chars so the color coding is like ~G~
end;

begin

if length(text) = 0 then exit; // idiot proof fuse

// ensure variables are reset
cw:= 0;
L:= 0;
SK:= 0;

glBindTexture(GL_TEXTURE_2D, Font.tex[fontn].GLID);
glBegin(GL_quads);

for i:= 0 to length(text) do begin

if SK <> 0 then begin SK&#58;= SK -1; continue; end;

b&#58;= byte&#40;text&#91;i + 1&#93;&#41;; // we need a integer type to use for array access,

// next character would wrap
if &#40;wordwrap <> 0&#41; and &#40;cw + trunc&#40;FontGeo&#91;b&#93;.spacing * mx&#41; > wordwrap&#41; then wrap;

// return character - go to new line
if b = 13 then begin wrap; continue; end;
// ~X~ color coding keyword
if b = 126 then begin eatcolor; continue; end;

// get tex coords from array
ta&#58;= FontGeo&#91;b&#93;.X / 256;
tb&#58;= FontGeo&#91;b&#93;.X / 256 + FontGeo&#91;b&#93;.W / 256;
tc&#58;= FontGeo&#91;b&#93;.Y / 256;
td&#58;= FontGeo&#91;b&#93;.Y / 256 + FontGeo&#91;b&#93;.H / 256;

// build vertices
va&#58;= cw;                                          // top left
vb&#58;= va + &#40;FontGeo&#91;b&#93;.W * mx&#41;;                    // top right
vc&#58;= &#40;FontGeo&#91;b&#93;.YOFS * my&#41; + L;  // bottom left
vd&#58;= vc + &#40;FontGeo&#91;b&#93;.H * my&#41;;                    // bottom right

// crunch
gltexcoord2f&#40;ta, tc&#41;; glvertex2fwin&#40;x + va, y + vc&#41;;
gltexcoord2f&#40;ta, td&#41;; glvertex2fwin&#40;x + va, y + vd&#41;;
gltexcoord2f&#40;tb, td&#41;; glvertex2fwin&#40;x + vb, y + vd&#41;;
gltexcoord2f&#40;tb, tc&#41;; glvertex2fwin&#40;x + vb, y + vc&#41;;

// add character size to left edge
cw&#58;= cw + trunc&#40;FontGeo&#91;b&#93;.spacing * mx&#41;;

end;

glend;

end;
character support records:

Code:
Glyph = packed record
X, Y, W, H, YOFS, SPACING&#58; byte;
end;

FontGeo&#58; array&#91;0..255&#93; of Glyph;
license: none, you can even eat it or whatever you want, but i take no responsibility for aynthing.

2d opengl routines:

Code:
//this draws a vertex in windows coordinate system
procedure glvertex2fwin&#40;const x, y&#58; single&#41;;
begin
glvertex2f&#40;x, win_height - y&#41;;
end;
how to get into this 2d mode?


Code:
// Dwarf with Axe - GAMEDEV forums&#58; 18 July 2002 6&#58;12&#58;57 PM
//
// There have been thousands of posts along the lines of
// "How do I do 2d in OpenGL" to "Duuuhde, I wunt too maek
// a two dee gaem in ohpun jee el; how do eye set uhp two dee???!?"
//
// I have developed a simple, nice, pretty way for all of you to have your 2D fun.

procedure GlEnable2D;
var
vport&#58; array&#91;0..3&#93; of integer;
begin
glGetIntegerv&#40;GL_VIEWPORT, @vPort&#41;;

glMatrixMode&#40;GL_PROJECTION&#41;;
glPushMatrix;
glLoadIdentity;
glOrtho&#40;0, vPort&#91;2&#93;, 0, vPort&#91;3&#93;, -1, 1&#41;;

glMatrixMode&#40;GL_MODELVIEW&#41;;
glPushMatrix;
glLoadIdentity;
end;

procedure GlDisable2D;
begin
glMatrixMode&#40;GL_PROJECTION&#41;;
glPopMatrix;
glMatrixMode&#40;GL_MODELVIEW&#41;;
glPopMatrix;
end;