// // glut sample, tstglut.c (cppではなくてc!) // window management, rotate objects // // 注意:日本語で目一杯コメントが入っていますが、多分、lcc-win32で再コンパイル // する時は全部削ってからでないとコンパイルに失敗するでしょう。 // // 元ファイルがtab 4なので、表示が見難いです。ファイルに保存してから調整してください // #include // '/'でディレクトリを区切ってますが、VC++でもこれで // 通ったので、OKOKでしょう? void drawdat(void) // 描画データ { glBegin(GL_TRIANGLE_FAN); // 10個しかないOPEN GLのプリミティブの1つ、 // 「三角形をつなぎ合わせた扇型」の定義を開始する。 // 余談だけど、glutだと予め定義されてる図形がもっとある。 // だけどさぁ。球とか円錐は分かるけど、何でティーポットが // 一発で描けるのさ(^^;; // ま、気持ちは良く分かるんだけど... glColor3f(0.0, 1.0, 0.0); // 頂点の色。RGBで指定。関数名の最初が"gl" // なので、これはOpenGLの関数。また、最後が"3f" // なので、3つの引数を取る'f'、浮動小数点の関数と // 判断できる。よって値は0.0〜1.0まで。もし、 // glColor3i()を使うなら、0〜255までだと思う(^^;; glVertex3f(0.0, 0.0, 1.0); // 頂点。扇で言えば手で持つ所の座標。 // 当たり前だが、x,y,zの座標で指定されている glVertex3f(1.0, 0.0, 0.0); // 以下、扇の骨の先っぽの座標 glVertex3f(0.0, 1.0, 0.0); glColor3f(0.0, 0.0, 1.0); // この辺りで意味もなく色を変えてみる。こうして // 明示的に色を変えない限り、以前の色指定が生きている glVertex3f(-1.0, 0.0, 0.0); glVertex3f(0.0, -1.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glEnd(); // 1つ目のプリミティブ定義終わり glBegin(GL_TRIANGLE_FAN); // 2つ目のプリミティブ glColor3f(1.0, 0.0, 0.0); glVertex3f(0.0, 0.0, -1.0); glVertex3f(1.0, 0.0, 0.0); glVertex3f(0.0, -1.0, 0.0); glColor3f(0.0, 1.0, 0.0); glVertex3f(-1.0, 0.0, 0.0); glVertex3f(0.0, 1.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glEnd(); // glBegin()〜glEnd()で定義した立体は、「そういう物体だ」とOpenGLに認識され、 // 高速に処理されるらしい。形が変化したり、色が変化したりするよーなものは // 別のやり方があるらしいのだが、初心者なあたしにそれはどうするの?などと // 質問しても無駄である。 // でも、普通世間一般の現実社会にある物体ってのは、勝手に形とか色とか変化 // しないので、これでOKかもね。 // …確信があるわけでは全然ないけど、照明の具合によって色が変わって見える、 // というのは、物体そのものの色が変化するのとは違うから、glBeginで定義した // 物体の「夕暮れ時の様子」なんてのはOpenGLで別途照明を定義してやれば // OKOKで表示できる気がします。 // …信じないように。責任持ちませんよ。 // ところで、この頂点の定義ですが、順番が非常に大事らしいです。 // 反時計周りに定義してあるのが「表側」で、時計周りが「裏側」だそうな。 // 例えばドラムのようなもんを定義する場合、手前の円周の定義では反時計周りに // 座標を定義し、奥の円周では時計周り。という理解で良いのかな。 // でもよー分かりません。このサンプルが妙な回転表示をしてるのは私が座標指定を // うまく修正できなかったからでしょう(^^; } /* --- */ void display(void) // 表示関数。適宜呼ばれ、図形を回転させている { glClear(GL_COLOR_BUFFER_BIT); // 前に描いた図形をクリア glRotatef(4.0, 1.0, 1.0, 1.0); // 回転させる drawdat(); // 描く glFlush(); // えーと?(爆) glutSwapBuffers(); // 描画のバッファを裏・表で交換する } void reshape(int w, int h) // 再描画 { glViewport(0, 0, (GLsizei)w, (GLsizei)h); // Windowサイズに絵の大きさを調整 glMatrixMode(GL_PROJECTION); glLoadIdentity(); //gluOrtho2D(-1.2, 1.2, -1.2, 1.2); // Windowサイズを絵よりどれだけ大きくするか glMatrixMode(GL_MODELVIEW); } void keyboard(unsigned char key, int x, int y) { if (key == 0x1b) exit(0); // ASCIIコード1B。つまりESCキーが押されたらプログラム終了 glutPostRedisplay(); // キーが押されたら再描画。ちなみにカーソルキーとかの // 類は別の方法が必要らしいです(未調査) } int main(int argc, char** argv) { glutInit(&argc, argv); // 実際に引数があろうがなかろうが初期化の為に呼ぶ必要が // あるらしい glutInitDisplayMode(GLUT_DOUBLE); // デフォルトだと描画バッファが1枚。ここでは回転 // させる都合上、バッファを2つ取る // glutInitWindowSize(300, 300); // 呼ばない場合、300,300 // glutInitWindowPosition(0, 0); // 呼ばない場合、画面左上に表示される。 glutCreateWindow("Glut test, << Push Any key >>"); // 読んで字のごとく…… glClearColor(0.0, 0.0, 0.4, 0.0); // 背景色を青でちょいと塗り潰す glutDisplayFunc(display); // 表示関数をGLUTに通知 glutReshapeFunc(reshape); // 再表示関数をGLUTに通知 glutKeyboardFunc(keyboard); // キーが押されたときの関数をGLUTに通知 //glutIdleFunc(glutPostRedisplay); // 暇な時に再表示関数を呼ぶようにGLUTに通知 glutMainLoop(); // メインメッセージ・ループの開始。必須と思われる return 0; // ANSI Cですからねぇ。main()はちゃんとintを返さなくては(^^;; } /* eof */