CMeshを変更しよう

自作クラスでOpenGLを使って3Dの描画を行っています。CMeshクラスでメッシュの管理を行っているのですが、ちょっと使いにくくて困ってました。
こんな感じのクラスです。

class CMesh {
  /* 略 */
  vector<CMeshSubset*> m_subsets; // マテリアルごとに分けたメッシュ
  vector<SMaterial*> m_Materials; // メッシュで使用するマテリアル
};

class CMeshSbuset {
  /* 略 */
  vector<SVertex> verts; // 頂点
  vector<SPolygon> faces; // 面<
}

マテリアルごとにメッシュを分けているのは、DirectXがそうしてるっぽいからで、構造体の先頭がSから始まるのは、Irrlichtのソースを見てて真似をしたくなったからです。マテリアルごとにメッシュが分かれていると確かに描画効率は上がると思うのですが、頂点までアクセスするのが二度手間になって困っていました。

for ( int i=0; i<pMesh->GetSubsetsNum(); i++ )
{
  CMeshSubset *pSub = pMesh->GetSubsets(i);
  for ( int j=0; j<pSub->verts.size(); j++ )
    /* これでようやく頂点(pSub->verts[j])にアクセスできるようになる */
}

「まあ、DirectXもそうみたいだから仕方ないや」と、思ってガマンしてやってきたのですが、今日、調べ物をしているときにソースを見てそうじゃないことに気が付きました。確かにDrawSubsetというメソッドはありますが、頂点は全て一つのVertexBufferに保存されているのですね。てっきり、pMesh->GetSubsets()->GetVB() のようなアクセスが必要なのだと思っていました。ならば、僕もそのようなフォーマットにしないわけにはいきません。
ついでなので、SVertexも失くそうと思います。Irrlichtを真似してSVertexを使っていたわけですが、gl*Pointer()ではデータがぎっしり詰まっていないとインターリーブと同じで効果が薄いと言う記述をみつけたもので。……確かに、連続で入っていないとキャッシュのヒット率も落ちてしまいますよね。


そんなわけで、次のように変更したいと思います。

  • CMeshSubsetを廃止。頂点は一つの配列(vector)としてCMeshが直接持つ
  • SVertexを廃止。頂点を扱う構造体は作らず、それぞれCMeshが直接持つ。

10月3日は内定式で東京に行くのですが、その準備などは日曜にやればいいので、明日は一日フリーです。がんばるぞ!