スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

"縮退三角形"を使ってみた

【リンク】 ◆解説系TOP◆

現在 3Dモデルを作ってボーンを入れたりとか、
本来ならばプログラマーの仕事じゃない事をやっている訳ですが、

そればっかりやるのもアレなので、
今日は ちょっと縮退三角形を使ったプログラムを書いてみました。


で、「縮退三角形って何?」と感じると思うのですが、
それを説明するには、まずDirectXでの描画方法を確認する必要があります。


まず、DirectXでポリゴンを描画する場合
自分は9割方D3DPT_TRIANGLESTRIPというプリミティブタイプを用いてます。

これは、頂点をジグザグに定義したら、
その頂点を帯状に結んで出来る部分がポリゴンになるという方式です。


【参考画像】
Strip.jpg

で、ジグザグに定義していかないといけないので、
ポリゴンの頂点は一筆書きみたいになります。

これはどういうことかと言うと、
離れた場所にあるポリゴンは同時に描画できない
という事になります。

【参考画像】
ThreePolygon.jpg
普通に描画しようとしたら、3回に分けて描画しないといけません。

↓プログラムだとこんな感じ。
pD3Ddevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,BluePolygon,sizeof(TEST));
pD3Ddevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,RedPolygon,sizeof(TEST));
pD3Ddevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,GreenPolygon,sizeof(TEST));

※Blue、Red、GreenPolygonというのは、それぞれTEST型の構造体の配列(要素4)です。

しかし、実は上記のような離れたポリゴンでも
1度に描画出来る方法があるのです。

それを可能にするのが"縮退三角形"という訳です。


で、ここからは縮退三角形の説明。
頂点を3つ定義すると、普通は三角形が出来ますよね。

しかし、三角形にならない場合があります。
それは、3つの頂点が任意の直線状に並ぶ時です。

【参考画像】
縮退三角形

で、DirectXの方に嫌がらせ
「一直線上に並ぶ3点を描画するように指定するとどうなるか?」というと・・・


描画してくれなくなります。

そう、描画されない。
描画しようが無いのですから。


そして、
上記では3つの頂点が異なる位置にありましたが、
2つの頂点が全く同じ場所に重なる三角形縮退三角形と言います。


で、この描画されない部分でポリゴンを上手くつないでしまえば
見かけ上は離れた場所にあるポリゴンが、
1回で描画出来る様になります。


【参考画像】
縮退三角形2

で、縮退三角形の作り方ですが、これは簡単。
2つのポリゴンを合体させたい場合は、
前者の最後の頂点と、後者の最初の頂点を重複させるだけです。

上記の水色の三角形の場合は、
------------------------------------------------------------------------
ポリゴンA (左側)
左上の頂点
右上の頂点
左下の頂点


ポリゴンB (右側)

左上の頂点
右上の頂点
左下の頂点



合体ポリゴンAB
左上の頂点
右上の頂点
左下の頂点
左下の頂点
左上の頂点
左上の頂点
右上の頂点
左下の頂点

------------------------------------------------------------------------
このようにすればOKです。


プログラムだと、こうなります。 (定義と、描画の部分のみ抜粋)
TEST tP[8] = { {-8, 8,0,0,0,-1,0xffff0000},
{ 8, 8,0,0,0,-1,0xff00ff00},
{-8,-8,0,0,0,-1,0xff0000ff},
{-8,-8,0,0,0,-1,0xff0000ff},
{ 24,8,0,0,0,-1,0xffff0000},
{ 24,8,0,0,0,-1,0xffff0000},
{ 40, 8,0,0,0,-1,0xff00ff00},
{ 24, -8,0,0,0,-1,0xff0000ff},
};

pD3Ddevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,6,tP,sizeof(TEST));

※縮退三角形も三角形の数に含みます。
 その為、三角形の数は2ではなく6と指定しています。

で、「何で4つも増えるの?」と思う方は
下記の画像を見てもらえば分かると思います。
縮退三角形



それと、何で縮退三角形のプログラムを試してみたかと言うと、
何か処理速度が速くなるらしいんですよ。

(確かに三角形を何百回、何千回と表示する作業を繰り返すより、
一回でポンと全部表示した方が速そうな気がする)


どのくらい速くなるのかは分かりませんが、
とりあえず複雑な3Dモデルで試してみて、速くなるようなら

縮退三角形を使う描画方法に切り替えてみようかなー とか思ってます(`・ω・´)
スポンサーサイト

テーマ : ゲーム - ジャンル : ゲーム

コメント

No title

これは面白いですね。
これはポリゴンとポリゴンの距離を遠ざけたりするのはちょっとめんどくさいので、
そういう処理をする場合は個別でポリゴンを作った方がいいという事ですか?

No title

そうですね
もし別々の処理 (動かす、テクスチャを切り替える等)をしようと思う場合は、
個別にポリゴンを定義した方が良いかと思いますv-290

これが便利なのは、単一の3Dモデルをより短時間で表示する時などに なるかな、と。

あと、三角形の数を指定する部分を (今回2 → 6と変更した所)
変数にして、時間が経つごとに値をインクリメントしていけば
3Dモデルがポリゴン単位で徐々に出現するみたいな、面白い演出が出来ると思いますv-291

No title

速度を気にされるなら'DrawPrimitiveUP/DrawIndexPrimitiveUP'函数を使用されるより
'DrawPrimitive/DrawIndexPrimitive'を使われるほうが良いと思います。

DrawPrimitiveUP系函数は呼び出しのたびに内部で
1.描画処理のための頂点バッファ作成
2.バッファに頂点データをコピー
3.描画のためDrawPrimitive呼び出し
4.バッファーの解放
という処理を行っているため時間がかかります。
複数回呼び出すと重いのはこのためです。

ですので、データ読込時などに頂点バッファを自分で作成し、
DrawPrimitive函数で描画を行うほうが高速に処理できます。(もちろんデータ量によりますが)

あと、一番下の説明図は頂点の動かす位置を間違えてますよ。
左上・右上と順番に数えた場合
5番目の頂点は7番目の頂点に重ねるのではなく4番目の頂点に重なるべきです。
同じく6番目の頂点は7番目の頂点に重なるべきです。

No title

そうでしたか!v-399
描画処理についてよく把握し切れて無かったようです。
(特に何の考えもなしに DrawPrimitiveUP関数を使ってました)

先ほど、DrawPrimitive関数を使う描画方法
( CreateVertexBuffer関数
  Lock関数
  頂点の定義
  Unlock関数
  SetStreamSource関数
  SetFVF関数
  DrawPrimitive関数  )
を試したところ、 上手く描画できました。

ポリゴンを表示しただけなので、速度面はまだ実感できるほど変わりませんでしたが、
とりあえずこれからはDrawPrimitive関数を使おうと思います。v-290

あと、記事の画像の方は確かに間違っていました。
申し訳ないです。 
(取り急ぎ修正しました)

ご指摘ありがとうございますv-290
コメントの投稿
管理者にだけ表示を許可する



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。