~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  OpenGL 入門講座    「三次元グラフィックスの基礎とOpenGL関数の全体像を掴む」 第1-5回 「3D-CG基礎、ポリゴン表示、ワイヤー表示」用のプログラム ----- ワイヤー表示・ポリゴン表示 ----- ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 忘れたころにやってくる OpenGL 入門講座の続きです。 今回は、ワイヤー表示・ポリゴン表示について説明します。 ■ 三次元物体:  私たちの身の周りにある物体は、何からできているでしょうか。鉄、プラ  スチック、木...とお答えになるでしょうか。それとも、もっと小さな単位、  分子とか原子とかといった単位で、お答えになるでしょうか。  一見、単純な物体であっても、沢山の分子から構成されていますね。同じ  ように、三次元 CG の世界の物体も、沢山の小さな面から構成されていま  す。*1 この小さな面のことを、ポリゴン(多角形)といいます。  トイ・ストーリーのウッディやバズ *2、NINTENDO 64 のマリオ *3 も、ポ  リゴンで作られているのです。  ところで、三次元 CG の世界では、平面は得意な形ですが、滑らかな曲面  は不得意なのです。例えば、円柱を角柱で表現したりするのです。そのた  め、滑らかな曲面を表現するには、小さなポリゴンを何枚も使って表現す  ることになります。*4  ポリゴン数が多いと、データ量が増え、描画時間もかかるので、できる限  り少ないポリゴンで、見栄えのするモデルを作る技術が必要になります。 ■ モデリング:  複雑な三次元物体を、単純なポリゴンでモデルを作成する作業をモデリン  グといいますが、普通はモデリング・ソフト(三次元CAD)を使用して行いま  す。しかし、入門講座では、簡単な形状しか今のところ扱いませんので、  モデリング・ソフトを使用しません。グラフ用紙に、三面図を書いて、頂  点の座標値を求めることにしましょう。なお、モデリング・ソフトのこと  をモデラーと呼びます。  まず、物体をポリゴンに分け、各ポリゴンの頂点の三次元座標を、求めな  ければなければなりません。この時、気をつけばければならないことが、  あります。OpenGL が扱えるポリゴンは、凸ポリゴンだけであるということ  です。GLU を用いれば、凹ポリゴン、円柱、球なども扱えますが、これら  も内部で複数の凸ポリゴンに分解して表示しています。ですので、まずは  基本の凸ポリゴンを理解しましょう。 凸ポリゴンとは、すべての頂点の内角が180度未満のポリゴンのことです。 内角が180度以上の頂点が 1 つでもあれば、凹ポリゴンになります。三角 形は、必ず凸ポリゴンになります。平行四辺形も凸ポリゴンです。ですが、 凸ポリゴンの凸の字は、凸ポリゴンではなく、凹ポリゴンになります。     ■ 三次元座標空間:  モデリングを行うには、三次元座標空間がどのようになっているかを理解  しなければなりません。高校の空間図形を思い出していただければ、簡単  でしょう。空間図形を表すには、X, Y, Z の三つのパラメータが必要とな  ります。(直交座標系です。) 三次元 CG の世界では、空間を表すのに、右手系、左手系の二つの座標系 がありますが、 OpenGL では、右手系の座標系を用いています。 Y 右手の親指を右に向け、   ^ 人差し指を上に向けます。   I そうすれば、中指が自分の方向に向くでしょう。   I   I この時の、親指が X 軸となります。  +--------> X 人差し指が Y 軸、中指が Z 軸となります。 / そして、指の指す方向が正の方向となります。 / V -----------------------> Z +-+-+-+-+ 右手の親指の向く方向を | | | | |_____ 座標軸の向きとすると、 +-+-+-+-+ | 軸の正の回転方向は、残 | I I ------ り、4本の指が示す回転 |_ _| 方向です。 | | (<- 右手です。^^;) なお、左手系の座標系では、Z の方向が逆になります。  この他に、建築座標系と呼ばれる X-Y 平面で、高さが Z である座標系を  使う場合もあります。(右手系の座標系で、X 軸周りに -90度回転したもの) ■ ローカル座標系とワールド座標系: 通常、三次元CGの世界では、空間上に配置される個々の物体の座標と空間 の座標を別々に定義します。前者をローカル座標系といい、後者をワール ド座標系といいます。 ○ローカル座標系  モデリングの座標系。  車、家、人などモデリングは、それぞれの独立した座標空間で作成しま  す。それは、その方が楽だからです。*5 ○ワールド座標系  物体を配置する座標系。  ローカル座標系でモデリングされた物体を配置します。  視点や、光源の位置もワールド座標で指定します。 先程の右手系、左手系との分類とは異なりますので注意してください。 例えば、ローカル座標系が左手系で、ワールド座標系が右手系といったシ ステムでも構わないのです。(OpenGL では、どちらも右手系です。) ■ プリミティブ: プリミティブとは、基本物体のことです。OpenGL では、ポリゴンやワイ ヤー・フレーム等を指します。 プリミティブは、次のような手順で表示します。 glBegin( タイプ ); glVertex{2,3,4}{s,i,f,d}[v] (.....); glVertex{2,3,4}{s,i,f,d}[v] (.....);        :        : glEnd();  プリミティブの頂点リストの開始と終了をしめす関数が、 glBegin() と  glEnd() です。glBegin() の引数には、GL_LINES(ライン)、  GL_POLYGON(ポリゴン)等のタイプを指定します。 プリミティブの頂点を指定する関数が、glVertex*() です。 glColor*() の時と同じように、引数の種類によって使用する関数が異なります。 glVertex*() は、glVertex2f() や glVertex3fv() などいくつかの関数を まとめた表現です。(* には、接尾子が付きます。) glVertex2f(GLfloat x, GLfloat y) glVertex3f(GLfloat x, GLfloat y, GLfloat z) glVertex2fv(GLfloat *coords) glVertex3fv(GLfloat *coords)       :        :  このように、最初の接尾子が 2 のものが、二次元の座標(x,y)を指定する もので、3 が、三次元の座標(x,y,z) を指定するものです。 2 番目の接尾子は、引数の型を指定するものです。f は float であり、d は、double を表します。 3 番目の接尾子 v が付いているものは、配列のポインタで指定するもの です。  なお、頂点は glBegin() と glEnd() の間に指定しなければなりません。 ■ ワイヤー・フレーム: ワイヤー・フレームとは、物体を線(ワイヤー)で表現するものです。 単純であることから描画が速く、アニメーションのプレビューなど、速度 を要求される場面によく利用されます。 program1_1.c では、X,Y,Z 軸をしめす矢印をワイヤー・フレームで表現 しています。 矢印の軸は GL_LINES、矢は GL_LINE_LOOP を使っています。  GL_LINES と GL_LINE_LOOP の違いは、終点から始点に線を結ぶかどうか  の違いです。 glBegin(GL_LINES); /* ラインの開始宣言 */ glVertex3fv(ax1); /* 第1頂点を指定 */ glVertex3fv(ax2); /* 第2頂点を指定 */ glEnd(); /* ラインの終了宣言 */ glBegin(GL_LINE_LOOP); /* GL_LINES と GL_LINE_LOOP の違いは、*/ glVertex3fv(ax3); /* 終点から始点を結ぶかどうかです。 */ glVertex3fv(ax2); /* GL_LINE_LOOP は終点から始点を結び */ glVertex3fv(ax4); /* ます。 */ glEnd(); ■ ポリゴン: program1_1.c では、箱 がポリゴンで表現されています。基本の GL_POLYGON を使っています。 この箱は、6 枚の平面ですので、6 枚のポリゴンで表現しています。 program1_1.c のポリゴンの色は、前回に説明したように、面ごとに色を付 けています。 glColor3fv(blue); /* ポリゴン・カラーの設定 */ glBegin(GL_POLYGON); /* ポリゴン開始宣言 */ glVertex3fv(v1); /* 第1頂点   箱の一つの面は、 */ glVertex3fv(v2); /* 第2頂点   正方形であるから */ glVertex3fv(v3); /* 第3頂点    頂点が4つになり */ glVertex3fv(v4); /* 第4頂点 ます。 */ glEnd(); /* ポリゴン終了宣言 */ 注意) ポリゴンは、あくまでも一平面ですから、ポリゴンを構成するすべての頂 点が、同一平面上になければなりません。もし、同一平面上にない場合は、 面が正しく表示されません。注意してください。 ■ 自由課題:   1. 立方体の箱を直方体の箱に変えてください。   2. 箱をポリゴンから、ワイヤーフレームに変更してください。   3. 六面の色をすべて変えてください。   今回のプログラムを一部手直しすれば、簡単にできますので、一度やって   みてください。 ■ 用語解説: ○ メタボール 濃度球。曲面を生成する手法で阪大で考え出されたものです。 外国では、呼び名が異なります。 ○ プリミティブ   プリミティブとは、基本物体のことです。OpenGL では、ポリゴンや   三角形メッシュ、ワイヤー・フレーム等を指します。   GLU であれば、球や円柱が基本物体になります。 ○ プレビュー アニメーションでのカメラワークのチェックや、物体の動きのチェッ クには、リアルタイムに近い速度が要求されます。最終レンダリング のクオリティでは、リアルタイムでのアニメーションは難しいため、 ワイヤー・フレームにするか、解像度を落とす等の工夫を行い、リア ルタイムに近い状態でレンダリングを行います。このような最終レン ダリングの前チェックをプレビューと言います。 ■ 注釈  *1) これは、サーフェイスモデルの場合です。OpenGL では、サーフェイ   スモデルという、表面だけの中身のないモデルを扱います。この他の   モデルとしては、ソリッドモデルというものがあります。 *2) もしかすると、ポリゴンではなく、パッチ曲面かもしれません。 PIXER のレンダーマンは、ポリゴンの他、パッチ曲面等が扱えるから です。ここでは、便宜上、ポリゴンであるとしています。 *3) NINTENDO 64 のマリオと言えば、メタルマリオが面白いですね。リフ レクション・マッピングされたマリオなのですが、OpenGL のリフレ クション・マッピングの結果とよく似ています。(^o^;) *4) レイ・トレーシング法を用いたものでは、直接二次曲面や、メタボー ルなどのプリミティブを扱えるものも多くあります。    *5) この理由ついては、また詳しく説明する機会があるかと思います。    ■ 次回予告:  第1-6回では、透視変換について説明します。 ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -- 寺西 忠勝