2009年5月17日日曜日

IndexBuffer

 DrawIndexedPrimitive()しかないものだとばかり思っていたがDrawIndexedPrimitiveUP()も存在することに昨日気がついて、それから今までずっと実装してた。
 std::vector< Vertex >とstd::vector< WORD >にデータをつめこんだあと、DrawIndexedPrimitiveUPでレンダリングする。
 ビデオカードによってはIndexBufferが使えないのもあるようなので、DrawPrimitiveUPでもレンダリングできるよう互換性ももたせる。いまどきそんなPC使う人いんのかよと思わんでもないが。それを言ったら、いまどき頂点つみこみとかせんか。

 やることは簡単なんだけど、デバッグにいちいち表示して確認してたもんだから時間がかかってしょうがないわ。

以下アバウトな実装

/** 頂点情報 */
struct Vertex
{
  float x, y, z;
  D3DCOLOR color;
  float tu, tv;

  // 頂点FVF
  enum { FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1, };
};


/** 頂点バッファ */
std::vector< Vertex > m_vertex;
/** インデックスバッファ */
std::vector< WORD > m_index;



/** 三角ポリゴンの追加*/
virtual bool addPolygon(
  const Vertex& vertex1,
  const Vertex& vertex2,
  const Vertex& vertex3 )
{
  const WORD baseIndex = static_cast( m_vertex.size() );
  m_index.push_back( baseIndex + 0 );
  m_index.push_back( baseIndex + 1 );
  m_index.push_back( baseIndex + 2 );

  m_vertex.push_back( vertex1 );
  m_vertex.push_back( vertex2 );
  m_vertex.push_back( vertex3 );

  return true;
}


/** 描画 */
bool render( LPDIRECT3DDEVICE9 device )
{
  if ( m_index.size()/3 > 0 && device )
  {
    device->SetFVF( Vertex::FVF );
    device->DrawIndexedPrimitiveUP(
      D3DPT_TRIANGLELIST,
      0,
      static_cast( m_vertex.size() ),
      static_cast(m_index.size()/3),
      &m_index.at(0),
      D3DFMT_INDEX16,
      &m_buffer.at(0),
      sizeof(Vertex) );

    return true;
  }

  return false;
}

 注意点として、D3DFMT_INDEX16と指定している以上65535以上のインデックス番号はオーバーフローしておかしくなる。適当にエラー処理は必要。

0 件のコメント: