頂点バッファの作成*1

*1 頂点インデックスバッファに関してもここで記述します。

頂点バッファを作成する手順は以下の様になります。

  1. 頂点のフォーマットを決定する。
  2. 前項で決めた頂点フォーマットに対しCreateVertexBufferを使い、必要な頂点数の分だけ頂点バッファの為にメモリを確保する。
  3. 確保したバッファにデータを送り込む。

また、頂点インデックスバッファの作成も似た様な手順になります。

  1. 2バイト整数を使用するか4バイト整数を使用するかを決める。*2
  2. CreateIndexBufferを使い、必要な分だけ頂点インデックスバッファの為にメモリを確保する。
  3. 確保したバッファにデータを送り込む。

*2 GPUによっては最大65535(もしくはそれ以下)しか利用できない場合があります。その場合は4バイト整数を利用しようとしても意味がないばかりか、表示がおかしくなる場合があります。その場合には2バイト整数を使用する事になります。GPUがどれだけ確保できるかはGetDeviceCapsでMaxVertexIndexの値を調べると良いでしょう。

実際のコード

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
/* 頂点データのフォーマット */
struct d3dvtx_s {
    D3DXVECTOR3    pnt;    // 位置
    D3DCOLOR    clr;    // 色
    D3DXVECTOR2    tx1;    // テクスチャ
};
/* 上の頂点フォーマットをフラグで表現する */
const int FVFVTX1_X = (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
 
/* 動的に確保する配列 */
d3dvtx_s* VtxSet;    // 頂点データ
unsigned short* VtxIdxSet;    // 頂点インデックスデータ
 
LPDIRECT3DVERTEXBUFFER9 lpVtxBuf;    // 頂点バッファ
LPDIRECT3DINDEXBUFFER9 lpIdxBuf;    // 頂点インデックスバッファ
 
/***** ここから実際のコード *****/
    /* ここでlpD3DdevはLPDIRECT3DDEVICE9型で定義された有効なDirect3Dデバイスとする。 */
 
    // 必要な数だけ頂点用の配列を確保する
    VtxSet    = new d3dvtx_s[9];
 
    // 頂点のセット
    SetVertex(0, 0.0f, 0.0f, 0.0f, 0xFF00, 0.0f, 0.0f);
    SetVertex(1, 1.0f, 0.0f, 0.0f, 0xFF00, 0.0f, 0.0f);
    SetVertex(2, 2.0f, 0.0f, 0.0f, 0xFF00, 0.0f, 0.0f);
    SetVertex(3, 0.0f, 1.0f, 0.0f, 0xFF00, 0.0f, 0.0f);
    SetVertex(4, 1.0f, 1.0f, 0.0f, 0xFF00, 0.0f, 0.0f);
    SetVertex(5, 2.0f, 1.0f, 0.0f, 0xFF00, 0.0f, 0.0f);
    SetVertex(6, 0.0f, 2.0f, 0.0f, 0xFF00, 0.0f, 0.0f);
    SetVertex(7, 1.0f, 2.0f, 0.0f, 0xFF00, 0.0f, 0.0f);
    SetVertex(8, 2.0f, 2.0f, 0.0f, 0xFF00, 0.0f, 0.0f);
 
    // 頂点バッファに確保するサイズの計算
    size_t wsz = 9 * sizeof(d3dvtx_s);
 
    // 頂点バッファの確保
    lpD3Ddev->CreateVertexBuffer(wsz, 0, FVFVTX1_X, D3DPOOL_MANAGED, &lpVtxBuf, NULL);
 
    // 確保する頂点バッファを宣言
    d3dvtx_s*    vbuf;
 
    // ロック
    lpVtxBuf->Lock(0, 0, reinterpret_cast<void**>(&vbuf), D3DLOCK_NOSYSLOCK);
 
    // データの転送
    memcpy(vbuf, VtxSet, wsz);
 
    // 解放
    lpVtxBuf->Unlock();
 
 
    // 頂点インデックスの確保(ここでは頂点1, 3, 7を使って三角形を描画しようとする。)
    VtxIdxSet = new unsigned short[3];
    VtxIdxSet[0] = 1;
    VtxIdxSet[1] = 3;
    VtxIdxSet[2] = 7;
 
    // 頂点インデックスバッファを確保するサイズ
    size_t isz    = 3 * sizeof(unsigned short);
 
    // 頂点インデックスバッファの確保(2バイト整数のバッファしか対応していないGPUもある為、2バイト整数のバッファとして定義)
    lpD3Ddev->CreateIndexBuffer(isz, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &lpIdxBuf, NULL);
 
    // 確保する頂点インデックスバッファを宣言
    unsigned short*    ibuf;
 
    // ロック
    lpIdxBuf->Lock(0, 0, reinterpret_cast<void**>(&ibuf), D3DLOCK_NOSYSLOCK);
 
    // 転送
    memcpy(ibuf, VtxIdxSet, isz);
 
    // 解放
    lpIdxBuf->Unlock();
 
    // デバイスにインデックスをセット
    lpD3Ddev->SetIndices(lpIdxBuf);

なお、頂点セット用の関数SetVertexは以下の様に定義されている物とします。
あとここでは範囲チェックを省略していますが、実際にはidがVtxSetの範囲内におさまっているかをチェックしてください。

  1
  2
  3
  4
  5
  6
  7
  8
void SetVertex(int id, float x, float y, float z, D3DCOLOR c, float u, float v) {
    (VtxSet + id)->pnt.x    = x;
    (VtxSet + id)->pnt.y    = y;
    (VtxSet + id)->pnt.z    = z;
    (VtxSet + id)->clr    = c;
    (VtxSet + id)->tx1.x    = u;
    (VtxSet + id)->tx1.y    = v;
}

なお、頂点データの表示に関してはDrawIndexedPrimitiveについてを参考にしてください。


ページ情報
  • カテゴリ : DirectX
  • 作成日 : 2006-08-05 (土) 00:04:59
  • 作成者 : rakuppe?
  • 最終編集日 : 2006-08-15 (火) 03:20:18
  • 最終編集者 : rakuppe?
[ トップ ]   [ 編集 | 凍結 | 差分 | バックアップ | 添付 | 複製 | 名前変更 | リロード ]   [ 新規 | 子ページ作成 | 一覧 | 単語検索 | 最終更新 | ヘルプ ]