– プログラム中でウィンドウの再描画イベントを発生させるには, glutPostRedisplay() 関数を用いる
– 繰り返し描画を行うには, 描画の度に座標変換の行列を設定する必要がある
– 座標変換のプロセス
L 図形の空間中での位置を決める「モデリング変換」
L その空間を視点から見た空間に直す「ビューイング (視野) 変換」
L その空間をコンピュータ内の空間にあるスクリーンに投影する「透視変換」
L スクリーン上の図形をディスプレイ上の表示領域に切り出す「ビューポート変換」
#include <stdlib.h> #include <GL/glut.h> 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} }; int edge[][2] = { {0, 1}, {1, 2}, {2, 3}, {3, 0}, {4, 5}, {5, 6}, {6, 7}, {7, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7} }; void idle(void){ glutPostRedisplay(); } void display(void){ int i; static int r = 0; /* 回転角 */ glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); /* 視点位置と視点方向 */ gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); /* 図形の回転 */ glRotated((double)r, 0.0, 1.0, 0.0); /* 図形の描画 */ glColor3d(0.0, 0.0, 0.0); glBegin(GL_LINES); for(i = 0; i < 12; ++i){ glVertex3dv(vertex[edge[i][0]]); glVertex3dv(vertex[edge[i][1]]); } glEnd(); glFlush(); /* 一周回ったら回転角を0に戻す */ if(++r >= 360) r = 0; } 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 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){ switch(key){ case 'q': case 'Q': case '\033': exit(0); default: break; } } void init(void){ glClearColor(1.0, 1.0, 1.0, 1.0); } int main(int argc, char *argv[]){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutReshapeFunc(resize); glutMouseFunc(mouse); glutKeyboardFunc(keyboard); init(); glutMainLoop(); return 0; }