
[頂点処理高速化 006]
Story
TriangleStrip化がんばってみたんだけどさ。うまく繋がらないし
ゴリゴリゴリゴリゴリケンですみたいな作り方したから、ちょっと
時間あけたらもぅソース読めないし、あーもー作りなおした方が
はやいかなー。あーでもなーもーめんどくせー。
って時に見つけたのがStrip化やってくれるらしき[NvTriStrip]
ちょっと調べてみたら使いやすそうだったので試してみた。
NvTriStripナニコレ
すげ大雑把に言うとTriangleListの頂点indexリストを放り込むと
TriangleStripになったリストが返って来るのだ。セールスポイントは
・複数に分割されたstripか1つにまとまったstripかを指定可能
・stripではなくて最適化されたTriangleListも生成可能
・APIとかOS非依存
・頂点キャッシュとかその辺もイイ感じに考えるよ♪
あたりらしい。通常strip化すると1つのオブジェクトが複数のstrip
に分割されてしまうので、stripを1つにまとめてくれると、既存の
コードを変更するコトなく導入できるので非常に使いやすい。
OS非依存とか言っときながらいきなりinclude windows.hとか書いて
あるのはどーかと思うが。WORDなんてシラネーヨって怒られたぞ、と。
linuxで使うには多少ゴリる必要があるが、基本的にはwindows.h切って
WORDを何かdefineしてfor分の中のint iって書いてあるの外に出す
とかすればいけるハズ。(ってかいけた。)
NvTriStrip使ってみる
使ってみる前に、頂点 法線 テクスチャ座標 それぞれが頂点indexを
共有できる感じで整列されている必要アリ。つまるところ
glDrawElementsでindex配列指定して どばーん! と描ける状態。
#include <NvTriStrip.h>
PrimitiveGroup* pPrim; //データ入れ物 NvTriStrip.hで定義
unsigned short num_prim; //返って来たデータ数が書き込まれる
GenerateStrip( 頂点index配列, 頂点index配列要素数,
&pPrim, &num_prim );
でおわり。
pPrim->numIndices にstrip化された頂点index配列要素数
pPrim->Indices にstrip化された頂点index配列
が入ってるので既存の頂点index配列とすり替えればOK。
delete[] pPrim; もお忘れなく。
あとは描画部分のGL_TRIANGLESをGL_TRIANGLE_STRIPに変更すれば
おわり。
NvTriStripオプション
・SetStitchStrips(const bool)
デフォルトではtrueになっていて、GenerateStripは1つに結合された
stripを返す。GenerateStrip前にSetStitchStrips(false)を指定
するコトにより結合されていない状態のstrip群を取得できる。
strip化をやってみたコトがある人なら分かるかもしれないが、strip
とstripを結合するのは結構やっかいで、かなりゴリる感じになって
しまうので不要な頂点がどうしても増えてしまう。ココでfalseを指定
するコトによってその無駄が省けるが、PrimitiveGroupが複数返って
くるので、その対処をしないといけない分要コード修正。
・SetCacheSize(const unsigned int)
データ最適化に関連するキャッシュサイズを指定する。デフォルトは16
で、コレはGeForce1&2の最適サイズらしい。GeForce3は24で、
それぞれCACHESIZE_GEFORCE1_2 CACHESIZE_GEFORCE3としてdefine
されている。(GeForce3までかょ。)
・SetMinStripSize(const unsigned int )
stripの最小サイズ(長さとも言うかも)を指定する。このサイズに満た
ないstripはかき集められて1つのTriangleListとして返って来る模様。
ちなみに3とか指定してみたらassertで死んだ。わーい^ー^
・SetListsOnly(const bool)
コレtrueしとくとstripじゃなくて、最適化されたlistが返ってくる。
デフォルトはfalse。
・その他
よーわからん。
NvTriStrip使ってみた
テストしたモデルとの相性が悪いのか全く速くならんかった。
ついでに20000ポリぐらいの球体つくって試してみたけど・・・
[no optimize]
triangle: 19800
work time : 27147 msec
total frames : 6592 frames
242.826 frame per second.
[NvTriStrip default]
triangle: 19800
[nvstrip] 59400 indices converted.
[nvstrip] num_prim: 1
[nvstrip] 29129 strip generated.
work time : 29188 msec
total frames : 6002 frames
205.632 frame per second.
[NvTriStrip stitch=off]
triangle: 19800
[nvstrip] 59400 indices converted.
[nvstrip] num_prim: 1728
[nvstrip] 25660 strip generated.
work time : 27066 msec
total frames : 5569 frames
205.756 frame per second.
すげ速度落ちた。ぬーん。
ふと思ったコト
隣接triangleでTextureCoordを共有していない場合
↑indexだけ見て無理やり繋げるとこーなるよね?
何でもかんでもstrip化すればイイってモンじゃないかも。
伝説のボツカット
NvTriStrip通してはみたものの、840面のTriangleListが、
長さ1のstrip840個に分割されてしまった時に勢いで描いたもの。
結局、モデルデータが完全独立な頂点とindexで構成されていたというオチ。
ゴゴゴゴゴゴゴ・・・
仮説を立ててみた。
繋がるも何も関連ねーんだ。スマン美紀男。
なんかもーstrip化はもうイイヤ。