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.