#include #include //図形の頂点の座標 GLdouble vertex[][3] = { {0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {1.0, 0.0, 1.0}, {1.0, 1.0, 1.0}, {0.0, 1.0, 1.0} }; //q図形の面となる頂点の番号 int face[][4] = { {0, 1, 2, 3}, {1, 5, 6, 2}, {5, 4, 7, 6}, {4, 0, 3, 7}, {4, 5, 1, 0}, {3, 2, 6, 7} }; //陰影 GLdouble normal[][3] = { {0.0, 0.0, -1.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 1.0, 0.0} }; GLfloat light0pos[] = {4.0, 5.0, 6.0, 1.0}; //GLfloat light1pos[] = {6.0, 0.0, 0.0, 1.0}; //光源の色 GLfloat light[] = {0.0, 0.0, 0.0, 1.0}; //図形の色 GLfloat MaterialColor1[] = {0.8, 0.2, 0.2, 1.0}; GLfloat MaterialColor2[] = {0.2, 0.2, 0.8, 1.0}; GLfloat MaterialColor3[] = {0.2, 0.8, 0.2, 1.0}; void cube(void) { int i; int j; glBegin(GL_QUADS); for(j = 0 ; j < 6 ; ++j){ glNormal3dv(normal[j]); for(i = 0 ; i < 4 ; ++i){ glVertex3dv(vertex[face[j][i]]); } } glEnd(); } void idle(void) { glutPostRedisplay(); } void display(void) { //静的呼び出すことで繰り返し関数が実行されたとき毎回初期化されずに済む。 static double r1 = 0.0, r2 = 0.0, r3 = 0.0; //ウィンドウを塗りつぶす。 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //光源の位置設定 glLightfv(GL_LIGHT0, GL_POSITION, light0pos); //glLightfv(GL_LIGHT1, GL_POSITION, light1pos); //下の図形の描画 glPushMatrix(); glRotated(r1, 0.0, 1.0, 0.0); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, MaterialColor1); cube(); glPopMatrix(); //真ん中図形の描画 glPushMatrix(); glTranslated(0.0, 1.0, 0.0); glRotated(r2, 0.0, 1.0, 0.0); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, MaterialColor3); cube(); glPopMatrix(); //上の図形の描画 glPushMatrix(); glTranslated(0.0, 2.0, 0.0); glRotated(r3, 0.0, 1.0, 0.0); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, MaterialColor2); cube(); glPopMatrix(); glPopMatrix(); glutSwapBuffers(); //一周したら回転角を0に戻す if(r1 >= 360.0) r1 = 0.0; else r1 += 1.0; if(r2 >= 360.0) r2 = 0.0; else r2 += 1.6; if(r3 >= 360.0) r3 = 0.0; else r3 += 2.2; } void resize(int w, int h) { glViewport(0, 0, w, h); //透視変換行列の設定 glMatrixMode(GL_PROJECTION); glLoadIdentity(); //透視変換(画角(度)、縦横比、奥行き前方面、奥行き後方面) gluPerspective(50.0, (double)w/(double)h, 1.0, 100.0); //モデルビューの変換行列の設定 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //視点 gluLookAt(4.0, 5.0, 6.0, 1.5, 3.0, 2.0, 0.0, 1.0, 0.0); } void mouse(int button, int state, int x, int y) { switch(button){ case GLUT_LEFT_BUTTON: if(state == GLUT_DOWN){ //アニメーション開始 glutIdleFunc(idle); } else{ //アニメーション停止 glutIdleFunc(0); } break; case GLUT_RIGHT_BUTTON: if(state == GLUT_DOWN){ //コマ送り.イベント(ボタンを押す)が複数回(押しっぱなし)になってもこの描画関数は一度だけ実行される。 glutPostRedisplay(); } break; default: break; } } void keyboard(unsigned char key, int x, int y) { //'q'、'Q'、'Esc'のいづれかのボタンを押すとウィンドウを閉じる。 switch (key){ case 'q': case 'Q': case '\033': exit(0); default: break; } } int init(void) { glClearColor(1.0, 1.0, 1.0, 1.0); glEnable(GL_DEPTH_TEST); //カリング。視点の裏を取り除いて効率を上げる。 glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glLightfv(GL_LIGHT1, GL_DIFFUSE, light); glLightfv(GL_LIGHT1, GL_SPECULAR, light); } int main(int argc, char *argv[]) { glutInitWindowSize(600, 600); //初期化する glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); //ウィンドウを開く glutCreateWindow(argv[0]); //ウィンドウ内に絵を描く関数を決め、図形表示する glutDisplayFunc(display); glutReshapeFunc(resize); glutMouseFunc(mouse); glutKeyboardFunc(keyboard); init(); //無限ループ。プログラムをイベント待ち受け状態にする glutMainLoop(); return 0; }