Japanese | English | Korean

Samples

プリミティブの描画

ここでは単純な Primitive オブジェクトの描画について解説します。
Primitive オブジェクトは1つ以上のプリミティブデータから構成されるオブジェクトです。Figure オブジェクトとは異なりボーンを持たず ActionTable との関連付けも行うことができません。 また、1つの Primitive オブジェクトは1種類のプリミティブしか扱えませんが、同一のプリミティブであれば最大 255 個の図形を持つことができます。

目次


1.プリミティブの種類

Primitive オブジェクトで扱うことのできるプリミティブには、以下の5種類があります。

  • 点(Points)

  • 1ピクセルで表現される点です。
    プリミティブ単位で色を指定することが可能です。

    プリミティブ情報 設定の有無 配列のフォーマット
    頂点情報 必須 プリミティブ数×3
    法線情報 なし  
    色情報 必須 プリミティブ数と同じまたは全体で1つ
    テクスチャ情報 なし  
  • 線(Lines)

  • 2頂点を結ぶ線分です。
    プリミティブ単位で色を指定することが可能です。

    プリミティブ情報 設定の有無 配列のフォーマット
    頂点情報 必須 プリミティブ数×2×3
    法線情報 なし  
    色情報 必須 プリミティブ数と同じまたは全体で1つ
    テクスチャ情報 なし  
  • 三角形(Triangles)

  • 3頂点からなるポリゴンです。
    プリミティブ単位での色の指定、及びテクスチャマッピングが可能です。

    プリミティブ情報 設定の有無 配列のフォーマット
    頂点情報 必須 プリミティブ数×3×3
    法線情報 任意 設定しないときはライトの影響を受けません(後述)
    プリミティブに対し1つであれば、1つの法線をすべての頂点に設定したときと同じ状態となります(プリミティブ数×3)
    各頂点に対し設定する場合、頂点ごとに法線が1つ必要です(プリミティブ数×3×3)
    色情報 必須 テクスチャを使用するときは不要です
    テクスチャ非使用時は、プリミティブ数と同じ または全体で1つ
    テクスチャ情報 任意 色情報を指定する場合は不要です
    テクスチャを使用する場合は、各頂点ごとにテクスチャ座標が1つ必要です(プリミティブ数×3×2)
  • 四角形(Quads)

  • 4頂点からなるポリゴンです
    プリミティブ単位での色の指定、及びテクスチャマッピングが可能です。

    プリミティブ情報 設定の有無 配列のフォーマット
    頂点情報 必須 プリミティブ数×4×3
    法線情報 任意 設定しないときはライトの影響を受けません(後述)
    プリミティブに対し1つであれば、1つの法線をすべての頂点に設定したときと同じ状態となります(プリミティブ数×3)
    各頂点に対し設定する場合、頂点ごとに法線が1つ必要です(プリミティブ数×4×3)
    色情報 必須 テクスチャを使用するときは不要です
    テクスチャ非使用時は、プリミティブ数と同じ
    または全体で1つ
    テクスチャ情報 任意 色情報を指定する場合は不要です
    テクスチャを使用する場合は、各頂点ごとにテクスチャ座標が1つ必要です(プリミティブ数×4×2)
  • ポイントスプライト(Point Sprites)

  • 画面に対し常に正面を向くように画像を表示します。
    1枚のテクスチャをマッピングすることが可能です。

    プリミティブ情報 設定の有無 配列のフォーマット
    頂点情報 必須 プリミティブ数×3
    法線情報 なし  
    色情報 なし  
    テクスチャ情報 なし  
    ポイントスプライト情報 任意 プリミティブ数×8


2.プリミティブの描画

ここではサンプルとして、線、三角形、ポイントスプライトを取り上げます。

2.1.Primitive オブジェクトの取得

まずPrimitive オブジェクトを生成し、それぞれに対しプリミティブの種別等の情報を設定します。

[Primitive オブジェクトの生成]

// Primitive オブジェクトの生成
Primitive line;
Primitive triangle;
Primitive pointsprite;

・・・

// Sample06Canvas.java 60行
// 直線の設定
line = new Primitive( Primitive.PRIMITIVE_LINES,
Primitive.COLOR_PER_PRIMITIVE,
1 );

・・・

// Sample06Canvas.java 74行
// 三角形の設定
triangle = new Primitive( Primitive.PRIMITIVE_TRIANGLES,
Primitive.COLOR_PER_PRIMITIVE |
Primitive.NORMAL_PER_FACE,
1 );

・・・

// Sample06Canvas.java 96行
// ポイントスプライトの設定
pointSprite = new Primitive( Primitive.PRIMITIVE_POINT_SPRITES,
Primitive.SPRITE_PER_PRIMITIVE,
1 );

Primitive.PRIMITIVE_LINES, Primitive.PRIMITIVE_TRIANGLES, Primitive.PRIMITIVE_POINT_SPRITESはプリミティブの型を表し、それぞれ線、三角形、ポイントスプライトであることを表しています。この宣言によって Primitive オブジェクトがそれぞれのプリミティブとして指定されます。

次に、Primitive.COLOR_PER_PRIMITIVEは色情報を各プリミティブごとに持たせるのではなく、オブジェクト全体で1つの色情報を持つことを表しています。Primitive.NORMAL_PER_FACE はプリミティブごとに1つの法線情報を持つことを表します。
Primitive.SPRITE_PER_PRIMITIVE は各プリミティブごとにポイントスプライト情報を持つのではなく、オブジェクト全体で1つのプリミティブ情報を持つことを表します。

法線情報、色情報、テクスチャ情報、およびポイントスプライト情報はプリミティブ情報と呼ばれ、論理和により組み合わせて指定します。なお、色情報とテクスチャ情報を同時に指定することはできません。

プリミティブの数は最初に述べたように、同一のプリミティブであれば最大で 255 個まで指定することが可能です。 また頂点情報、およびプリミティブ情報は Primitive オブジェクトが生成されたときに、自動的に情報を格納するための配列が用意されます。配列のサイズは、プリミティブの個数や種別によって異なります。

2.2.各プリミティブ情報の設定

  • 線(Lines)

  • ここでは線に関するプリミティブ情報を設定します。

    [1つの線プリミティブ]


    ・・・

    // Sample06Canvas.java 60行
    // 直線の設定
    line = new Primitive( Primitive.PRIMITIVE_LINES,
    Primitive.COLOR_PER_PRIMITIVE,
    1 );
    // 頂点情報配列を直接書き換えることで設定
    line.getVertexArray()[0] = -400; // 端点( -400, 0, 0 )
    line.getVertexArray()[1] = 0;
    line.getVertexArray()[2] = 0;
    line.getVertexArray()[3] = -200; // 端点( -200, 0, 0 )
    line.getVertexArray()[4] = 0;
    line.getVertexArray()[5] = 0;
    // 色情報配列を直接書き換えることで設定
    line.getColorArray()[0] = ( 255 << 16 ) | 128;

    ・・・



    直線は2点からなるプリミティブですので2点の座標を設定する必要があります。そこでgetVertexArray() メソッドにより頂点情報配列を取得し、それを直接書き換えることで各座標を設定します。
    頂点情報配列には { x0, y0, z0, x1, y1, z1, x2, … } という順番で頂点情報が格納されています。また、 getVertexArray()[ i ] によって頂点情報配列の i 番目の情報を参照することができます。

    次に、色情報はこのサンプルの場合全体で1つ必要ですので、 getColorArray() メソッドにより取得した色情報配列に頂点情報と同様に色情報を設定します。
    色情報配列には { ((r0 << 16) | (g0 << 8) | b0), ((r1 << 16) | (g1 << 8) | b1), … } という順番で色情報が格納されています。なお、色情報配列の各要素について上位8ビットは無視されます。


  • 三角形(Triangles)

  • ここでは三角形に関するプリミティブ情報を設定します。

    [1つの三角形プリミティブ]


    ・・・

    // Sample06Canvas.java 74行
    // 三角形の設定
    triangle = new Primitive( Primitive.PRIMITIVE_TRIANGLES,
    Primitive.COLOR_PER_PRIMITIVE |
    Primitive.NORMAL_PER_FACE,
    1 );
    // 頂点情報配列を直接書き換えることで設定
    triangle.getVertexArray()[0] = 0; // 頂点( 0, 100, 0 )
    triangle.getVertexArray()[1] = 100;
    triangle.getVertexArray()[2] = 0;
    triangle.getVertexArray()[3] = -100; // 底点( -100, -100, 0 )
    triangle.getVertexArray()[4] = -100;
    triangle.getVertexArray()[5] = 0;
    triangle.getVertexArray()[6] = 100; // 底点( 100, -100, 0 )
    triangle.getVertexArray()[7] = -100;
    triangle.getVertexArray()[8] = 0;
    // 色情報配列を直接書き換えることで設定
    triangle.getColorArray()[0] = ( 255 << 8 ) | 255;
    // 法線情報配列を直接書き換えることで設定
    triangle.getNormalArray()[0] = 0; // 法線ベクトル( 0, 0, 4096 )
    triangle.getNormalArray()[1] = 0;
    triangle.getNormalArray()[2] = 4096;

    ・・・




    三角形は3点からなる図形ですので3頂点の座標を設定する必要があります。頂点情報、および色情報の設定は線プリミティブと同様です。
    法線情報配列は getNormalArray()メソッドにより取得でき、この法線情報配列に対し法線情報を設定します。また、法線情報配列には { x0, y0, z0, x1, … } という順番で法線情報が格納されています。このとき、法線情報には各法線ベクトルの向きが設定されます。


  • ポイントスプライト(Point Sprites)
  • ここではポイントスプライトに関するプリミティブ情報を設定します。

    [1つのポイントスプライト]


    ・・・

    // Sample06Canvas.java 96行
    // ポイントスプライトの設定
    pointSprite = new Primitive( Primitive.PRIMITIVE_POINT_SPRITES,
    Primitive.POINT_SPRITE_PER_PRIMITIVE,
    1 );
    // 頂点情報配列を直接書き換えることで設定
    pointSprite.getVertexArray()[0] = 300; // 頂点( 300, 0, 0 )
    pointSprite.getVertexArray()[1] = 0;
    pointSprite.getVertexArray()[2] = 0;
    // ポイントスプライト情報配列を直接書き換えることで設定
    pointSprite.getPointSpriteArray()[0] = 256; // テクスチャサイズ 256 * 256
    pointSprite.getPointSpriteArray()[1] = 256;
    pointSprite.getPointSpriteArray()[2] = 0;
    pointSprite.getPointSpriteArray()[3] = 0;
    pointSprite.getPointSpriteArray()[4] = 0;
    pointSprite.getPointSpriteArray()[5] = 255;
    pointSprite.getPointSpriteArray()[6] = 255;
    pointSprite.getPointSpriteArray()[7] =
    Primitive.POINT_SPRITE_FLAG_LOCAL_SIZE;

    ・・・




    ポイントスプライトはテクスチャがマッピングされたものですので、1頂点の座標を設定する必要があります。
    頂点情報の設定は線プリミティブ、および三角形プリミティブと同様です。ただしポイントスプライトの頂点はポイントスプライトの中点として設定されます。

    ポイントスプライト情報配列は getPointSpriteArray() メソッドにより取得でき、この配列に対しポイントスプライト情報を設定します。また、ポイントスプライト情報配列には { w0, h0, angle0, u00, v00, u10, v10, flag0, w1, … } という順番でポイントスプライト情報が格納されています。なお、 Primitive.POINT_SPRITE_FLAG_LOCAL_SIZE はポイントスプライトの幅と高さがモデル座標系のものであることを表します。


2.3.テクスチャに関する設定

Primitive オブジェクトのうちポイントスプライト、または三角形や四角形に対しテクスチャを貼り付ける場合 Texture オブジェクトが必要になります。
ここでは Primitive オブジェクトと Texture オブジェクトの関連付けについてポイントスプライトを例として解説します。

[Texture オブジェクトの設定]

// テクスチャ
Texture texture;

・・・

// Sample06Canvas.java 114行
// テクスチャの読み込み
try {
texture = ( Texture ) Object3D.createInstance(
Connector.openInputStream( “resource:///texture.bmp” ) );
}

・・・

// Sample06Canvas.java 123行
// テクスチャ貼り付け
pointSprite.setTexture( texture );

・・・


Primitive オブジェクトに Texture オブジェクトを関連付ける際には setTexture() メソッドを使用します。これにより、各プリミティブに対しテクスチャを貼り付けることが可能になります。
ただし Figure オブジェクトとは異なり、単一の Primitive オブジェクトに対し複数の Texture オブジェクトを関連付けることはできません。


2.4.各プリミティブの描画

ここでは実際に Primitive オブジェクトを描画してみます。

[Primitive オブジェクトの描画]


・・・

// Sample06Canvas.java 183行
// Primitive オブジェクトの描画
g3.renderObject3D( line, trans );
g3.renderObject3D( triangle, trans );
g3.renderObject3D( pointSprite, trans );

・・・

Primitive オブジェクトの描画にも他の 3D オブジェクト同様 renderObject3D() メソッドを使用します。

 

プリミティブの描画(左画像:表面、右画像:裏面)



3.プリミティブ独自の特徴

プリミティブは大きくカテゴリ分けすると以下の2つに分類されます。

  • ポリゴン(三角形、四角形)
  • 特殊プリミティブ(点、線、ポイントスプライト)

このうち特殊プリミティブは光源の影響を受けません。常に設定した色またはテクスチャで描画が行われます。また、ポリゴンについても法線情報が設定されていないものについては同様に光源の影響を受けません。

特殊プリミティブを Figure オブジェクト等のその他オブジェクトと同時にレンダリングした場合、Z位置は考慮されず特殊プリミティブでないオブジェクトが正しく描画された後に特殊プリミティブがその上に描画されます。また透視投影を行う場合、特殊プリミティブを極端な位置に配置したり、ニア面の距離の値を非常に小さく(特に1.0以下)設定する、あるいはニア面とファー面の距離の差を非常に大きく(特に1000.0以上)設定する場合、演算時のオーバーフローが起こりやすくなります。
いずれの場合も結果として予期したとおりの描画が行われない可能性があります。