Nehe lesson 43 questions (freetype fonts)

I wrapped this lesson in a class and it works pretty well, but I can’t figure out how to change the color of the font. Also the font is not transparent: the background color of the letters is whatever the current opengl color is set to.

  1. How do you set the font color?
  2. Is it possible to make the background transparent?

thanks,
William

I’m having a problem that might be related to yours. Maybe set the background Alpha to 0 via glClearColor().

I was trying to use Freetype, but it was becoming a pain. I couldn’t get it to work, so I had to settle without Text antialiasing. Have you looked at NEHE lesson 17? It offers an alternative method for rendering text, and you might be interested or settle for it, if you cannot solve your problem.

I am already setting the clear color alpha to 0.

I tried the ‘hacked’ version of lesson 43 (see the errata page) and it works even better. I can set the color, it looks great etc, but it runs at about 1/3 the speed of the non-hacked version.

Would anyone have an idea why it’s so slow? This is the slow code:

glPushAttrib(GL_CURRENT_BIT | GL_PIXEL_MODE_BIT | GL_ENABLE_BIT);

glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glDisable(GL_LIGHTING);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glGetIntegerv(GL_UNPACK_ALIGNMENT, &old_unpack);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glPixelTransferf(GL_RED_SCALE, r);
glPixelTransferf(GL_GREEN_SCALE, g);
glPixelTransferf(GL_BLUE_SCALE, b);
glPixelTransferf(GL_ALPHA_SCALE, a);

glRasterPos2f(fx, fy);

for(i=0; str[i]; i++) {
cdata = chars[str[i]];
move_raster_x(cdata->left);
move_raster_y(cdata->move_up);
glDrawPixels(cdata->w, cdata->h, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, cdata->data);
move_raster_y(-cdata->move_up);
move_raster_x(cdata->advance - cdata->left);
}

glPixelStorei(GL_UNPACK_ALIGNMENT, old_unpack);
glPopAttrib();

I found the slow opengl call:

glGetIntegerv(GL_UNPACK_ALIGNMENT, &old_unpack);

This takes 11 ms! Why?

I was going to suggest for your original problem to set, glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE). This would allow the incoming texture color to replace the underlying color.

I have heard that the glPixelTransfer operations are slow, but I am not sure if this is the source of that problem. Does Lesson 43 use glPixelTransfer, as well?

Frankly, I wish I could get Lesson 43 to work with my compiler (VC 6). Instead I am using wglUseFontBitmaps method, which does not offer anti-aliased text. I thought about using the Lesson 17 method, but I don’t like to implement anything that I don’t have a fair understanding of.

glDrawPixels(cdata->w, cdata->h, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, cdata->data);

Never ever do this if you want performance. If you want to draw something to the screen, then it should be in a texture and you should render with it.

I added
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)

and that took care of the font background not being transparent. This is for the ‘non-hacked’ version of lesson 43 and it’s running at 160 fps doing a lot of drawing. The only remaining problem is to get the font (foreground) color to be settable. Maybe the problem is that I haven’t figured out how to use luminance / alpha:

glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
width,
height,
0,
GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE,
expanded_data
);

Is it possible to set the color with this? If I set the luminance byte from 0 to 255, I get black to white (grayscale) text color.

William

Well, my understanding of luminance is that it is only an intensity setting. I can’t see off hand, how color can be set with it. As far as I can tell, glColor is the only thing that needs to be set (although Blending might have to be off, to avoid undesired effects), but than again, I am certainly no expert, and hence my predicament.

I’m glad you got Lesson 43 working. I am considering trying out Lesson 17, so to utilize text anti-aliasing, but I need to become a little bit more familiar with it. The code doesn’t look so bad, but I hope implementation is not hassle.

Is it possible to set the color with this?

More importantly, why would you want to? Baking the color into the font is the wrong way to go. What you want is a font that can be rendered with any color. This is not difficult to achieve.

The pixel data you get out of FreeType should be greyscale, in bytes. So you can upload that to a GL_INTENSITY texture (both the internal format and the upload data format should be GL_INTENSITY).

Then, use GL_MODULATE for your TexEnv, and turn on blending with a standard alpha blend (based on the source alpha, of course). If you need to preserve the destination alpha, then you’ll need to use blend function separation.

Yes I do get a greyscale from the freetype font. I didn’t know about GL_MODULATE etc. I’ll look into that. In the mean time I was able to get colored fonts working based on lesson 43 by just changing the texture to rgba, and it runs fast and looks very nice.

GLubyte* expanded_data = new GLubyte[ 4 * width * height];
unsigned char r, g, b;
r = 255;
b = 0;
g = 0;

for(int j=0; j<height; j++) {
for(int i=0; i<width; i++) {
expanded_data[4*(i+jwidth)] = r;
expanded_data[4
(i+jwidth)+1] = g;
expanded_data[4
(i+jwidth)+2] = b;
expanded_data[4
(i+j*width)+3] = (i>=bitmap.width || j>=bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j]; // alpha
}
}

glBindTexture( GL_TEXTURE_2D, tex_base[ch]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // possibly try GL_NEAREST
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // possibly try GL_NEAREST

glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
width,
height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
expanded_data
);

William

Thanks. I got the GL_MODULATE method to work.

William