Bpx2DオブジェクトをDirect3Dで描画するためのコードをようやく書き始めた。結局コンピュートシェーダーは使わずにオーソドックスの頂点データを渡して描画する方法にした。座標変換はBox2D座標を頂点シェーダーで変換して表示する。といってもDirect2Dで描画するよりも変換は簡単だ。Direct3Dでは中心が(0.0,0.0)で画面幅・高さがそれぞれ1.0で画面座標が正規化されるので、それなりにスケーリングし、画面のアスペクト比をかけてやるだけで変換できてしまう。
#include "2dshader.hlsli"
VertexShaderOutput main(VertexShaderInput input)
{
VertexShaderOutput output;
// Box2Dでのボディーからシェイプの頂点を求める
// float32 x = (T.q.c * v.x - T.q.s * v.y) + T.p.x;
// float32 y = (T.q.s * v.x + T.q.c * v.y) + T.p.y;
float x = (body_rot.x * input.pos.x - body_rot.y * input.pos.y + body_pos.x) * screen_aspect.x * screen_scale.x + screen_offset.x;
float y = (body_rot.y * input.pos.x + body_rot.x * input.pos.y + body_pos.y) * screen_aspect.y * screen_scale.y + screen_offset.y;
float4 pos = float4(x,y,input.pos.z,1.0f);
//pos = mul(pos,transform);
output.pos = pos;//float4(input.pos,1.0f);
// Pass through the color without modification.
output.color = body_color;
return output;
}
とりあえず上記のようなシェーダーコードを書いてポリゴン・シェイプだけを表示してみたのが下の動画である。
四角形がうまく表示されていない。これはBox2Dポリゴンが右回りに頂点定義しているためである。Direct3Dではトライアングル・ストリップで描画しているので頂点の並び順を変換しないとうまく表示されない。つまりBox2Dで四角形ポリゴンの頂点定義を1,2,3,4とすると、Direct3Dで描画するためには1,2,4,3という並び順に変換しなかればならない。
四角形だけなら上記の並び順に変えるだけでいいが、ポリゴンは既定では8頂点まで定義できその頂点数も拡張可能なので、それぞれの頂点数に応じて並び替え情報を用意するのはいい方法ではない。こういう場合は頂点データをもとに三角形に分割し、そのデータを持たせたほうがよさそうである。つまりあらかじめBox2Dの頂点情報から三角形のリストをあらかじめ作っておけばよさそうである。そうするのであればインデックス描画に変換したほうが効率がよさそうである。
三角形分割の方法についてはWeb上にごろごろしているので、それをもとに作ってみようかなと思う。