Fast Ortho Text and Graphics

I am doing a sim, and I have Text on an ortho viewport, this text rarly changes and it slows my frame rate down(it takes up alot of the screen), I am thinking i should write this into the framebuffer to speed things up, but am not sure how to do this or if this is the right thing to do. any suggestions?

Touching the framebuffer by hand is forbidden

Joke aside, no, don’t touch the framebuffer on your own. There are some reasons for this. You can’t touch it directly (and as easy) because it’s in the videomemory, and not in the main memory, i.e. you can’t just obtain a pointer to the buffer. You can draw directly to the framebuffer with glDrawPixels, but this is one of the slowest function available (trust me, you don’t want to use this in speed critical environments unless you got a $5.000+ graphics board which may do this abit faster).

The fastets and simplest way is actually to setup an orthographic projection matrix, and draw each letter as a textured quad, which I understand you do. This shouldn’t be slow at all.

If you don’t get it to work that fast, post some code and maybe we can find whats wrong.

Im doing Bitmap texts, do you think i should use Textures instead?
here is a code snipit that sets up the text manager.

MyFont.CreateFont(FontHeight,
nWidth,
nEscapement,
nOrientation,
nWeight,
bItalic,
bUnderline,
cStrikeOut,
nCharSet,
nOutPrecision,
nClipPrecision,
nQuality,
nPitchAndFamily,
FaceName);

SelectObject (hdc, MyFont);  


GetCharWidth32(hdc,0,255,Buffer);

FontSizeListVector.push_back(Buffer);
if(FontHeight == 48)
	font = 0;
if(FontHeight == 18)
	font = 1;
if(FontHeight == 12)
	font = 2;
for(int i = 0; i < 256; i++)
	Fonts[font][i] = Buffer[i];

wglUseFontBitmaps (hdc, 0, 255, FontIndexBase + FontIndexCounter * FontIndexIncrement);  

// then i draw it (centering it)
int StringSize = 0;
for (i = 0 ; i < strlen(string); i++)
StringSize += Fonts[FontNumber][string[i]];
if(Centered == 1)
ScreenPos = x - ((float)StringSize/(2.0 * (float)ScreenSize));
else
ScreenPos = x - ((float)StringSize/(float)ScreenSize);
////TRACE("ScreenPos = %f
",ScreenPos);
glRasterPos3f(ScreenPos, y, z);
}
else
{
glRasterPos3f(x,y,z);
}
glListBase (FontIndexBase + FontNumber * FontIndexIncrement);
//glColor3f (red, green, blue);
glCallLists (strlen(string), GL_UNSIGNED_BYTE, string);

well, i dont think i would write to the frame buffer, but more use the stencil buffer or something, so i would not have to do other calculations for the pixels on the screen being used by the Text

so i need speedy text, that always faces the observer… (im doing 2d text as well this same way on the ortho viewport, which is pretty slow)

Definately change text to textured quads. Bitmap text can be very slow.

yup
i just grabbed a NeHe demo, and wonder why I did not do this in the first place… but one last question…
Does this textured quad work for 3d placed text? should i just billboard the stuff? (which is no problem at all) just wondering… with bitmap text you dont have to worry about that… maybe that is what i was thinking… (not very well i admit

yeah, you can place the textured quad in 3d space and do things with it. however, i usually find it easier to set up an orthographic context and draw my 2d elements that way. i generally turn off depth buffering to avoid any problems. (in general, my 2d stuff is of the HUD/overlay type, and should always get drawn.)

by rendering your 2d in a straight-on orthographic context, it becomes much easier to place items in the proper place. furthermore, if you use the ortho view only for placing 2d elements, you can set up its coordinate system in whatever manner you choose.

[B} by rendering your 2d in a straight-on orthographic context, it becomes much easier to place items in the proper place. furthermore, if you use the ortho view only for placing 2d elements, you can set up its coordinate system in whatever manner you choose.[/b]

One question on that, would it be easier to make one texture that has all the letters, then put the letters in based on texture coordinates (I’d assume it were a tesselated quad then) or make a quad for each letter? Woudln’t that get rather labor/quad intensive for a lot of text?

right right
im using 3D text as well as 2D text, to label important land marks and such.
so i figger just billboard the quads.

I just got the NeHe Texture Font demo, they have a 256x256 texture of the ascii table, and you can just pick letter according to the coords. seems easy enough, you could probably make them tri-strips as well, but that may make the text coords more confusing… buts its a quad per letter, which is faster than bitmaped or stroke fonts… and i got the need for speed!

For drawing in 2D, here’s an example from the opengl.org faq (seems nicer than using glOrtho2D):

As an example, here’s how to draw a full-screen quad at the zNear clipping plane:

glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
glLoadIdentity ();
glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();
glBegin (GL_QUADS);
glVertex3i (-1, -1, -1);
glVertex3i (1, -1, -1);
glVertex3i (1, 1, -1);
glVertex3i (-1, 1, -1);
glEnd ();
glPopMatrix ();
glMatrixMode (GL_MODELVIEW);
glPopMatrix ();

Your application might want the quad to have a maximum Z value, in which case 1 should be used for the Z value instead of -1.

If you insert gluOrtho2D(0, screenWidth, screenHeight, 0) after

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

where screenWidth and screenHeight is the size of the window, you can pass vertices in screen coordinates, which is quite handy.

If you only load the identity matrix, you will have to somehow convert the actual screen coordinate you want, to the range [-1.0, 1.0]. But this method, on the other hand, is resolution independant, which is good.

Just a tip…