[頂点処理高速化 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化はもうイイヤ。