我会解释为什么这是不可能的。混合蒙版需要三遍,因为它包含三个部分:目标、源和蒙版。无论您做什么,都必须将源和掩码混合到帧缓冲区中,然后渲染到目标。
然而,模板缓冲区是内置在默认窗口帧缓冲区中的,只要您告诉 OpenGL 提供它(就像您提供深度缓冲区一样),并且看起来完全符合您的要求。作为 GLUT 调用,在双缓冲窗口中初始化窗口中的模板缓冲区以及启用 alpha 的颜色和深度缓冲区看起来像这样:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL);
模板缓冲区能够完全满足您的需求 - 您可以在其中绘制一个形状,并有选择地告诉它丢弃或保留该形状内的像素。这是一个如何使用它的示例,从 OpenGL 红皮书修改:
GLdouble dRadius = 0.1; // Initial radius of spiral
GLdouble dAngle; // Looping variable
// Use 0 for clear stencil, enable stencil test
glClearStencil(0);
glEnable(GL_STENCIL_TEST);
// Clear stencil buffer
glClear(GL_STENCIL_BUFFER_BIT);
// All drawing commands fail the stencil test, and are not
// drawn, but increment the value in the stencil buffer.
// glStencilFunc takes three arguments: the stencil function, the reference value, and the mask value. Whenever the stencil function is tested (for example GL_LESS), both the reference and the stencil value being tested from the buffer is bitwise ANDed with the mask: GL_LESS returns true if (ref & mask) < (stencil & mask).
glStencilFunc(GL_NEVER, 0x0, 0x0);
// glStencilOp takes three arguments: the stencil operation to call when the stencil test fails, the stencil operation to call when the stencil test passes but the depth test fails, and the stenciloperation to call when the stencil test passes AND the depth test passes (or depth test is disabled or no depth buffer is allocated).
glStencilOp(GL_INCR, GL_INCR, GL_INCR);
// Spiral pattern will create stencil pattern
// Draw the spiral pattern with white lines. We
// make the lines white to demonstrate that the
// stencil function prevents them from being drawn
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_LINE_STRIP);
for(dAngle = 0; dAngle < 400.0; dAngle += 0.1)
{
glVertex2d(dRadius * cos(dAngle), dRadius * sin(dAngle));
dRadius *= 1.002;
}
glEnd();
// Now, allow drawing, except where the stencil pattern is 0x1
// and do not make any further changes to the stencil buffer
glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// Now draw red square
glColor3f(0.0f, 1.0f, 0.0f);
glRectf(0, 0, 200, 200);
此绘图代码的输出是一个红色正方形,上面有一个螺旋线,从 (1, 1) 开始。螺旋由丢弃的像素组成,因此将与清除的颜色缓冲区具有相同的颜色。如果您要将此代码用于您的目的,您将在您希望纹理成为螺旋代码的位置绘制正方形,然后使用 GL_EQUAL 作为模板函数,在绘制红色正方形的位置绘制蒙版纹理。有关模板缓冲区的更多信息,请参阅here。