最終更新: mikk_ni3_92 2008年12月24日(水) 15:09:31履歴
現在地: メニュー >> 発展編04 >> 発展編::両面ステンシル1 >> 発展編04::まとめコード2
関連:発展編04::まとめコード1
関連:発展編04::まとめコード1
#include <iostream> #include <GL/glew.h> //先に記述する #include <GL/glut.h> //-------------各種外部変数 -----------// const double PlaneEq[]={1.0, 0.0, 0.0, 0.0}; //---------- プロトタイプ宣言 -----------// void LIGHT_INIT(); void display(); void reshape(int w, int h); void timer(int value); void SetMaterialGold(); void SetUpTwoSideStencil(); void DrawStencilFace(); //----------- OpenGLの初期設定 -------------------------// void GLUT_INIT() { glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH|GLUT_STENCIL); glutInitWindowSize(640,480); glutCreateWindow("Two Side Stencil Part 2"); } bool GLEW_INIT() { GLenum err; err = glewInit(); if (err != GLEW_OK){ std::cerr << glewGetErrorString(err) << '\n'; return false; } return true; } void GLUT_CALL_FUNC() { glutDisplayFunc(display); glutReshapeFunc(reshape); glutTimerFunc(0,timer,17); } void MY_INIT() { glClearColor(1.0, 1.0, 1.0, 1.0); glClearStencil(0); LIGHT_INIT(); //光源設定 glEnable(GL_NORMALIZE);//法線の有効化 glEnable(GL_DEPTH_TEST); } void LIGHT_INIT() { float Light0Pos[]={3,4,5,0}; //光源の位置 glLightfv(GL_LIGHT0, GL_POSITION, Light0Pos);//位置だけ設定(あとはデフォルト) glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } //材質設定 void SetMaterialGold() { static GLfloat gold_amb[] = { 0.24725, 0.1995, 0.0745, 1.0 }; static GLfloat gold_diff[] = { 0.75164, 0.60648 , 0.22648, 1.0 }; static GLfloat gold_spe[] = { 0.628281, 0.555802,0.366065,1.0 }; static GLfloat gold_shin[] = { 51.2 }; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, gold_amb); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, gold_diff); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gold_spe); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, gold_shin); } //----------- メイン関数 ----------------// int main(int argc, char **argv) { glutInit(&argc,argv); GLUT_INIT(); if ( GLEW_INIT() == false){ std::cerr << "Can't init glew\n"; return -1; } GLUT_CALL_FUNC(); MY_INIT(); glutMainLoop(); return 0; } //--------------- ここからコールバック ----------------------// void display() { static int r = 0; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glLoadIdentity(); gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //視点の設定 glRotatef(static_cast<float>(r),0,1,0); glEnable(GL_CLIP_PLANE0); glClipPlane(GL_CLIP_PLANE0, PlaneEq);//クリッププレーンを設置 glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); //両面ステンシル開始 SetUpTwoSideStencil(); //両面ステンシルの設定 SetMaterialGold(); glutSolidSphere(1,30,30); //描画 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); //両面ステンシル終了 glDisable(GL_CLIP_PLANE0); DrawStencilFace();//切断面の描画 glDisable(GL_STENCIL_TEST); //ステンシルテスト無効化 glutSwapBuffers(); //ウィンドウに出力 if(++r>360) r = 0; } void reshape(int w, int h) { glViewport(0, 0, w, h); //ビューポートの設定 glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); } void timer(int t) { glutPostRedisplay(); glutTimerFunc(t,timer,17); //タイマー関数 } //------------- ここから各種関数 ----------------// void SetUpTwoSideStencil() { //これ以降は裏面の設定 glActiveStencilFaceEXT(GL_BACK); glStencilFunc(GL_ALWAYS, 0, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); //ステンシル値 「+1」 //これ以降は表面の設定 glActiveStencilFaceEXT(GL_FRONT); glStencilFunc(GL_ALWAYS, 0, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);//ステンシル値「-1」 } void DrawStencilFace() { //ステンシル値が0でない部分が描画される glStencilFunc(GL_NOTEQUAL, 0, ~0); glPushMatrix(); glRotatef(90,0,1,0); glRectf(-10,10,10,-10); glPopMatrix(); }