– プログラム中でウィンドウの再描画イベントを発生させるには, 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;
}
