これは機能するはずです:
glEnable(GL_BLEND);
// Use a simple blendfunc for drawing the background
glBlendFunc(GL_ONE, GL_ZERO);
// Draw entire background without masking
drawQuad(backgroundTexture);
// Next, we want a blendfunc that doesn't change the color of any pixels,
// but rather replaces the framebuffer alpha values with values based
// on the whiteness of the mask. In other words, if a pixel is white in the mask,
// then the corresponding framebuffer pixel's alpha will be set to 1.
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ZERO);
// Now "draw" the mask (again, this doesn't produce a visible result, it just
// changes the alpha values in the framebuffer)
drawQuad(maskTexture);
// Finally, we want a blendfunc that makes the foreground visible only in
// areas with high alpha.
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
drawQuad(foregroundTexture);
これはかなりトリッキーなので、不明な点があれば教えてください。
GLコンテキストを作成するときに、アルファバッファを要求することを忘れないでください。それ以外の場合は、アルファバッファなしでコンテキストを取得することが可能です。
編集:ここでは、イラストを作成しました。

編集:この答えを書いて以来、私はこれを行うためのより良い方法があることを学びました:
- OpenGLの固定機能パイプラインに制限されている場合は、テクスチャ環境を使用してください
- シェーダーを使用できる場合は、フラグメントシェーダーを使用してください。
この回答で説明されている方法は機能し、これら2つの優れたオプションよりもパフォーマンスが特に悪くはありませんが、エレガント性と柔軟性が劣ります。