/********************************************************************* OpenGL(MesaGL) (+ GLUT) sample program Kenji with Tail *********************************************************************/ #include #include /* 視点の方向、距離(のための変数) */ double er = 0, ef = 5; void idle(void) { glutPostRedisplay(); } /* 円柱を描く */ void drawobj(void) { int i; static int flag = 0; #define DIV 36 static GLdouble vertex[DIV+1][3]; /* 一回目の呼出時のみ初期化 */ if (flag == 0) { for (i = 0; i < DIV; i++){ vertex[i][0] = cos(PI * 2 * i / DIV); vertex[i][1] = sin(PI * 2 * i / DIV); vertex[i][2] = 0; } vertex[i][0] = vertex[0][0]; vertex[i][1] = vertex[0][1]; vertex[i][2] = vertex[0][2]; flag = 1; } /* 実際の描画 */ glBegin(GL_QUADS); for (i = 0; i < DIV; i++) { glNormal3dv(vertex[i]); glVertex3d(vertex[i][0], vertex[i][1], 2.0); glVertex3dv(vertex[i]); glNormal3dv(vertex[i+1]); glVertex3dv(vertex[i+1]); glVertex3d(vertex[i+1][0], vertex[i+1][1], 2.0); } glEnd(); } void display(void) { int i, j; static int r = 0; /* 床座標の設定 */ GLdouble vertex[][3] = { { 1.0, -.1, 1.0 }, { 1.0, -.1,-1.0}, {-1.0, -.1,-1.0 }, {-1.0, -.1, 1.0}, { 0.0, 1.0, 0.0 } /* <- 法線ベクトル */ }; GLfloat lpos[4] = {0.0, 2.5, 5.0, 0.0}; GLfloat mcolr[4] = {0.7, 0.2, 0.2, 1.0}; GLfloat mcolg[4] = {0.2, 0.7, 0.2, 1.0}; GLfloat mcolb[4] = {0.2, 0.2, 0.7, 1.0}; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* マトリクスの保存(視点視線情報を含んでいない) */ glPushMatrix(); /* 視点、視線方向の設定 */ gluLookAt(cos(er)*ef, ef, sin(er)*ef, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glLightfv(GL_LIGHT0, GL_POSITION, lpos); /* 床の描画 */ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mcolg); glBegin(GL_QUADS); glNormal3dv(vertex[4]); for (i = 0; i < 4; i++){ glVertex3dv(vertex[i]); } glEnd(); /* 視点視線情報を含んだマトリクスの保存 */ glPushMatrix(); /* 赤色の円柱 */ glScaled(.5, .5, .5); glTranslated(0.0, 1.0, 0.0); glRotated((GLdouble)r, 0.0, 1.0, 0.0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mcolr); drawobj(); /* 赤色の円柱の上の一緒に動く青色の円柱 */ glScaled(.5, .5, .5); glTranslated(0.0, 3.0, 4.0); glRotated((GLdouble)r, 0.0, 1.0, 0.0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mcolb); drawobj(); /* 視点視線情報を含んだマトリクスの復帰 */ glPopMatrix(); /* 赤色の円柱とは別に動く緑色の円柱 */ glScaled(.15, .15, .15); glTranslated(0.0, 4.0, 0.0); glRotated((GLdouble)r, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mcolg); drawobj(); /* 視点視線情報を含んでいないマトリクスの復帰 */ glPopMatrix(); glutSwapBuffers(); if (++r >= 360) r = 0; } void resize(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(30.0, (GLdouble)w/h, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key, int x, int y) { if (key == '\033') exit(0); } /* マウスボタンにより視点情報を変更 */ void mouse(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_UP) er += .1; /* if (er >= 2*PI) er = 0; */ break; case GLUT_MIDDLE_BUTTON: if (state == GLUT_UP) ef += .2; break; case GLUT_RIGHT_BUTTON: if (state == GLUT_UP) ef -= .2; if (ef < 1) ef = 1; break; } } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow(argv[0]); glClearColor(1.0, 1.0, 1.0, 0.0); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); glutIdleFunc(idle); glutReshapeFunc(resize); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glutMainLoop(); }