(Ab)使用模板缓冲区:
- 将模板缓冲区清除为 0xff
- 对于每个圆圈,仅将模板缓冲区为 0xff 的颜色和模板缓冲区写入(和混合)。如果模板和深度测试成功,则将片段的模板值设置为零。
这样您只能写入(和混合)一个颜色像素一次,直到您再次清除模板缓冲区。
例子:
#include <GL/glut.h>
void quad()
{
glBegin( GL_QUADS );
glVertex2i( -1, -1 );
glVertex2i( 1, -1 );
glVertex2i( 1, 1 );
glVertex2i( -1, 1 );
glEnd();
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -2, 2, -2, 2, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// clear stencil buffer to all 1s
glClearStencil( 0xff );
glClear( GL_STENCIL_BUFFER_BIT );
// turn on stencil testing & make sure we don't mask out any bits
glEnable( GL_STENCIL_TEST );
glStencilMask( 0xff );
// only allow fragments through to the color/depth buffers if
// the stencil buffer at that point is 0xff
glStencilFunc( GL_EQUAL, 0xff, 0xff );
// if the stencil/depth tests succeed for a fragment,
// zero out the stencil buffer at that point;
// that way you can only write to a color buffer pixel once
glStencilOp( GL_KEEP, GL_KEEP, GL_ZERO );
glEnable( GL_BLEND );
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glTranslatef( -0.5, -0.5, 0 );
glColor4ub( 255, 0, 0, 128 );
quad();
glPopMatrix();
glPushMatrix();
glTranslatef( 0.5, 0.5, 0 );
glColor4ub( 255, 0, 0, 128 );
quad();
glPopMatrix();
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_STENCIL );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}