#include #include #include #include #define W 7 /* 地面の幅*/ #define D 8 /* 地面の長さ */ #define FRONT 0 #define HIGHANGLE 1 #define UPSIDE 2 int ViewPoint = HIGHANGLE; /* * 地面を描く */ static void myGround(double height) { const static GLfloat ground[][4] = { { 0.6, 0.6, 0.6, 1.0 }, { 0.3, 0.3, 0.3, 1.0 } }; int i, j; glBegin(GL_QUADS); glNormal3d(0.0, 1.0, 0.0); for (j = -D; j < D; ++j) { for (i = -W; i < W; ++i) { glMaterialfv(GL_FRONT, GL_DIFFUSE, ground[(i + j) & 1]); glVertex3d((GLdouble)i, height, (GLdouble)j); glVertex3d((GLdouble)i, height, (GLdouble)(j + 1)); glVertex3d((GLdouble)(i + 1), height, (GLdouble)(j + 1)); glVertex3d((GLdouble)(i + 1), height, (GLdouble)j); } } glEnd(); } void idle(void) { glutPostRedisplay(); } /* * 画面表示 */ void display(void) { static GLfloat lightpos[] = { 3.0, 4.0, 5.0, 1.0 }; /* 光源の位置 */ static GLfloat color[] = { 0.5, 1.0, 1.0, 1.0 }; /* やかんの色 */ static GLdouble px = 0.0 ,pz = 0.0; static GLdouble r = 0.0; pz = 6.0*sin((GLfloat)glutGet(GLUT_ELAPSED_TIME)/300)*cos((GLfloat)glutGet(GLUT_ELAPSED_TIME)/600); px = 6.0*sin((GLfloat)glutGet(GLUT_ELAPSED_TIME)/300)*sin((GLfloat)glutGet(GLUT_ELAPSED_TIME)/600); /* 画面クリア */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* モデルビュー変換行列の初期化 */ glLoadIdentity(); /* 光源の位置を設定 */ glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* 視点の移動(物体の方を奥に移す) */ glTranslated(0.0, 0.0, -25.0); switch(ViewPoint){ case FRONT: gluLookAt(7.0, 7.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0); glRotated(30.0, 30.0, 30.0, 0.0); break; case HIGHANGLE: gluLookAt(0.0, 7.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0); break; case UPSIDE: gluLookAt(0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0); break; default: break; } glRotated(0.0, 2.0, 0.0, 0.0); /* シーンの描画 */ myGround(0.0); glPushMatrix(); glRotated(r - 90.0, 0.0, 1.0, 0.0); glTranslated(px, 1.0, pz); glMaterialfv(GL_FRONT, GL_DIFFUSE, color); glutSolidTeapot(1.0); glPopMatrix(); glutSwapBuffers(); } void resize(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); } static void keyboard(unsigned char key, int x, int y) { /* ESC か q をタイプしたら終了 */ if (key == '\033' || key == 'q') { exit(0); } } void mouse(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) { } else { } break; case GLUT_RIGHT_BUTTON: if(state == GLUT_DOWN){ if(ViewPoint == FRONT) ViewPoint = HIGHANGLE; else if(ViewPoint == HIGHANGLE) ViewPoint = UPSIDE; else ViewPoint = FRONT; glutPostRedisplay(); } break; default: break; } } void init(void) { /* 初期設定 */ glClearColor(1.0, 1.0, 1.0, 0.0); glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutReshapeFunc(resize); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); init(); glutIdleFunc(idle); glutMainLoop(); return 0; }