今まで使用してきたサンプルは,すべてGLUTクラスを使用してモデルを描画してきました。

GLUTクラスが提供しているモデルを組み合わせることで,ロボットなどの3Dのモデルを構成しています。しかし,立方体や球を組み合わせてできるモデルには限界があります。

複雑なモデルを構成するには,より低レベルの要素を自分で使用します。こんなときに使うのがポリゴンです。

ポリゴンを描画してみる

ポリゴンと聞くと,つい3Dのゲームを思い出してしまいませんか。3D CGの専門用語のようですが,実際は多角形という意味の英語です。

多角形といっても,CGで使われるのはもっぱら三角形と四角形です。

3Dのモデルはポリゴンに分割されて描画されます。もちろん,今までこの解説で使用してきた立方体や球もポリゴンで構成されています。球のような曲面でも,小さいポリゴンにより分割することで,擬似的に曲面として描画できます。

ポリゴン以外にも,次のような要素(プリミティブ)を描画することができます。

  • 連続した線(開いた連続線と,閉じた連続線の2種類)
  • 三角形
  • 連続した三角形(三角形のつなげ方によって2種類)
  • 四角形
  • 連続した四角形
  • ポリゴン

これらのプリミティブを描画するには次のように記述します。

    gl.glBegin(...); // プリミティブの種類を指定
 
    gl.glVertex3f(); // 座標を指定
         ...
 
    gl.glEnd();

座標の指定にはGL#glVertex3fメソッド以外に,倍精度のglVertex3dメソッド,配列もしくはバッファを利用するglVertex3fv/glVertex3dvメソッドを利用できます。

例えば,ポリゴンで四角形を描画する場合,次のようになります。

サンプルはここからダウンロードできます: SimplePolygon.java

   // ポリゴンを描画することを指定
    gl.glBegin(GL.GL_POLYGON);
 
    // ポリゴンの各頂点を指定する
    gl.glVertex3f(-1.0f, -1.0f,  0.0f);
    gl.glVertex3f(1.0f, -1.0f,  0.0f);
    gl.glVertex3f(1.0f,  1.0f,  0.0f);
    gl.glVertex3f(-1.0f,  1.0f,  0.0f);
 
    gl.glEnd();
ポリゴン
図1 ポリゴン

ここで注意しなくてはならないのが,ポリゴンには表と裏があるということです。

座標が反時計方向に連なっている向きが表になります。描画速度を向上させるため,ポリゴンの裏側は描画されないことも多くあります。表と裏の違いから意外なところでポリゴンが描画されないことがあるので,ご注意ください。

例えば,上記のコードではz軸の正方向に向いている面が表で,負方向に向いている面が裏になります。

SimplePolygonを実行して,マウスでドラッグしてみましょう。はじめはポリゴンが見えていたのが,回転させると見えなくなってしまいます。このプログラムはポリゴンの裏側を描画していないので,このような現象が起こります。

また,180度以上の角度を持つ凹多角形は正しく描画されないことがあります。もし,凹があるような多角形を描画する場合は,すべて凸になるように三角形などを使用して分割します。

複数のポリゴンの描画

複数のポリゴンを描画することも同じように行えます。

ここではモノリスのような形状を作ってみます。

サンプルはここからダウンロードできます: Monolith.java

Monolithクラスでは座標値をフィールドとして保持してあります。

  // 頂点座標
  private float[] vertices = {
    // 正面
    -1.0f, -1.0f,  0.1f,
     1.0f, -1.0f,  0.1f,
     1.0f,  1.0f,  0.1f,
    -1.0f,  1.0f,  0.1f,
 
    // 右側面
     1.0f, -1.0f,  0.1f,
     1.0f, -1.0f, -0.1f,
     1.0f,  1.0f, -0.1f,
     1.0f,  1.0f,  0.1f,

         ...

GL#glVertex3fv/glVertex3dvメソッドは配列のオフセットを指定できるので,順々に読み出すようにできます。

    for (int i = 0; i < 6; i++) {
      // 各面の色を指定
      gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, COLORS[i], 0);

      // 面を描画
      gl.glBegin(GL.GL_POLYGON);
      for (int j = 0; j < 4; j++) {
        int index = i * 12 + j * 3;
        gl.glVertex3fv(vertices, index);
      }
			
      gl.glEnd();
    }
モノリス
図2 モノリス

このコードではモノリスの各面に異なる色を付けてみました。glBeginメソッドをコールする前に,glMaterialfvメソッドをコールすることで色を変化させることができます。ここでは環境光反射(GL_AMBIENT)しか指定していませんが,その他の反射も設定できます。

これを実行してみましょう。図2のようにカラフルなモノリスが表示されるはずです。

このサンプルはとても単純なものです。しかし,単純,複雑の違いはありますが,複数のポリゴンを使用してモデルを形成するという点では同じです。

今週はポリゴンの描画までを行いました。来週はこのポリゴンの見ばえをもう少しよくしてみましょう。見ばえをよくするために使うのがテクスチャです。テクスチャとは...説明は来週までとっておきましょう。

著者紹介 櫻庭祐一

横河電機の研究部門に勤務。同氏のJavaプログラマ向け情報ページ「Java in the Box」はあまりに有名