サンプル

プリミティブの描画


描画できるプリミティブは以下のものがあります。

プリミティブ 説明
1ピクセルで描画される点。
プリミティブ単位で色を指定できる。
ブレンド処理方法(ブレンドなし、半透明、加算、減算)を属性として選択できる。
ライン 2点を直線で結んだ幅1ピクセルのライン。
プリミティブ単位で色を指定できる。
ブレンド処理方法を属性として選択できる。
三角ポリゴン 3点を指定することで描画される三角ポリゴン
  • カラーポリゴン又はテクスチャポリゴン
  • 頂点単位の法線又はプリミティブ単位の法線
  • ブレンド処理方法
  • 光源処理の有無
  • スフィアマップの有無
といったポリゴン属性を選択できる
四角ポリゴン 4点を指定することで描画される四角ポリゴン。
選択できるポリゴン属性は三角ポリゴンと同様。
ポイントスプライト 表示座標を指定し、常に視点方向を向いた四角ポリゴンを描画する。
ブレンド処理方法を指定できる。

これらのプリミティブの描画方法は、MascotCapsule V3 では以下の3種類の方法があります。


  1. OEMC_Micro3D_Render_drawPrimitive( Render* This, hi_sint32 primtype, IntArray* coord, IntArray* normal, IntArray* texcoord, IntArray* color ) を使用して一種類のプリミティブを複数個一括で描画する方法。
  2. OEMC_Micro3D_Render_drawCommandList( Render* This, IntArray* array ) を使用して複数種類のプリミティブを一括で描画する方法。
  3. OEMC_Micro3D_bgeinPrimitive( Render* This, hi_sint32 primtype ) から始まり、OEMC_Micro3D_endPrimitive( Render* This ) で終了する、1プリミティブずつ指定する方法。

これらの方法のうち、3. の方法は関数呼び出しが冗長になるためお勧めできません。通常は 1. あるいは、コマンドリストに抵抗がなければ 2. を推奨します。
ここでは 1. の OEMC_Micro3D_Render_drawPrimitive() を使用したプリミティブの描画方法について説明します。

 
環境光+平行光源 環境光のみ





1. 各種プリミティブ

ここでは MascotCapsule V3 で描画できるプリミティブについて説明します。

1.1. 点

三次元座標を指定して点を描画します。描画される点はスクリーンの設定によらず、1ピクセルで表現されます。
点を描画する際には、以下のパラメータが必要です。

1.2. ライン

三次元座標で示される2点間を結ぶラインを描画します。描画されるラインの幅はスクリーンの設定によらず、1ピクセルで表現されます。
ラインを描画する際には、以下のパラメータが必要です。

1.3. 三角ポリゴン

三次元座標で示される3点で構成される三角ポリゴンを描画します。三角ポリゴンにはテクスチャを貼り付けるテクスチャポリゴンと、色を指定し、単色で描画されるカラーポリゴンがあります。
三角ポリゴンを描画する際には、以下のパラメータが必要です。

1.4. 四角ポリゴン

三次元座標で示される4点で構成される四角ポリゴンを描画します。三角ポリゴン同様、四角ポリゴンもテクスチャポリゴンとカラーポリゴンがあります。
四角ポリゴンを描画する際には、以下のパラメータが必要です。

1.5. ポイントスプライト

三次元座標で示される1点を中心とした、視点に対し常に正面を向く四角ポリゴンを描画します。
ポイントスプライトを描画する際には、以下のパラメータが必要です。


なお、MascotCapsule V3 におけるポイントスプライトは、表示の際、以下のフラグを指定して表示方法を決定します。

フラグ 説明
M3DPSF_LOCAL_SIZE モデル座標系におけるサイズを指定します。
M3DPSF_PIXEL_SIZE スクリーン座標系におけるサイズを指定します。
M3DPSF_PERSPECTIVE 透視投影においてパースを有効にします。
M3DPSF_NO_PERS 透視投影においてパースを無効にします。

これらのフラグを論理輪で表示方式として指定します。
ただし、M3DPSF_LOCAL_SIZE と M3DPSF_PIXEL_SIZE 、および M3DPSF_PERSPECTIVE と M3DPSF_NO_PERS はそれぞれ排他的な関係にあります。




2. プリミティブ描画

ここでは前述の通り OEMC_Micro3D_Render_drawPrimitive() を用いたプリミティブの描画について説明します。
OEMC_Micro3D_Render_drawPrimitive() を使用することにより、複数のプリミティブを一度に描画設定することができるようになります。このとき、一度に設定できるのは同じ属性を持つ、同じプリミティブのみです。異なるプリミティブ、あるいは同じプリミティブでも異なる属性を持つ場合には別々に描画設定を行う必要があります。

(例) 同じプリミティブで異なる属性を持つ場合
       法線をプリミティブ単位で持つ三角ポリゴンと頂点単位で持つ三角ポリゴン等


OEMC_Micro3D_Render_drawPrimitive() は引数として、Render オブジェクトのポインタのほかに以下のものを指定する必要があります。

以下に各引数の説明を行います

2.1. プリミティブの種類、属性、データタイプ、および数

これらの引数の指定方法は以下の通りです

プリミティブの種類|プリミティブの属性 | プリミティブのデータタイプ | (プリミティブの数 << 16)

というように各項目の論理和を指定します。

/**
  * 三角ポリゴン用構造体
  * typedef struct tag_Triangle{
  *         IntArray coord;     /* 頂点情報配列 */
  *         IntArray normal;   /* 法線情報配列 */
  *         IntArray color;     /* 色情報配列 */
  * }Triangle;
  */

/* 三角ポリゴン */
OEMC_Micro3D_Render_drawPrimitive( &render,
M3DP_TRIANGLES | M3DPD_TEXCOORD_NONE |
M3DPD_NORMAL_PER_FACE | M3DPD_COLOR_PER_FACE |
M3D_BLEND_NORM | M3D_LIGHTING | ( 2 << 16 ),
&triangle.coord, &triangle.normal, NULL, &triangle.color );

プリミティブの個数は 16bit 左シフトする必要があることに注意してください。OEMC_Micro3D_Render_drawPrimitive() で一度に設定できるプリミティブの個数は最大で 255 個です。また、属性、およびデータタイプに関しては必要なものを連記することができます。


プリミティブの種類は以下の宣言から指定します。

プリミティブ 宣言
M3DP_POINTS
ライン M3DP_LINES
三角ポリゴン M3DP_TRIANGLES
四角ポリゴン M3DP_QUADS
ポイントスプライト M3DP_POINT_SPRITES

プリミティブの指定は一回の関数呼び出しにつき、必ず一つだけです。



属性に関しては以下の宣言の中から指定します。

宣言 説明
M3D_LIGHTING プリミティブは光源処理の対象となります。
点、ライン、ポイントスプライトでは無効です。
M3D_SPECULAR プリミティブはスフィアマップ処理の対象となります。
点、ライン、ポイントスプライトでは無効です。
M3D_COLORKEY プリミティブはカラーキーによる透過処理の対象となります。 点、ラインでは無効です。
M3D_BLEND_NORM ブレンド処理を行いません。
M3D_BLEND_HALF 半透明処理を行います。
M3D_BLEND_HALF 加算処理を行います。
M3D_BLEND_SUB 減算処理を行います

属性の設定は必要なものを論理和で追加してください。
ただし、プリミティブによっては受け付けない属性もあります。
また、光源、スフィアマップ、カラーキー、ブレンド処理等については、それぞれ詳細なマニュアルをご参照ください。


データタイプに関しては以下の宣言から指定します。

宣言 説明
M3DPD_NORAML_PER_FACE プリミティブ単位で法線を持ちます。
点、ライン、ポイントスプライトでは無効です。
M3DPD_NORMAL_PER_VERTEX 頂点単位で法線を持ちます。
点、ライン、ポイントスプライトでは無効です。
M3DPD_COLOR_PER_FACE プリミティブ単位で色情報を持ちます。
ポイントスプライトでは無効です。
点、ラインでは必ず指定してください。
M3DPD_TEXCOORD テクスチャ位置情報を持ちます。
点、ラインでは無効です。
M3DPD_TEXCOORD_AND_PS_PARAMS_PER_FACE ポイントスプライトのテクスチャ位置情報を持ちます。
ポイントスプライトでのみ有効です。
ポイントスプライトではこれか、 M3DPD_TEXCOORD_AND_PS_PARAMS_PER_VERTEX を必ず指定してください。( * )
M3DPD_TEXCOORD_AND_PS_PARAMS_PER_VERTEX ポイントスプライトのテクスチャ位置情報を持ちます。
ポイントスプライトでのみ有効です。
ポイントスプライトではこれか、 M3DPD_TEXCOORD_AND_PS_PARAMS_PER_FACE を必ず指定してください。( * )
M3DPD_NORMAL_NONE 法線情報を持ちません。
M3DPD_COLOR_NONE 色情報を持ちません。
M3DPD_TEXCOORD_NONE テクスチャ位置情報を持ちません。

( * )M3DPD_TEXCOORD_AND_PS_PARAMS_PER_FACE と M3DPD_TEXCOORD_AND_PS_PARAMS_PER_VERTEX は処理としては同じ効果が得られます。両者の違いは、プログラム上の使用方法の相違になります。


データタイプの設定も属性等同様、必要なものを論理和で追記してください。プリミティブによっては受け付けないデータタイプ、または必須のデータタイプがあります。




2.2. 頂点配列

頂点配列の指定には IntArray を使用します。
プリミティブの種類によって必要な頂点数は異なりますので、適切な数の頂点を設定してください。

/**
  * 整数配列用コンテナ
  * typedef struct tagIntArray {
  *       hi_sint32 num;
  *       hi_sint32* array;
  * } IntArray;
  */

/* 頂点情報配列 */
static const hi_sint32 _coord_array[] = {
0, 500, 0, -256, 0, 0, 256, 0, 0, /* 1 */
0, -500, 0, -256, 0, 0, 256, 0, 0, /* 2 */
};

/* 各情報配列用コンテナ */
const IntArray triangle_coord = { sizeof( _coord_array ) /
sizeof( _coord_array[0] ), _coord_array };


/**
  * プリミティブ初期化
  */
triangle.coord = triangle_coord;
プリミティブ 必要な頂点数
プリミティブ数×1
ライン プリミティブ数×2
三角ポリゴン プリミティブ数×3
四角ポリゴン プリミティブ数×4
ポイントスプライト プリミティブ数×1

実際には各頂点は ( x, y, z ) の三要素から成り立ちますので、配列そのものの大きさは頂点数×3となります。頂点の三要素の格納順は x, y, z の順です。





2.3. 法線配列

法線配列の指定には IntArray を使用します。プリミティブの種類、および、データタイプによって必要な法線数は異なりますので、適切な数の法線を設定してください。

/* 法線情報配列 */
static const hi_sint32 _normal_array[] = {
0, 0, -4096, /* 1 */
0, 0, -4096, /* 2 */
};

/* 各情報配列用コンテナ */
const IntArray triangle_normal = { sizeof( _normal_array ) /
sizeof( _normal_array[0] ), _normal_array };


/**
  * プリミティブ初期化
  */
triangle.normal = triangle_normal;
プリミティブ データタイプ 必要な法線数
- - - 0
ライン - - - 0
三角ポリゴン M3DPD_NORMAL_PER_FACE プリミティブ数×1
M3DPD_NORMAL_PER_VERTEX プリミティブ数×3
四角ポリゴン M3DPD_NORMAL_PER_FACE プリミティブ数×1
M3DPD_NORMAL_PER_VERTEX プリミティブ数×4
ポイントスプライト - - - 0

実際には各法線は ( x, y, z ) の三要素から成り立ちますので、配列そのものの大きさは法線数×3となります。法線の三要素の格納順は x, y, z の順です。





2.4. テクスチャ位置情報配列

テクスチャ位置情報配列の指定には IntArray を使用します。プリミティブの種類、および、データタイプによって必要なテクスチャ位置情報の数は異なりますので、適切な数のテクスチャ位置情報を設定してください。

/**
  * 四角ポリゴン用構造体
  * typedef struct tag_Quad{
  *       IntArray coord;       /* 頂点情報配列 */
  *       IntArray color;       /* 色情報配列 */
  *       IntArray texcoord; /* テクスチャ位置情報配列 */
  * }Quad;
  */

/* テクスチャ位置情報配列 */
static const hi_sint32 _texcoord_array[] = {
255, 255, 0, 255, 0, 0, 255, 0,
};

/* 各情報配列用コンテナ */
const IntArray quad_texcoord = { sizeof( _texcoord_array ) /
sizeof( _texcoord_array[0] ), _texcoord_array };

/**
 * プリミティブ初期化
 */
quad.texcoord = quad_texcoord;

プリミティブ データタイプ 必要なテクスチャ位置情報の数
- - - 0
ライン - - - 0
三角ポリゴン M3DPD_COLOR_PER_FACE 0
M3DPD_TEXCOORD プリミティブ数×3
四角ポリゴン M3DPD_COLOR_PER_FACE プリミティブ数×3
M3DPD_TEXCOORD プリミティブ数×4
ポイントスプライト - - - プリミティブ数×1(**)

三角ポリゴン、および四角ポリゴンの頂点情報はテクスチャ上の2次元座標 ( x, y ) ですので、配列そのものの大きさはテクスチャ位置情報の数×2となります。また、三角ポリゴン、および四角ポリゴンの頂点情報で設定された座標と、テクスチャ位置情報で設定された座標は設定された順番に応じて対応付けがなされます。

( * * )ポイントスプライトの場合、ポイントスプライトの各パラメータもここに含まれます。
ポイントスプライトに必要なパラメータは、

以上のものがあり、配列そのものの大きさはプリミティブ数×8となります。





2.5. 色情報配列

色情報配列の指定には IntArray を使用します。プリミティブの種類、および、データタイプによって必要な法線数は異なりますので、適切な数の色情報を設定してください。

/* 色情報配列 */
static const hi_sint32 _color_array[] = {
0 << 16 | 255 << 8 | 0, /* 1 */
255 << 16 | 0 << 8 | 128, /* 2 */
};

/* 各情報配列用コンテナ */
const IntArray triangle_color = { sizeof( _color_array ) / sizeof( _color_array[0] ), _color_array };

/**
  * プリミティブ初期化
  */
triangle.color = triangle_color;

プリミティブ データタイプ 必要な色情報の数
- - - プリミティブ数×1
ライン - - - プリミティブ数×1
三角ポリゴン M3DPD_COLOR_PER_FACE プリミティブ数×1
M3DPD_TEXCOORD 0
四角ポリゴン M3DPD_COLOR_PER_FACE プリミティブ数×1
M3DPD_TEXCOORD 0
ポイントスプライト - - - 0

色情報は RGB で各要素が 8bit の 24bit 形式で指定します。これは、実際の環境のピクセル情報に左右されることがありません。

( R 要素 << 16 ) | ( G << 8 ) | ( B )

したがって、配列そのものの大きさは必要な色情報の数×1となります。




3.プリミティブ描画のサンプルコード

ここではサンプルコード内のプリミティブ描画に関する部分について説明します。ここでは1.2.で使用した、三角ポリゴンの描画を例にとって説明します。
まず、プリミティブ用の変数を以下のように準備します。

/**
  * 整数配列用コンテナ
  * typedef struct tagIntArray {
  *       hi_sint32 num;
  *       hi_sint32* array;
  * } IntArray;
  *
  * 三角ポリゴン用構造体
  * typedef struct tag_Triangle{
  *       IntArray coord;
  *       IntArray normal;
  *       IntArray color;
  * }Triangle;
  */


/* 頂点情報配列 */
static const hi_sint32 _coord_array[] = {
0, 500, 0, -256, 0, 0, 256, 0, 0, /* 1 */
0, -500, 0, -256, 0, 0, 256, 0, 0, /* 2 */
};

/* 法線情報配列 */
static const hi_sint32 _normal_array[] = {
0, 0, -4096, /* 1 */
0, 0, -4096, /* 2 */
};

/* 色情報配列 */
static const hi_sint32 _color_array[] = {
0 << 16 | 255 << 8 | 0, /* 1 */
255 << 16 | 0 << 8 | 128, /* 2 */
};

/* 各情報配列用コンテナ */
const IntArray triangle_coord = { sizeof( _coord_array ) / sizeof( _coord_array[0] ), _coord_array };
const IntArray triangle_normal = { sizeof( _normal_array ) / sizeof( _normal_array[0] ), _normal_array };
const IntArray triangle_color = { sizeof( _color_array ) / sizeof( _color_array[0] ), _color_array };


/**
 * プリミティブ初期化
 */
triangle.coord = triangle_coord;
triangle.normal = triangle_normal;
triangle.color = triangle_color;

描画処理のため Render オブジェクトへの設定を行います。

/* 視点変換行列設定 */
OEMC_Micro3D_Atrans3i_multiply2( &vtrans, &view_trans, &vtrans );
OEMC_Micro3D_Render_setViewTrans( &render, &vtrans );

/* 三角ポリゴン */
OEMC_Micro3D_Render_drawPrimitive( &render,
M3DP_TRIANGLES | M3DPD_TEXCOORD_NONE |
M3DPD_NORMAL_PER_FACE | M3DPD_COLOR_PER_FACE |
M3D_BLEND_NORM | M3D_LIGHTING | ( 2 << 16 ),
&triangle.coord, &triangle.normal, NULL, &triangle.color );

/* VRAMへ転送 */
OEMC_Micro3D_Render_flush( &render );

他のプリミティブも同様に設定します。

ライン

/**
  * ライン用構造体
  * typedef struct tag_Line{
  *      IntArray coord;
  *      IntArray color;
  * }Line;
  */


/* 頂点情報配列 */
static const hi_sint32 _coord_array[] = {
640, 1024, 0, 640, -1024, 0,
};

/* 色情報配列 */
static const hi_sint32 _color_array[] = {
255 << 16 | 0 << 8 | 0,
};

/* 各情報配列用コンテナ */
const IntArray line_coord = { sizeof( _coord_array ) / sizeof( _coord_array[0] ), _coord_array };
const IntArray line_color = { sizeof( _color_array ) / sizeof( _color_array[0] ), _color_array };


/**
  * プリミティブ初期化
  */
line.coord = line_coord;
line.color = line_color;

/**
  * Render への設定
  */
/* 視点変換行列設定 */
OEMC_Micro3D_Atrans3i_multiply2( &vtrans, &view_trans, &vtrans );
OEMC_Micro3D_Render_setViewTrans( &render, &vtrans );

/* ライン */
OEMC_Micro3D_Render_drawPrimitive( &render,
M3DP_LINES | M3DPD_NORMAL_NONE | M3DPD_TEXCOORD_NONE |
M3DPD_COLOR_PER_FACE | M3D_BLEND_NORM | ( 1 << 16 ),
&line.coord, NULL, NULL, &line.color );

/* VRAMへ転送 */
OEMC_Micro3D_Render_flush( &render );

ポイントスプライト

/**
  * バイトデータ用構造体
  * typedef struct tagByteData
  * {
  *       const hi_byte* addr;
  *       hi_uint32 size;
  * } ByteData;
  *
  * ポイントスプライト用構造体
  * typedef struct tag_Sprite{
  *       IntArray coord;
  *       IntArray texcoord;
  *       Texture tex;
  * }Sprite;
  */

/* 頂点情報配列 */
static const hi_sint32 _coord_array[] = {
-1024, 512, 0,
};

/* テクスチャ位置情報配列 */
static const hi_sint32 _texcoord_array[] = {
1024, 1024, 0, 0, 0, 255, 255, M3DPSF_LOCAL_SIZE | M3DPSF_PERSPECTIVE,
};

/* ビットマップデータ */
static const hi_byte _sprite_bmp[] = {
0x42, 0x4d, 0x36, 0x4, 0x1, 0x0, 0x0, 0x0,
・・・(中略)・・・
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};

/* 各情報配列用コンテナ */
const ByteData sprite_bmp = { _sprite_bmp, sizeof( _sprite_bmp ) } ;
const IntArray sprite_coord = { sizeof( _coord_array ) / sizeof( _coord_array[0] ), _coord_array };
const IntArray sprite_texcoord = { sizeof( _texcoord_array ) / sizeof( _texcoord_array[0] ), _texcoord_array };


/**
 * プリミティブ初期化
 */
sprite.coord = sprite_coord;
sprite.color = sprite_color;
sprite.texcoord = sprite_texcoord;

/**
 * Render への設定
 */
/* Texture を設定 */
OEMC_Micro3D_Render_setTexture( &render, &sprite.tex );

/* 視点変換行列設定 */
OEMC_Micro3D_Atrans3i_multiply2( &vtrans, &view_trans, &vtrans );
OEMC_Micro3D_Render_setViewTrans( &render, &vtrans );

/* ポイントスプライト */
OEMC_Micro3D_Render_drawPrimitive( &render,
M3DP_POINT_SPRITES | M3DPD_NORMAL_NONE |
M3DPD_COLOR_NONE | M3DPD_TEXCOORD_AND_PS_PARAMS_PER_FACE |
M3D_BLEND_NORM | ( 1 << 16 ),
&sprite.coord, NULL, &sprite.texcoord, NULL );

/* VRAMへ転送 */
OEMC_Micro3D_Render_flush( &render );

四角ポリゴン( * テクスチャデータはポイントスプライトと共有しています。)

/**
  * 四角ポリゴン用構造体
  * typedef struct tag_Quad{
  *       IntArray coord;
  *       IntArray color;
  *       IntArray texcoord;
  * }Quad;
  */

/* 頂点情報配列 */
static const hi_sint32 _coord_array[] = {
-512, 0, 0, -1536, 0, 0, -1536, -1024, 0, -512, -1024, 0,
};

/* 法線情報配列 */
static const hi_sint32 _normal_array[] = {
0, 0, -4096,
};

/* テクスチャ位置情報配列 */
static const hi_sint32 _texcoord_array[] = {
255, 255, 0, 255, 0, 0, 255, 0,
};

/* 各情報配列用コンテナ */
const IntArray quad_coord = { sizeof( _coord_array ) / sizeof( _coord_array[0] ), _coord_array };
const IntArray quad_normal = { sizeof( _normal_array ) / sizeof( _normal_array[0] ), _normal_array };
const IntArray quad_texcoord = { sizeof( _texcoord_array ) / sizeof( _texcoord_array[0] ), _texcoord_array };


/**
 * プリミティブ初期化
 */
quad.coord = quad_coord;
quad.color = quad_color;
quad.texcoord = quad_texcoord;

/**
  * Render への設定
  */
/* 視点変換行列設定 */
OEMC_Micro3D_Atrans3i_multiply2( &vtrans, &view_trans, &vtrans );
OEMC_Micro3D_Render_setViewTrans( &render, &vtrans );

/* 四角ポリゴン(テクスチャポリゴン) */
OEMC_Micro3D_Render_drawPrimitive( &render,
M3DP_QUADS | M3DPD_TEXCOORD | M3DPD_NORMAL_PER_FACE |
M3DPD_COLOR_NONE | M3D_BLEND_NORM | M3D_LIGHTING | ( 1 << 16 ),
&quad.coord, &quad.normal, &quad.texcoord, NULL );

/* VRAMへ転送 */
OEMC_Micro3D_Render_flush( &render );


このページの先頭へ戻る