/* exercise06.c */ /* compile: cc -o exercise06 exercise06.c -g -O2 -Wall -lglfw -lGLU -lGL -lX11 -lXrandr -lm */ #include #include #include #include /* 円を描画する */ void circle(double x, double y, double r) { int const N = 24; /* 円周を 24分割して線分で描画することにする */ int i; glBegin(GL_LINE_LOOP); for (i = 0; i < N; i++) glVertex2d(x + cos(2 * M_PI * i / N) * r, y + sin(2 * M_PI * i / N) * r); glEnd(); } int main(void) { double restitution = 1.0; /* はねかえり係数 */ int width = 640, height = 400; /* ウィンドウのサイズ */ long double x = 200.0, y = 200.0; /* ボールの中心位置 */ long double vx = 5.0, vy = 5.0; /* ボールの移動速度 */ long double r = 10.0; /* ボールの半径 */ long double g = 9.8; /* 重力加速度 */ long double dt = 0.1; /* 時間刻み */ /* グラフィック環境を初期化して、ウィンドウを開く */ glfwInit(); glfwOpenWindow(width, height, 0, 0, 0, 0, 0, 0, GLFW_WINDOW); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* 投影以外の座標変換は行わない */ for (;;) { /* Esc が押されるかウィンドウが閉じられたらおしまい */ if (glfwGetKey(GLFW_KEY_ESC) || !glfwGetWindowParam(GLFW_OPENED)) break; glfwGetWindowSize(&width, &height); /* 現在のウィンドウサイズを取得する */ glViewport(0, 0, width, height); /* ウィンドウ全面をビューポートにする */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, width, 0, height, -1.0, 1.0); /* この範囲の空間をビューポートに投影する */ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); /* バックバッファを黒で塗り潰す */ /* ウィンドウのサイズが変更されても、ボールがウィンドウ外に出ていかないようにする */ x = fminl(x, width - r); y = fminl(y, height - r); /* ボールを移動 */ x += vx; y += vy; /* ボール加速 */ vy -= g*dt; /* ウィンドウの上下左右の端にぶつかったらバウンド */ if (x <= r || x >= width - r) vx = -restitution*vx; if (y <= r || y >= height - r) vy = -restitution*vy; glColor3d(1.0, 1.0, 1.0); circle(x, y, r); /* ボールを描く */ glfwSwapBuffers(); /* フロントバッファとバックバッファを入れ替える */ usleep(40 * 1000); /* 40ミリ秒くらい時間待ち */ } glfwTerminate(); /* ウィンドウを閉じる */ return 0; }