#include<GL/freeglut.h>
#include<math.h>
void init()
{
/*
color buffer,stencil buffer清除色, 使能模板测试
*/
glClearColor(1.0,0.0,0.0,1.0);
glShadeModel(GL_FLAT);
glClearStencil(0);
glEnable(GL_STENCIL_TEST);
}
void myReshape(GLsizei w, GLsizei h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity();
/*
glStencilFunc(GL_NEVER,0xff,0xff); 使得始终通不过模板测试,这样只会写模板缓冲区,绘制的东西不会落在颜色缓冲区
glStencilOp后的三个参数分别表示在模板测试失败、模板测试通过,但深度测试未通过、模板测试盒深度测试均通过的情况下
GL_INCR_WRAP表示将模板缓冲值自增1,如果超过了最大值,则从0开始
*/
glStencilFunc(GL_NEVER,0xff,0xff);
glStencilOp(GL_INCR_WRAP,GL_INCR_WRAP,GL_INCR_WRAP);
GLdouble dRadius = 0.5;
glBegin(GL_LINE_LOOP);
for(double angle = 0.0; angle < 3.1415926 * 2; angle+= 0.001)
{
glVertex2d(dRadius * cos(angle), dRadius * sin(angle));
}
glEnd();
/*
如果最低位与1相与之后不等于1,则通过模板测试,此时颜色值被写到最终的color buffer中
所以这种利用模板缓冲区的场景需要二遍绘制,才能达到最终的效果
*/
glStencilFunc(GL_NOTEQUAL,0x1,0x1);
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
glColor3f(0.0,1.0,1.0);
glRectf(-0.8f,-0.8f,0.8f,0.8f);
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_STENCIL);
glutInitWindowSize(400,400);
glutInitWindowPosition(200,200);
glutCreateWindow("stencil test");
init();
glutReshapeFunc(myReshape);
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}