|
This tutorial is a bit more of a comparison with using different methods for using fonts. Again, we will be using the NSGLFont class. We will look at the four different types of NSGLFont that are now available, as well as see the kinds of changes that are made for each of them to work
First, a bit of extra code that I created. In Tutorial 7, I mentioned that I didn't know how to get the size of a letter. This led to an evenly spaced font, even when the font should have been variable width. Here is how you can find the width of each character:
x_offset[i] = (unsigned int)[font widthOfString: [NSString stringWithCString: jstr]] +1;
|
Now, let's look at bitmapFont. This font was covered in the last tutorial, and is made by using the glBitmap command. It's a quick font to create, and is generally easy to work with. On the other hand, a glBitmap can't really be scaled, moved, rotated, translated, or have any really interesting thing done to it.
glNewList( base+i,GL_COMPILE);
glBitmap(width[i],height[i],0,0,x_offset[i],0,data[i]);
glEndList();
|
This next one is very similar to the bitmapFont, and is a pixmapFont. Instead of using the glBitmap command, this uses glDrawPixels. Using this font means that we can have antialiased text, but this font isn't as easy to work with. Changing the color of a font using the pixmapFont format is much more difficult than for glBitmap, since we have to change the color of the actual pixels and not just the raster color. We can zoom in or out by using glZoomPixels. This font looks nicer than the bitmapFont, but has a bit more set up.
colorspace = CGColorSpaceCreateDeviceRGB();
alphaInfo = kCGImageAlphaPremultipliedLast;
glNewList( base+i,GL_COMPILE);
glDrawPixels(width[i],height[i],GL_RGBA,GL_UNSIGNED_BYTE,data[i]);
glBitmap(0,0,0,0,x_offset[i],0,NULL);
glEndList();
|
Finally we start on extruded fonts. Extruded fonts can be easily rotated, translated, colored, scaled or any other OpenGL operation you might like to use. Unfortunately, they are made of polygons, so they eat your polygon count. First, we look at cheapOutlineFont. This font type limits the number of polygons used in any one character, however, this can mean that the character is simply not rendered properly. The colorspace is gray scale again. We try to determine the lowest number of vertices by a simple scan across a row. We then extrude the font using this scan. We scale these down, and we the translate so that we aren't writing everything on top of itself.
One of the worst aspects of this font is that you cannot use any color you want, because it will not necessarily look good. Most of the time, transparency will make the fonts looks plain wierd, with lines going through them.
glNewList( base+i,GL_COMPILE);
glBegin(GL_QUADS);
for( n = 0; n < nVertices*4; n += 4 ) {
glVertex3f(vertex[n+0]*xdiff, vertex[n+1]*ydiff, 0);
glVertex3f(vertex[n+2]*xdiff, vertex[n+1]*ydiff, 0);
glVertex3f(vertex[n+2]*xdiff, vertex[n+3]*ydiff, 0);
glVertex3f(vertex[n+0]*xdiff, vertex[n+3]*ydiff, 0); }
glEnd();
glTranslatef(x_offset[i]*xdiff, 0, 0);
glEndList();
|
Last, we look at outlineFont. This is the most costly in terms of setup of all the fonts. This is the nicest of the fonts as well. There are no color restrictions with this font. This font type has all the previously mentioned benefits of an extruded font, but uses on average more polygons and on average takes more time to be set up.
This font is a height map of an antialiased font drawing. It does not look as nice as an antialiased pixel based font if there is no rotation or translation.
glNewList( base+i,GL_COMPILE);
glBegin( GL_QUADS );
maxX = 0;
for( x = 0; x < max_width - STEPSIZE; x += STEPSIZE ) {
for( y = 0; y < max_height - STEPSIZE; y += STEPSIZE ) {
if( [self getHeight:i atX:x atY:y] == 0 &&
[self getHeight:i atX:x atY:y+STEPSIZE] == 0 &&
[self getHeight:i atX:x+STEPSIZE atY:y+STEPSIZE] == 0 &&
[self getHeight:i atX:x+STEPSIZE atY:y] == 0);
else {
usex = (float)x*xdiff; usey = (float)y*ydiff;
usez = (float)[self getHeight:i atX:x atY:y]*z/255;
glVertex3f(usex, usey, usez);
usex = (float)x*xdiff; usey = (float)(y+STEPSIZE)*ydiff;
usez = (float)[self getHeight:i atX:x atY:y+STEPSIZE]*z/255;
glVertex3f(usex, usey, usez);
usex = (float)(x+STEPSIZE)*xdiff; usey = (float)(y+STEPSIZE)*ydiff;
usez = (float)[self getHeight:i atX:x+STEPSIZE atY:y+STEPSIZE]*z/255;
glVertex3f(usex, usey, usez);
usex = (float)(x+STEPSIZE)*xdiff; usey = (float)y*ydiff;
usez = (float)[self getHeight:i atX:x+STEPSIZE atY:y]*z/255;
glVertex3f(usex, usey, usez); } } }
glEnd();
glTranslatef(x_offset[i]*xdiff, 0, 0);
glEndList();
|
|
|