#include #include #include static double ex = 0.0, ez = 0.0; /* 視点の位置 */ static double r = 270.0; /* 視点の向き */ void scene(void) { /* 物体の色指定 */ static GLfloat red[] = { 0.8, 0.2, 0.2, 1.0 }; static GLfloat green[] = { 0.2, 0.8, 0.2, 1.0 }; static GLfloat blue[] = { 0.2, 0.2, 0.8, 1.0 }; static GLfloat yellow[] = { 0.8, 0.8, 0.2, 1.0 }; static GLfloat ground[][4] = { { 0.6, 0.6, 0.6, 1.0 }, { 0.3, 0.3, 0.3, 1.0 } }; int i, j; /* 赤い箱 */ glPushMatrix(); glTranslated(-1.0, 0.5, -5.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, red); glutSolidCube(0.5); glPopMatrix(); /* 緑の箱 */ glPushMatrix(); glTranslated(0.0, 0.5, 3.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, green); glutSolidCube(0.5); glPopMatrix(); /* 青い球 */ glPushMatrix(); glTranslated(-3.0, 0.5, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, blue); glutSolidSphere(0.5,20,20); glPopMatrix(); /* 黄色い円錐*/ glPushMatrix(); glTranslated(5.0, 0.5, -1.0); glRotated(-90.0,1.0,0.0,0.0);//横倒しになってるので立てる glMaterialfv(GL_FRONT, GL_DIFFUSE, yellow); glutSolidCone(0.5,1.0,20,20); glPopMatrix(); /* 地面 */ glBegin(GL_QUADS); glNormal3d(0.0, 1.0, 0.0); for (j = -10; j < 10; ++j) { for (i = -10; i < 10; ++i) { glMaterialfv(GL_FRONT, GL_DIFFUSE, ground[(i + j) & 1]); glVertex3d((GLdouble)i, -0.5, (GLdouble)j); glVertex3d((GLdouble)i, -0.5, (GLdouble)(j + 1)); glVertex3d((GLdouble)(i + 1), -0.5, (GLdouble)(j + 1)); glVertex3d((GLdouble)(i + 1), -0.5, (GLdouble)j); } } glEnd(); } void display(void) { /* 画面クリア */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* モデルビュー変換行列の初期化 */ glLoadIdentity(); /* 視点の移動  青い球を正面へ*/ glRotated(r, 0.0, 1.0, 0.0); glTranslated(ex, 0.0, ez); //移動にあわせてスポットライトの位置を変更 static GLfloat lightPosition[4] = { 0.0, 0.5,0.0, 1.0 }; //光源の位置 static GLfloat lightDiffuse[3] = { 1.0, 1.0, 1.0 }; //拡散光 static GLfloat lightAmbient[3] = { 0.25, 0.25, 0.25 }; //環境光 static GLfloat lightSpecular[3] = { 1.0, 1.0, 1.0 }; //鏡面光 GLfloat spotDirrection[] = { -3.0, 0.5, 0.0 }; //スポットライトを向ける方向 glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular); glLightf( GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.01); glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, spotDirrection ); //スポットライトの向ける方向(デフォルト (0,0,-1.0)) glLightf( GL_LIGHT0, GL_SPOT_CUTOFF, 20.0 );// スポットライトの絞り(デフォルト 180.0) glLightf( GL_LIGHT0, GL_SPOT_EXPONENT, 0.1 );// スポットライトの中心からの減衰の度合い(デフォルト 0) glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); /* シーンの描画 */ scene(); glFlush(); } void idle(void) { glutPostRedisplay(); } void movedisplay(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glPushMatrix(); glRotated(r, 0.0, 1.0, 0.0); glTranslated(ex, 0.0, ez); scene(); glPopMatrix(); glFlush(); } 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); } void keyboard(unsigned char key, int x, int y) { /* ESC をタイプしたら終了 */ if (key == '\033') { exit(0); } else if (key == 'w') { glutIdleFunc(idle); if(r/90 == 3) //正面 { if(ex < 10.0) //地面の座標より外にいかないように 以下略 ex+=0.2; } else if(r/90 == 4||r/90 == 0)//右? { if(ez <10.0) ez += 0.2; } else if(r/90 == 2)//左? { if(ez > -10.0) ez -= 0.2; } else if(r/90 == 1)//後ろ { if(ex > -10.0) ex -=0.2; } movedisplay(); glutIdleFunc(0); // move(1);//前へ } else if(key=='a') { glutIdleFunc(idle); if(r==0.0) { r = 270.0; } else { r -=90.0; } movedisplay(); glutIdleFunc(0); // move(2);//左へ } else if(key=='s') { glutIdleFunc(idle); if(r/90 == 3) //正面 { if(ex >-10.0) ex-=0.2; } else if(r/90 == 4||r/90 == 0) { if(ez > -10.0) ez -= 0.2; } else if(r/90 == 2) { if(ez < 10.0) ez += 0.2; } else if(r/90 == 1) { if(ex < 10.0) ex +=0.2; } movedisplay(); glutIdleFunc(0); // move(3);//後ろへ } else if(key=='d') { glutIdleFunc(idle); if(r == 360.0) { r = 90.0; } else { r+=90.0; } movedisplay(); glutIdleFunc(0); // move(4);//右へ } else { } } void init(void) { /* 初期設定 */ glClearColor(1.0, 1.0, 1.0, 0.0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutReshapeFunc(resize); glutKeyboardFunc(keyboard); init(); glutMainLoop(); return 0; }