/* * ステンシル バッファ */ #include /* 初期化 */ void init(void) { GLfloat lightAmb[] = {0.0, 0.0, 0.0, 1.0}; GLfloat lightPos[] = {0.0, 0.0, -1.0, 1.0}; GLfloat lightDif[] = {1.0, 1.0, 1.0, 1.0}; /* 背景色の指定 RGBA */ glClearColor(1.0, 1.0, 1.0, 0.0); /* ステンシルバッファのクリア値 */ glClearStencil(0x00); /* デプスバッファの有効化 */ glEnable(GL_DEPTH_TEST); /* デプスバッファの同じ距離は上書き */ glDepthFunc(GL_LEQUAL); /* ステンシルバッファの有効化 */ glEnable(GL_STENCIL_TEST); /* カリングの有効化 */ glEnable(GL_CULL_FACE); /* Culling GL_BACK or GL_FRONT */ glCullFace(GL_BACK); /* 光源の設定 */ glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb); glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDif); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } void resize(int w, int h) { /* ビューポートの設定 */ glViewport(0, 0, w, h); /* 射影変換モードに */ glMatrixMode(GL_PROJECTION); /* 変換行列を単位行列に */ glLoadIdentity(); /* 透視射影の視野台形 左、右、下、上、手前、奥 */ glFrustum(-1.33, 1.33, -1.0, 1.0, 1.0, 5.0); /* モデル変換モードに戻す */ glMatrixMode(GL_MODELVIEW); } /* 画面表示 */ void display(void) { GLfloat red[] = {1.0, 0.0, 0.0, 0.0}; GLfloat blue[] = {0.0, 0.0, 1.0, 0.0}; /* 背景色でクリア */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glLoadIdentity(); glTranslated(0.0, 0.0, -3.0); glRotated(30.0, 0.0, 1.0, 0.0); /* ステンシルテストが成功であれば更新 */ glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); /* ステンシルバッファを常に 0x01 に */ glStencilFunc(GL_ALWAYS, 0x01, 0xFF); /* 描画しない */ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glPushMatrix(); glBegin(GL_TRIANGLES); glNormal3f(0.0, 0.0, 1.0); glVertex3f(2.0, 0.6, 0.0); glVertex3f(-2.0, 0.6, 0.0); glVertex3f(0.0, -2.0, 0.0); glEnd(); glPopMatrix(); /* 描画する */ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); /* ステンシルバッファが 0x00 であれば */ glStencilFunc(GL_EQUAL, 0x00, 0xFF); glMaterialfv(GL_FRONT, GL_DIFFUSE, red); glPushMatrix(); glBegin(GL_TRIANGLES); glNormal3f(0.0, 0.0, 1.0); glVertex3f(0.0, 2.0, 0.0); glVertex3f(-2.0, -0.6, 0.0); glVertex3f(2.0, -0.6, 0.0); glEnd(); glPopMatrix(); /* ステンシルバッファが 0x01 であれば */ glStencilFunc(GL_EQUAL, 0x01, 0xFF); glMaterialfv(GL_FRONT, GL_DIFFUSE, blue); glPushMatrix(); glBegin(GL_TRIANGLES); glNormal3f(0.0, 0.0, 1.0); glVertex3f(0.0, 2.0, 0.0); glVertex3f(-2.0, -0.6, 0.0); glVertex3f(2.0, -0.6, 0.0); glEnd(); glPopMatrix(); glFlush(); } int main(int argc, char *argv[]) { /* GLUT の初期設定 */ glutInit(&argc, argv); glutInitWindowPosition(100, 50); glutInitWindowSize(400, 300); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); glutCreateWindow(argv[0]); /* 各関数の指定 */ glutDisplayFunc(display); glutReshapeFunc(resize); /* 初期設定 */ init(); /* メインループ */ glutMainLoop(); return 0; }