Can I draw an alphamap texture with filled foreground and background colours?

I’m drawing text from a texture atlas containing an alphamap GL_ALPHA, GL_UNSIGNED_BYTE — it’s produced by stb_truetype, if that’s any help. Right now I’m drawing with GL_BLEND enabled and the texture with all the default settings. I can set the foreground colour with glColor3f, the background is transparent, and everything works fine.

The problem is, on some platforms drawing transparent text is too slow. And I don’t actually need it; the background is always a solid colour. I am, in fact, filling it with glRectf just before drawing the texture.

Experiments have shown that disabling GL_BLEND fixes all my performance issues, but of course that gives me solid blocks of colour instead of text. Looking at the documentation for glTexEnvi, it seems to me that it ought to be possible to draw the texture without blending, getting it to just apply the alpha value to fixed source and destination colours. But I can’t figure out how, the documentation is rather opaque, and just trying stuff isn’t helping.

(Maybe I need to have GL_BLEND enabled but tell it somehow to use my background colour rather than reading from the framebuffer?)

Can anyone enlighten me?

I am using old-fashioned fixed-pipeline pre-shader OpenGL, by the way, so I can’t simply do all this in the shader fragment.

I believe that you can achieve this using GL_COMBINE and GL_INTERPOLATE. Requires OpenGL 1.3 or the ARB_texture_env_combine extension.

Off the top of my head, something like:

static GLfloat bgColor[4] = {...};
static GLfloat fgColor[4] = {...};
glColor4fv(fgColor);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, bgColor);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);

I suspect I’m not the only person who forgot practically everything they learnt about ARB_texture_env_combine as soon as fragment shaders arrived.

Sorry, busy and I haven’t had a chance to try it yet, but I will. I think my target devices are all at least 1.3. I’ll report back; thanks!

It worked flawlessly. Thank you!

…unfortunately, on the elderly Rockchip GPU on my target device this is actually slower than using GL_BLEND and transparency (~100ms per frame rather than ~50ms per frame. I will admit I have trouble believing those numbers given that I’m writing only about 4000 quads per frame, but that’s what the benchmark says). Which is a shame.

My backup plan is to render coloured textures in my font atlas rather than just using a simple alphamap but that seems really ugly.