2015年12月

TONOMAGEDDON フリー配信開始!

メリークリスマス!
銀のおたまです。

突然ではございますが、なんと本日!
TONOMAGEDDONをフリー公開いたしました!!


コミケ88から4ヶ月ちょっと、ようやく公開まで漕ぎ着けることができました・・・

よりにもよってクリスマスに。

この企画は4月の頭にスタートしたので、そこからは8ヶ月!
いやはや時間が経つのは早いものでございます。


ダウンロードはウマモサクのサイト内、トノマゲドン→DOWNLOADをクリック!
内容はzipファイルとなっております。


また、このフリー公開に当たり、ニコニコ自作ゲームフェス2016への登録をしました!
以下がPVになります!!






それでは、TONOMAGEDDONをどうぞよろしく!!

ゲーム製作日誌 プログラム編 No.10-4 「GPU専用の頂点置き場VRAM」


 前々回は三角形の表現の方法、そして前回はそれをどのようにGPUに解釈させるかという方法について考えてきました。今回は、三角形の頂点データをGPUに送るためのGPU専用の領域を確保したいと思います。


1,頂点データはいつ送るか?

 実際に三角形を描画するために、前々回に用意した頂点配列をGPUに伝える必要があります。GPUには専用のビデオメモリが存在し、通常そこに頂点データやテクスチャを配置しておきます。

 C#で書いたプログラムを実行するのはCPUですが、三角形を描画するのはGPUという全く別の装置です。一般的にCPU・GPU間のデータのやりとりの速度は、それぞれが単独で動くよりも速くはないです。そのため、書きたいと思った時に毎回、C#のプログラムから描画させたい三角形を送信していると大きなタイムロスになってしまいます。実際、ゲームは1秒間に60回のペースで画面に描画する必要が有るため頻繁な送信はタイムロスになります。

 そこで、三角形の描画が必要だとわかり三角系の形が確定した段階でGPUの専用メモリにその三角形の頂点データを送っておきます。こうしておけば、C#のプログラムからはGPUに対して専用メモリにある三角形を描画するよう指令を出すだけで、遅い転送時間をかけることもなく効率的に描画が行えるようになります。しかもこの三角形の頂点データは常に置きっぱなしになるため、次に三角形を描画したい時には使い回すこともできるわけです。つまり次からは転送しなくてもいいわけです。

 もちろん描画したい三角形の形が変わってしまった場合には、頂点データの使い回しが効かないので頂点データをVRAMに転送し直す必要があります。

 同じ理屈で言うと、人間の体のように瞬間瞬間で形が変わっていくようなものだったら、描画する前に毎回三角形の頂点を送り直さなければいけないことになります。しかし、そういうような一部は変形しないような変形は変形の仕方を転送することで三角形を送り直す必要がなくなるのですがそれはまた今度扱います。


2,頂点バッファの確保 

 効率よく描画をするためには、GPUのメモリ(VRAM)に三角形の頂点データを予め置いておきたいのです。その置き場所を表すものが「頂点バッファ(VertexBuffer)」です。頂点バッファは、使いたいサイズや目的を指定して作成します。

10-4-1
  • 2行目には、使いたいサイズ(バイト数)を書く

    前回作成した頂点構造体PositionColorは、1つあたり28バイトを要していました。その点を3つつなげて三角形を表現するので28×3 = 84バイト必要になります。
    このように毎回計算するのは大変なので、頂点配列の要素数vertex.Lengthと構造体に要するバイトサイズをMarshal.SizeOf()を利用して求めたものを掛け算して、全体的に必要なバイトサイズを求めています。


  • 3行目には、頂点バッファに読み書きするかを書く

    頂点バッファには、頂点バッファに書かれた情報を読み取るReadと、頂点バッファに情報を書き込むWriteができます。今回は描画したい三角形の頂点データを予め送っておくだけでよく、その三角形を改めて読み返す必要もないためUsage.WriteOnly(書き込みのみ)を指定します。


  • 4行目には、頂点の各要素の使用目的を|(OR演算)でつなげて並べて書く

    例えば、前回作成した頂点構造体PositionColorは、座標(Position)と色(Color)を要素として持っていたので、頂点バッファ作成時にはVertexFormat.Position | VertexFormat.Colorと指定してあげます。
    他にも法線(VertexFormat.Normal)やテクスチャ座標(VertexFormat.Texture0~8)があります。


  • 5行目には、転送する頂点の保管方法を書く

    transfer

    保管方法は、Direct3D9で発生してしまうロストデバイスという現象に大きく関係しています。
    ロストデバイスは、「Ctrl+Alt+Delete」を押した時やディスプレイを切り替えた時に、VRAMに送ったデータが消えてしまう現象です。ようは今から送ろうとしている頂点もその際に消えてしまうということです。
    Pool.Defaultを指定するとCPUからVRAMに頂点を転送したっきり、ロストデバイスが起きてしまっても送った頂点を元に戻そうという機能が働きません。
    default

    Pool.Managedを指定するとCPUからVRAMに頂点を転送した後も、CPUは送ったデータを持ち続けます。それを使って、ロストデバイスが発生してVRAMからデータが消えてしまった時も再転送をして対処してくれます。通常はこちらを使っておいたほうが無難だと思います。
    managed


以上を踏まえたコードが以下です。
//頂点バッファ
VertexBuffer vertexBuffer = new VertexBuffer(D3Device,
vertex.Length * Marshal.SizeOf(typeof(VertexType)),
Usage.WriteOnly,
VertexFormat.Position,
Pool.Managed);
 
3,まとめ

 CPU側で作成した頂点をGPUに伝えるためには、まずGPUの専用メモリであるVRAMに頂点データを転送する必要があります。しかし、その転送にかかるコストは大きいためできるだけ一回転送した頂点データを三角形の形が変わらないかぎり使いまわすことが必要です。
 そこでVRAM上で自由に使える場所である頂点バッファを確保して、そこに頂点データを転送することにしました。頂点データ作成時で特に大切だった引数はPoolで、Managedに設定するとロストデバイスが発生しても転送しなおしを考慮しなくて良くなるという設定でした。


 今回で頂点データの置き場所(頂点バッファ)が確保できたので、次回は実際にそこに頂点データを移動する方法を扱います。

 
twitterはこちら
ニコ生放送します
ギャラリー
  • ウマモサク
  • ウマモサク
  • ウマモサク
  • 3/17 制作記録
  • 3/17 制作記録
  • C91告知
  • C91告知
  • C91告知
  • C91告知
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

  • ライブドアブログ