PDA

View Full Version : word wrap? no problem! [SRC | FREE]



JernejL
22-05-2006, 01:26 PM
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.


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:



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:



//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?



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

savage
23-05-2006, 08:25 AM
Excellent, I will see if I can use that somewhere. Thanks for posting it.

JernejL
23-05-2006, 08:57 AM
just wondering, i'd rather have it wrap by whole words, any ideas how would this be easiest to implement?

savage
23-05-2006, 11:55 AM
At the wrap point I would scan backwards until I find a space. I did that for a JEDI-SDL word-wrap function I wrote. I posted it on these forums as well, but can't seem to find it right now.

JernejL
23-05-2006, 04:31 PM
At the wrap point I would scan backwards until I find a space. I did that for a JEDI-SDL word-wrap function I wrote. I posted it on these forums as well, but can't seem to find it right now.

yes i had a similar idea, but what about the characters i already drawn in first line that should then wrap to second line?

savage
23-05-2006, 09:25 PM
I think I created a dynamic array of strings and pre-parsed the text so that each array element contained the string for that line. So my word wrapping code was part of this routine not part of the drawing code.
Then when it comes to drawing, I just loop through the array knowing that each index represents 1 line of text and space them vertically appropriately.

aidave
23-05-2006, 10:39 PM
related function using Jedi



// ----------------------------------------------------------------------------
procedure AIRConsole.AddBrokenDisplay&#40;const aLine&#58; string&#41;;
var
myOriginal&#58; string;
myBroken&#58; string;
myLen&#58; integer;
i&#58; integer;
begin
myOriginal &#58;= aLine;
myLen &#58;= 160;
if StrLen&#40;PAnsiChar&#40;myOriginal&#41;&#41; > myLen then
begin
i &#58;= 0;
while StrLen&#40;PAnsiChar&#40;myOriginal&#41;&#41; > myLen do
begin
myBroken &#58;= StrLeft&#40;myOriginal, myLen&#41;;
myOriginal &#58;= StrRestOf&#40;myOriginal, myLen&#41;;
if i=0 then
Display.Add&#40;myBroken&#41;
else
Display.Add&#40;'\' + myBroken&#41;;
i &#58;= i + 1;
end;
Display.Add&#40;'\' + myOriginal&#41;;
end
else
Display.Add&#40;myOriginal&#41;;
end;


edit: oops, thought this did word wrap too, but it doesnt. nm :oops:

JernejL
24-05-2006, 09:12 PM
I think I created a dynamic array of strings and pre-parsed the text so that each array element contained the string for that line. So my word wrapping code was part of this routine not part of the drawing code.
Then when it comes to drawing, I just loop through the array knowing that each index represents 1 line of text and space them vertically appropriately.

this seems like a good idea, but i think what im going to do is this:

I will parse whole text, and remember at which character the lines should wrap (store it in a fixed array - im expecting maximum like 5-10 so wraps), then cache the data, when i will draw it i will know where will the characters should wrap :idea:

savage
25-05-2006, 08:07 AM
this seems like a good idea, but i think what im going to do is this:

I will parse whole text, and remember at which character the lines should wrap (store it in a fixed array - im expecting maximum like 5-10 so wraps), then cache the data, when i will draw it i will know where will the characters should wrap :idea:

Sounds good as well, and less resource hungry.

JernejL
05-06-2006, 11:58 AM
Ok, it works great now! here is the updated function:

Procedure DrawFont(x, y, mx, my, trans: 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;

wraps: array[0..31] of word; // i dont think my game will ever need / have more than 32 word wraps
maxwrap: integer;
currwrap: integer;
lastspace: integer; // faster word wrap

procedure Vwrap(c: integer);
begin
cw:= 0;
wraps[maxwrap]:= c;
maxwrap:= maxwrap +1;
// since there is no array bounds checking this takes care for safety
if maxwrap > high(wraps) then maxwrap:= high(wraps);
end;

// this function processes the string and remembers all locations where lines should wrap (line returns, word wraps, etc..)
procedure MeasureWraps;
var
i: integer;
begin
maxwrap:= 0;
lastspace:= -1; // faster word wrap

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

if SK <> 0 then begin SK:= SK -1; continue; end; // skipping text coding characters

b:= byte(text[i + 1]); // we need a integer type to use for array access,

if b = 32 then lastspace:= i; // remember last space for word wrapping

if b = 126 then begin sk:= 2; continue; end; // skip ~X~ color coding keyword

// next character would fall over the specified text width dimension, wrap at last known space character
if (wordwrap <> 0) and (cw + trunc(FontGeo[fontn, b].spacing * mx) > wordwrap) then begin
Vwrap(lastspace); continue;
end;

if b = 13 then begin Vwrap(i); continue; end; // return character - go to new line

// add character width to this line text width
cw:= cw + trunc(FontGeo[fontn, b].spacing * mx);

end;
end;

// go to next line
procedure wrap;
begin
cw:= 0;
L:= L + (FontGeo[fontn, 32].H * my);
end;

// process color codes
procedure EatColor; // changes font color depending on keyword
begin
if text[i + 2] = 'W' then glcolor4f(1, 1, 1, trans); // white
if text[i + 2] = 'N' then glcolor4f(0, 0, 0, trans); // none - black
if text[i + 2] = 'R' then glcolor4f(0.9, 0, 0, trans); // red
if text[i + 2] = 'G' then glcolor4f(0, 0.9, 0, trans); // green
if text[i + 2] = 'B' then glcolor4f(0, 0, 0.9, trans); // blue

if text[i + 2] = 'Y' then glcolor4f(1.0, 1, 0, trans); // red
if text[i + 2] = 'T' then glcolor4f(0, 1, 1, trans); // green
if text[i + 2] = 'O' then glcolor4f(1, 0.7734375, 0.09765625, trans); // blue


{yellow #FFFF00
teal #00FFFF
orange #FFC619 }


SK:= 2; // skip 2 chars so the color coding is like '~C~' where C is color
end;


begin

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

// ensure variables are reset for preprocessing

cw:= 0;
SK:= 0;
fillchar(wraps, sizeof(wraps), $FF);
MeasureWraps;

// ensure variables are reset for rendering
cw:= 0;
L:= 0;
SK:= 0;
currwrap:= 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:= SK -1; continue; end;

b:= byte(text[i + 1]); // we need a integer type to use for array access

if b = 126 then begin eatcolor; continue; end;

// find out if we are supposed to wrap at this character
if currwrap < maxwrap then
if wraps[currwrap] = i then begin wrap; currwrap:= currwrap +1; continue; end;

// get tex coords from array
ta:= FontGeo[fontn, b].X / 256;
tb:= FontGeo[fontn, b].X / 256 + FontGeo[fontn, b].W / 256;
tc:= FontGeo[fontn, b].Y / 256;
td:= FontGeo[fontn, b].Y / 256 + FontGeo[fontn, b].H / 256;

// build vertices
va:= cw; // top left
vb:= va + (FontGeo[fontn, b].W * mx); // top right
vc:= (FontGeo[fontn, b].YOFS * my) + L; // bottom left
vd:= vc + (FontGeo[fontn, b].H * my); // bottom right

// crunch
gltexcoord2f(ta, tc); glvertex2fwin(x + va, y + vc);
gltexcoord2f(ta, td); glvertex2fwin(x + va, y + vd);
gltexcoord2f(tb, td); glvertex2fwin(x + vb, y + vd);
gltexcoord2f(tb, tc); glvertex2fwin(x + vb, y + vc);

// add character size to left edge
cw:= cw + trunc(FontGeo[fontn, b].spacing * mx);

end;

glend;

end;

JernejL
23-06-2006, 10:32 AM
This board needs a tumbleweed smiley (or some people that give feedback).

savage
23-06-2006, 11:58 AM
I have not had a chance to try your code, but if you say it works I believe you :).

JernejL
27-06-2006, 08:38 AM
lol, ofcourse it works :)

JernejL
12-07-2006, 12:07 PM
ok, i now realised i need a function to get text size extents when word-wrapped, so i made another function, the word wrap function also got some fixes, so if you happen to have used this function you should update it.




Procedure DrawText&#40;x, y, mx, my, trans&#58; single; const text&#58; string; fontn, wordwrap&#58; integer&#41;;
var
i&#58; integer;
b&#58; byte;
cw&#58; integer;
ta, tb, tc, td&#58; single;
va, vb, vc, vd&#58; single;

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

wraps&#58; array&#91;0..31&#93; of word; // i dont think my game will ever need / have more than 32 word wraps
maxwrap&#58; integer;
currwrap&#58; integer;
lastspace&#58; integer; // faster word wrap

procedure Vwrap&#40;c&#58; integer&#41;;
begin
cw&#58;= 0;
wraps&#91;maxwrap&#93;&#58;= c;
maxwrap&#58;= maxwrap +1;
// since there is no array bounds checking this takes care for safety
if maxwrap > high&#40;wraps&#41; then maxwrap&#58;= high&#40;wraps&#41;;
end;

// this function processes the string and remembers all locations where lines should wrap &#40;line returns, word wraps, etc..&#41;
procedure MeasureWraps;
var
i&#58; integer;
begin
maxwrap&#58;= 0;
lastspace&#58;= -1; // faster word wrap

for i&#58;= 1 to length&#40;text&#41; do begin

if SK <> 0 then begin SK&#58;= SK -1; continue; end; // skipping text coding characters

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

if b = 32 then lastspace&#58;= i; // remember last space for word wrapping

if b = 126 then begin sk&#58;= 2; continue; end; // skip ~X~ color coding keyword

// next character would fall over the specified text width dimension, wrap at last known space character
if &#40;wordwrap <> 0&#41; and &#40;cw + trunc&#40;FontGeo&#91;fontn, b&#93;.spacing * mx&#41; > wordwrap&#41; then begin
Vwrap&#40;lastspace&#41;; continue;
end;

if b = 13 then begin Vwrap&#40;i&#41;; continue; end; // return character - go to new line

// add character width to this line text width
cw&#58;= cw + trunc&#40;FontGeo&#91;fontn, b&#93;.spacing * mx&#41;;

end;
end;

// go to next line
procedure wrap;
begin
cw&#58;= 0;
L&#58;= L + &#40;FontGeo&#91;fontn, 32&#93;.H * my&#41;;
end;

// process color codes
procedure EatColor; // changes font color depending on keyword
begin
if text&#91;i + 1&#93; = 'W' then glcolor4f&#40;1, 1, 1, trans&#41;; // white
if text&#91;i + 1&#93; = 'N' then glcolor4f&#40;0, 0, 0, trans&#41;; // none - black
if text&#91;i + 1&#93; = 'R' then glcolor4f&#40;0.9, 0, 0, trans&#41;; // red
if text&#91;i + 1&#93; = 'G' then glcolor4f&#40;0, 0.9, 0, trans&#41;; // green
if text&#91;i + 1&#93; = 'B' then glcolor4f&#40;0, 0, 0.9, trans&#41;; // blue

if text&#91;i + 1&#93; = 'Y' then glcolor4f&#40;1.0, 1, 0, trans&#41;; // yellow
if text&#91;i + 1&#93; = 'T' then glcolor4f&#40;0, 1, 1, trans&#41;; // teal
if text&#91;i + 1&#93; = 'O' then glcolor4f&#40;1, 0.7734375, 0.09765625, trans&#41;; // orange

SK&#58;= 2; // skip 2 chars so the color coding is like '~C~' where C is color
end;


begin

if length&#40;text&#41; = 0 then exit; // idiot proof fuse

// ensure variables are reset for preprocessing

cw&#58;= 0;
SK&#58;= 0;
fillchar&#40;wraps, sizeof&#40;wraps&#41;, $FF&#41;;
MeasureWraps;

// ensure variables are reset for rendering
cw&#58;= 0;
L&#58;= 0;
SK&#58;= 0;
currwrap&#58;= 0;

glBindTexture&#40;GL_TEXTURE_2D, Font.tex&#91;fontn&#93;.GLID&#41;;
glBegin&#40;GL_quads&#41;;

for i&#58;= 1 to length&#40;text&#41; do begin

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

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

if b = 126 then begin eatcolor; continue; end;

// find out if we are supposed to wrap at this character
if currwrap < maxwrap then
if wraps&#91;currwrap&#93; = i then begin wrap; currwrap&#58;= currwrap +1; continue; end;

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

// build vertices
va&#58;= cw; // top left
vb&#58;= va + &#40;FontGeo&#91;fontn, b&#93;.W * mx&#41;; // top right
vc&#58;= trunc&#40;&#40;FontGeo&#91;fontn, b&#93;.YOFS * my&#41; + L&#41;; // bottom left, this needs to be trunc-ed here and nowhere else!
vd&#58;= trunc&#40;vc + &#40;FontGeo&#91;fontn, b&#93;.H * my&#41;&#41;; // bottom right, this needs to be trunc-ed here and nowhere else!

// 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;fontn, b&#93;.spacing * mx&#41;;

end;

glend;

end;

function GetTextExtents&#40;mx, my&#58; single; const text&#58; string; fontn, wordwrap&#58; integer&#41;&#58; IRect;
var
i&#58; integer;
b&#58; byte;
cw&#58; integer;

// skip this much of characters from being parsed
SK&#58; integer;

LongestLine&#58; single;
LinesAll&#58; single;

maxwrap&#58; integer;
lastspace, lastwrap&#58; integer; // faster word wrap
lastspacew&#58; single;

procedure Vwrap&#40;linew&#58; single&#41;;
begin
if cw > linew then LongestLine&#58;= linew;
cw&#58;= 0;
lastspacew&#58;= 0;
maxwrap&#58;= maxwrap +1;
end;

begin

if length&#40;text&#41; = 0 then exit; // idiot proof fuse

// ensure variables are reset for preprocessing

cw&#58;= 0;
SK&#58;= 0;
LongestLine&#58;= 0;
lastwrap&#58;= 0;
LinesAll&#58;= 1;
lastspacew&#58;= 0;

maxwrap&#58;= 0;
lastspace&#58;= -1; // faster word wrap

for i&#58;= 1 to length&#40;text&#41; do begin

if SK <> 0 then begin SK&#58;= SK -1; continue; end; // skipping text coding characters

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

if b = 32 then begin lastspace&#58;= i; lastspacew&#58;= cw end; // remember last space for word wrapping

if b = 126 then begin sk&#58;= 2; continue; end; // skip ~X~ color coding keyword

// next character would fall over the specified text width dimension, wrap at last known space character
if &#40;wordwrap <> 0&#41; and &#40;cw + trunc&#40;FontGeo&#91;fontn, b&#93;.spacing * mx&#41; > wordwrap&#41; then begin
Vwrap&#40;lastspacew&#41;; continue;
end;

if b = 13 then begin Vwrap&#40;cw&#41;; continue; end; // return character - go to new line

// add character width to this line text width
cw&#58;= cw + trunc&#40;FontGeo&#91;fontn, b&#93;.spacing * mx&#41;;

end;

LinesAll&#58;= LinesAll + maxwrap;

result.left&#58;= 0;
result.top&#58;= 0;
if LongestLine <> 0 then result.Right&#58;= trunc&#40;LongestLine&#41; else result.Right&#58;= cw;
result.Bottom&#58;= trunc&#40;LinesAll * &#40;FontGeo&#91;fontn, 32&#93;.H * my&#41;&#41;;

end;

paul_nicholls
12-07-2006, 11:20 PM
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.


Procedure DrawFont&#40;x, y, mx, my&#58; single; const text&#58; string; fontn, wordwrap&#58; integer&#41;;
var
i&#58; integer;
b&#58; byte;
cw&#58; integer;
ta, tb, tc, td&#58; single;
va, vb, vc, vd&#58; single;

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

procedure wrap;
begin
cw&#58;= 0;
L&#58;= L + &#40;FontGeo&#91;32&#93;.H * my&#41;;
end;

procedure EatColor; // changes font color depending on keyword
begin
if text&#91;i + 2&#93; = 'W' then glcolor3f&#40;1, 1, 1&#41;;
if text&#91;i + 2&#93; = 'N' then glcolor3f&#40;0, 0, 0&#41;;
if text&#91;i + 2&#93; = 'R' then glcolor3f&#40;1, 0, 0&#41;;
if text&#91;i + 2&#93; = 'G' then glcolor3f&#40;0, 1, 0&#41;;
if text&#91;i + 2&#93; = 'B' then glcolor3f&#40;0, 0, 1&#41;;
SK&#58;= 2; // skip 2 chars so the color coding is like ~G~
end;

begin

if length&#40;text&#41; = 0 then exit; // idiot proof fuse

// ensure variables are reset
cw&#58;= 0;
L&#58;= 0;
SK&#58;= 0;

glBindTexture&#40;GL_TEXTURE_2D, Font.tex&#91;fontn&#93;.GLID&#41;;
glBegin&#40;GL_quads&#41;;

for i&#58;= 0 to length&#40;text&#41; 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:



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:



//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?



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

No offense dude, but any chance you can add indentation in your source code?

No indentation...SHUDDER....

Cheers,
Paul.

JernejL
16-07-2006, 01:04 PM
No offense dude, but any chance you can add indentation in your source code?

No indentation...SHUDDER....

Cheers,
Paul.

hehe, you are right, but the reason why the code lacks indentation is because of my syntax highlighting setup, and because sometimes too indented code becomes too wide to be on screen and requires too much horisontal scrolling.

i bet ill get flamed for saying that :roll: