I'm trying to work with the FTGL font library, to create a texture-mapped font and render it to the screen. The library creates a texture in the GL_ALPHA format to hold the font glyphs, and then when you tell it to render a string, it goes through and glBegin(GL_QUADS) and renders each glyph, exactly how you'd expect.
Only problem is, I'm not getting any text. In one scenario, I get solid black boxes instead of text, in another I get nothing. I've run the code under gDEBugger to ensure that the texture is getting uploaded and set up properly, and everything looks right, but I'm still not seeing any output.
I've tried the obvious stuff. Calling glColor beforehand to try to set a text color does nothing. Neither does attempting to ensure that alpha-blending will work properly, like so:
glEnable(GL_ALPHA_TEST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Does anyone have any idea what I'm missing, in order to make rendering from a GL_ALPHA texture to the screen show up properly?
It's clear after an examination of FTGL's code that the API is designed to do the text rendering itself. You're expected to call its rendering functions, which will make the OpenGL calls internally.
To put it another way, FTGL is not designed to load a font into a texture, then give you that texture object and have you draw the glyphs yourself. That doesn't mean you can't, only that the API is not going to help you do it.
The reason you get black is because
GL_ALPHAtextures return zeros for the RGB component when accessed. Since you useGL_MODULATEin your texture environment, that's going to multiply zero by the RGB part of the color.To do what you intend, you need to set the
GL_TEXTURE_ENV_MODEtoGL_COMBINEinstead ofGL_MODULATE. Which means you need to use the combine environment mode, which isn't simple. Having abandoned fixed-function for shaders pretty much as soon as they existed, I haven't touched combiners in a long time. So take what follows with a grain of salt. Here's a guess at what the environment code should look like:What you want to do is generate a color where the RGB part comes from
glColorand the Alpha part comes from the texture. This is how you do that.In English, the first line says that the texture environment mode is "combine", which activates a more complicated operation mode. The next three lines specify how the RGB part of the color is generated. The
GL_COMBINE_RGBset toGL_REPLACEmeans that the source RGB value 0 will be what the output RGB is. SettingGL_SRC0_RGBtoGL_PRIMARY_COLORmeans that source RGB value 0 is the primary color, which is the color generated by vertex processing (ie: unless you're using lighting, this is just what you passed withglColor). SettingGL_OPERAND0_RGBtoGL_SRC_COLORmeans to take the color as it is (there are special operations you can do, like take1 - the coloror whatever).The next 3 lines set up where the alpha part of the output color comes from. The
GL_COMBINE_ALPHAset toGL_REPLACEmeans that the source alpha value 0 (different from the source RGB value 0) will be what the output alpha is. SettingGL_SRC0_ALPHAtoGL_TEXTUREmeans that the source alpha value 0 comes from the texture of the current texture unit. SettingGL_OPERAND0_ALPHAtoGL_SRC_ALPHAmeans to take the alpha as it is (as before, you could apply some transform to the alpha here).Alternatively, if your OpenGL implementation has ARB_texture_swizzle available, you can set up a swizzle mask to effectively transform the
GL_ALPHAformat intoGL_INTENSITY. Then you can useGL_MODULATEas yourGL_TEXTURE_ENV_MODE. However, you have to make sure that your blend mode isglBlendMode(GL_ONE, GL_ONE_MINUS_SRC_ALPHA). This is necessary becauseGL_MODULATEwill multiply the color by the alpha. If you usedGL_SRC_ALPHAinstead ofGL_ONE, you would be doing the multiply by alpha twice (once in the texture env stage, once in the blend stage).