// 3D空間内を移動出来るプログラム // ~4/8 // WASDで平行移動 ←↑↓→で視点移動 // R/D 上下移動 // 4/9 // 数字とobjectの対応 // 1 Redcube 2 GreenSphere 3 BlueTetrahedron 4 YellowTorus // 各数字を押した後、 // ←↑↓→で回転 // 4/10 // r/f 上下移動 WASD平行移動 #include #include #include #include #include static double ex = 0.0, ez = 0.0, ey = 0.0; /* 視点の位置 */ static double the = 0.0, phi = 0.0; /* 視点の向き */ static GLfloat lit_amb[4]={0.2, 0.2, 0.2, 1.0}; /* 環境光 */ static GLfloat lit_dif[4]={0.5, 0.5, 0.5, 1.0}; /* 拡散光 */ static GLfloat lit_spc[4]={0.5, 0.5, 0.5, 1.0}; /* 鏡面光 */ static GLfloat lit_pos[4]={0.0, 0.5, 0.0, 1.0}; /* 光源の位置 */ static GLfloat lit_shi[1]={30.0}; /* ハイライト */ static GLfloat lit_emi[4]={0.0,0.0,0.0,0.0}; /* 発光係数 */ static GLfloat spotDirrection[]={0.0, 0.0, -1.0}; /* 光源の向き */ static double sca1 = 1.0, sca2 = 1.0, sca3 = 1.0, sca4 = 1.0; /* 拡大係数 */ static double the1 = 0.0, the2 = 0.0, the3 = 0.0, the4 = 0.0; /*横回転*/ static double phi1 = 0.0, phi2 = 0.0, phi3 = 0.0, phi4 = 0.0;/*縦回転*/ static double obj1[3]={0.0,0.0,0.0},obj2[3]={0.0,0.0,0.0},obj3[3]={0.0,0.0,0.0},obj4[3]={0.0,0.0,0.0}; /* object移動用 (x, y, z) */ static int flag = 0; /* オブジェクト指定用 */ void scene(void) { /* 物体の色 */ static GLfloat red[] = { 0.8, 0.2, 0.2, 0.8 }; static GLfloat green[] = { 0.2, 0.8, 0.2, 0.8 }; static GLfloat blue[] = { 0.2, 0.2, 0.8, 0.8 }; static GLfloat yellow[] = { 0.8, 0.8, 0.2, 0.8 }; static GLfloat ground[][4] = { { 0.6, 0.6, 0.6, 1.0 }, { 0.3, 0.3, 0.3, 1.0 } }; int i, j; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, lit_amb); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, lit_dif); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, lit_spc); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, lit_shi); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, lit_emi); /* 赤い箱 */ glPushMatrix(); glTranslated(0.0+obj1[0], 1.0+obj1[1], -3.0+obj1[2]); glRotated( the1, 0.0, 1.0, 0.0); glRotated( phi1, cos(M_PI*the/180.0) ,0.0,sin(M_PI*the/180.0) ); glScalef( sca1, sca1, sca1); glMaterialfv(GL_FRONT, GL_DIFFUSE, red); glutSolidCube(1.0); glPopMatrix(); /* 緑の玉 */ glPushMatrix(); glTranslated(0.0+obj2[0], 0.5+obj2[1], 3.0+obj2[2]); glRotated( the2, 0.0, 1.0, 0.0); glRotated( phi2, cos(M_PI*the/180.0) , 0.0, sin(M_PI*the/180.0)); glScalef( sca2, sca2, sca2); glMaterialfv(GL_FRONT, GL_DIFFUSE, green); glutSolidSphere(1.0,30,30); glPopMatrix(); /* 青い六面体*/ glPushMatrix(); glTranslated(-3.0+obj3[0], 1.5+obj3[1], 0.0+obj3[2]); glRotated( the3, 0.0, 1.0, 0.0); glRotated( phi3, cos(M_PI*the/180.0) ,0.0,sin(M_PI*the/180.0) ); glScalef( sca3, sca3, sca3); glMaterialfv(GL_FRONT, GL_DIFFUSE, blue); glutSolidTetrahedron(); glPopMatrix(); /* 黄色いトーラス */ glPushMatrix(); glTranslated(3.0+obj4[0], 0.0+obj4[1], 0.0+obj4[2]); glRotated( the4, 0.0, 1.0, 0.0); glRotated( phi4, cos(M_PI*the/180.0) ,0.0,sin(M_PI*the/180.0) ); glScalef(sca4, sca4, sca4); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, yellow); glutSolidTorus(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(); /* 光源設定 */ glLightfv(GL_LIGHT0, GL_AMBIENT, lit_amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, lit_dif); glLightfv(GL_LIGHT0, GL_SPECULAR, lit_spc); glLightfv(GL_LIGHT0, GL_POSITION, lit_pos); glLightfv(GL_LIGHT0, GL_SHININESS, lit_shi); glLightfv(GL_LIGHT0, GL_EMISSION, lit_emi); 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, 25.0 );// スポットライトの絞り(デフォルト 180.0) glLightf( GL_LIGHT0, GL_SPOT_EXPONENT, 0.1 );// スポットライトの中心からの減衰の度合い(デフォルト 0) glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); /* シーンの描画 */ scene(); glutSwapBuffers(); } void idle(void) { glutPostRedisplay(); } void movedisplay(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glPushMatrix(); glRotated(the, 0.0, 1.0, 0.0); glRotated(phi,cos(M_PI*the/180.0) ,0.0,sin(M_PI*the/180.0)); glTranslated(ex, ey, ez); scene(); 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); glLoadIdentity(); } void max(void) { switch(flag){ case 0: if(ez > 10.0) ez = 10.0; if(ez < -10.0) ez = -10.0; if(ex > 10.0) ex = 10.0; if(ex < -10.0) ex = -10.0; break; case 1: if(obj1[0] > 10.0) obj1[0]=10.0; if(obj1[0] < -10.0) obj1[0]=-10.0; if(obj1[2] > 13.0) obj1[2]=13.0; if(obj1[2] < -7.0)obj1[2]=-7.0; break; case 2: if(obj2[0] > 10.0) obj2[0]=10.0; if(obj2[0] < -10.0) obj2[0]=-10.0; if(obj2[2] > 7.0) obj2[2]=7.0; if(obj2[2] < -13.0) obj2[2]=-13.0; break; case 3: if(obj3[0] > 13.0) obj3[0]=13.0; if(obj3[0] < -7.0) obj3[0]=-7.0; if(obj3[2] > 10.0) obj3[2]=10.0; if(obj3[2] < -10.0) obj3[2]=-10.0; break; case 4: if(obj4[0] > 7.0) obj4[0]=7.0; if(obj4[0] < -13.0) obj4[0]=-13.0; if(obj4[2] > 10.0) obj4[2]=10.0; if(obj4[2] < -10.0) obj4[2]=-10.0; break; default: break; } return; } void mouse(int button, int state, int x, int y) { if(button == GLUT_LEFT_BUTTON || button == GLUT_RIGHT_BUTTON ){ if(state == GLUT_DOWN){ switch (flag) { case 0: break; case 1: glutIdleFunc(idle); if(button == GLUT_LEFT_BUTTON) sca1 += 0.1; else sca1 -= 0.1; if( sca1 > 2.0 ) sca1 = 2.0; if( sca1 < 0.3 ) sca1 = 0.3; movedisplay(); glutIdleFunc(0); break; case 2: glutIdleFunc(idle); if(button == GLUT_LEFT_BUTTON) sca2 += 0.1; else sca2 -= 0.1; if( sca2 > 1.5 ) sca2 = 1.5; if( sca2 < 0.3 ) sca2 = 0.3; movedisplay(); glutIdleFunc(0); break; case 3: glutIdleFunc(idle); if(button == GLUT_LEFT_BUTTON) sca3 += 0.1; else sca3 -= 0.1; if( sca3 > 1.5 ) sca3 = 1.5; if( sca3 < 0.3 ) sca3 = 0.3; movedisplay(); glutIdleFunc(0); break; case 4: glutIdleFunc(idle); if(button == GLUT_LEFT_BUTTON) sca4 += 0.1; else sca4 -= 0.1; if( sca4 > 2.0 ) sca4 = 2.0; if( sca4 < 0.3 ) sca4 = 0.3; movedisplay(); glutIdleFunc(0); break; default: break; } } else { glutIdleFunc(0); } } } void key(int key, int x, int y) { switch ( key ) { /*************視点移動/物体回転**************/ case GLUT_KEY_DOWN: //上 switch (flag) { case 0: glutIdleFunc(idle); phi+=5.0; if(phi > 75.0) phi=75.0; movedisplay(); glutIdleFunc(0); break; case 1: glutIdleFunc(idle); phi1 += 5.0; if(phi1 > 360.0) phi1 = 0.0; movedisplay(); glutIdleFunc(0); break; case 2: glutIdleFunc(idle); phi2 += 5.0; if(phi2 > 360.0) phi2 = 0.0; movedisplay(); glutIdleFunc(0); break; case 3: glutIdleFunc(idle); phi3 += 5.0; if(phi3 > 360.0) phi3 = 0.0; movedisplay(); glutIdleFunc(0); break; case 4: glutIdleFunc(idle); phi4 += 5.0; if(phi4 > 360.0) phi4 = 0.0; movedisplay(); glutIdleFunc(0); break; default: break; } break; case GLUT_KEY_UP: //下 switch (flag) { case 0: glutIdleFunc(idle); phi-=5.0; if(phi < -75.0) phi= -75.0; movedisplay(); glutIdleFunc(0); break; case 1: glutIdleFunc(idle); phi1 -= 5.0; if(phi1 < -360.0) phi1 = 0.0; movedisplay(); glutIdleFunc(0); break; case 2: glutIdleFunc(idle); phi2 -= 5.0; if(phi2 < -360.0) phi2 = 0.0; movedisplay(); glutIdleFunc(0); break; case 3: glutIdleFunc(idle); phi3 -= 5.0; if(phi3 < -360.0) phi3 = 0.0; movedisplay(); glutIdleFunc(0); break; case 4: glutIdleFunc(idle); phi4 -= 5.0; if(phi4 < -360.0) phi4 = 0.0; movedisplay(); glutIdleFunc(0); break; default: break; } break; case GLUT_KEY_LEFT: //左 switch (flag) { case 0: glutIdleFunc(idle); the-=5.0; if(the < -360.0) the=0.0; movedisplay(); glutIdleFunc(0); break; case 1: glutIdleFunc(idle); the1 -= 5.0; if(the1 < -360.0) the1 = 0.0; movedisplay(); glutIdleFunc(0); break; case 2: glutIdleFunc(idle); the2 -= 5.0; if(the2 < -360.0) the2 = 0.0; movedisplay(); glutIdleFunc(0); break; case 3: glutIdleFunc(idle); the3 -= 5.0; if(the3 < -360.0) the3 = 0.0; movedisplay(); glutIdleFunc(0); break; case 4: glutIdleFunc(idle); the4 -= 5.0; if(the4 < -360.0) the4 = 0.0; movedisplay(); glutIdleFunc(0); break; default: break; } break; case GLUT_KEY_RIGHT: //右 switch (flag) { case 0: glutIdleFunc(idle); the+=5.0; if(the > 360.0) the=0.0; movedisplay(); glutIdleFunc(0); break; case 1: glutIdleFunc(idle); the1 += 5.0; if(the1 > 360.0) the1 = 0.0; movedisplay(); glutIdleFunc(0); break; case 2: glutIdleFunc(idle); the2 += 5.0; if(the2 > 360.0) the2 = 0.0; movedisplay(); glutIdleFunc(0); break; case 3: glutIdleFunc(idle); the3 += 5.0; if(the3 > 360.0) the3 = 0.0; movedisplay(); glutIdleFunc(0); break; case 4: glutIdleFunc(idle); the4 += 5.0; if(the4 > 360.0) the4 = 0.0; movedisplay(); glutIdleFunc(0); break; default: break; } break; /************************************/ default: break; } } void keyboard(unsigned char key, int x, int y) { switch (key) { case '\033': // ESC 終了 exit(0); break; case 'd': //右移動 switch(flag){ case 0: glutIdleFunc(idle); ez-=0.2*sin(M_PI*the/180.0); ex-=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 1: glutIdleFunc(idle); obj1[0]+=0.2*cos(M_PI*the/180.0); obj1[2]+=0.2*sin(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 2: glutIdleFunc(idle); obj2[0]+=0.2*cos(M_PI*the/180.0); obj2[2]+=0.2*sin(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 3: glutIdleFunc(idle); obj3[0]+=0.2*cos(M_PI*the/180.0); obj3[2]+=0.2*sin(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 4: glutIdleFunc(idle); obj4[0]+=0.2*cos(M_PI*the/180.0); obj4[2]+=0.2*sin(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; default: break; } break; case 'a': //左移動 switch(flag){ case 0: glutIdleFunc(idle); ez+=0.2*sin(M_PI*the/180.0); ex+=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 1: glutIdleFunc(idle); obj1[0]-=0.2*cos(M_PI*the/180.0); obj1[2]-=0.2*sin(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 2: glutIdleFunc(idle); obj2[0]-=0.2*cos(M_PI*the/180.0); obj2[2]-=0.2*sin(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 3: glutIdleFunc(idle); obj3[0]-=0.2*cos(M_PI*the/180.0); obj3[2]-=0.2*sin(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 4: glutIdleFunc(idle); obj4[0]-=0.2*cos(M_PI*the/180.0); obj4[2]-=0.2*sin(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; default: break; } break; case 'w': //前方移動 switch(flag){ case 0: glutIdleFunc(idle); ex-=0.2*sin(M_PI*the/180.0); ez+=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 1: glutIdleFunc(idle); obj1[0]+=0.2*sin(M_PI*the/180.0); obj1[2]-=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 2: glutIdleFunc(idle); obj2[0]+=0.2*sin(M_PI*the/180.0); obj2[2]-=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 3: glutIdleFunc(idle); obj3[0]+=0.2*sin(M_PI*the/180.0); obj3[2]-=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 4: glutIdleFunc(idle); obj4[0]+=0.2*sin(M_PI*the/180.0); obj4[2]-=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; default: break; } break; case 's': //後方移動 switch(flag){ case 0: glutIdleFunc(idle); ex+=0.2*sin(M_PI*the/180.0); ez-=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 1: glutIdleFunc(idle); obj1[0]-=0.2*sin(M_PI*the/180.0); obj1[2]+=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 2: glutIdleFunc(idle); obj2[0]-=0.2*sin(M_PI*the/180.0); obj2[2]+=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 3: glutIdleFunc(idle); obj3[0]-=0.2*sin(M_PI*the/180.0); obj3[2]+=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; case 4: glutIdleFunc(idle); obj4[0]-=0.2*sin(M_PI*the/180.0); obj4[2]+=0.2*cos(M_PI*the/180.0); max(); movedisplay(); glutIdleFunc(0); break; default: break; } break; case 'f': //下へ switch(flag){ case 0: glutIdleFunc(idle); ey += 0.5; movedisplay(); glutIdleFunc(0); break; case 1: glutIdleFunc(idle); obj1[1]-=0.1; if(obj1[1] < 0.0) obj1[1]=0.0; movedisplay(); glutIdleFunc(0); break; case 2: glutIdleFunc(idle); obj2[1]-=0.1; if(obj2[1] < 0.0) obj2[1]=0.0; movedisplay(); glutIdleFunc(0); break; case 3: glutIdleFunc(idle); obj3[1]-=0.1; if(obj3[1] < 0.0) obj3[1]=0.0; movedisplay(); glutIdleFunc(0); break; case 4: glutIdleFunc(idle); obj4[1]-=0.1; if(obj4[1] < 0.0) obj4[1]=0.0; movedisplay(); glutIdleFunc(0); break; default: break; } break; case 'r': //上へ switch(flag){ case 0: glutIdleFunc(idle); ey -= 0.5; movedisplay(); glutIdleFunc(0); break; case 1: glutIdleFunc(idle); obj1[1]+=0.1; movedisplay(); glutIdleFunc(0); break; case 2: glutIdleFunc(idle); obj2[1]+=0.1; movedisplay(); glutIdleFunc(0); break; case 3: glutIdleFunc(idle); obj3[1]+=0.1; movedisplay(); glutIdleFunc(0); break; case 4: glutIdleFunc(idle); obj4[1]+=0.1; movedisplay(); glutIdleFunc(0); break; default: break; } break; case '0': flag = 0; break; case '1': flag = 1; break; case '2': flag = 2; break; case '3': flag = 3; break; case '4': flag = 4; break; default: break; } } 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_DOUBLE |GLUT_DEPTH); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutReshapeFunc(resize); glutKeyboardFunc(keyboard); glutSpecialFunc(key); glutMouseFunc(mouse); init(); glutMainLoop(); return 0; }