DirectX SDK 2006學習筆記3——索引緩衝

Copyright © MikeFeng  QQ: 76848502 

3.索引緩衝
  索引緩衝Index Buffer是由用戶定義的,用來告訴D3D渲染頂點順序的WORD或者DWORD數組。
索引緩衝離不開頂點緩衝,但是頂點緩衝卻不一定需要索引緩衝。創建索引緩衝的過程和創建頂點緩衝類似,首先是聲明,然後在OnCreateDevice中初始化和創建,在OnFrameRender中渲染,在OnDestroyDevice中銷燬。相關代碼如下:
聲明:
LPDIRECT3DINDEXBUFFER9 g_pIB = NULL;     // Buffer to hold indeces
OnCreateDevice:
HRESULT hr;
V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );
V_RETURN( g_SettingsDlg.OnCreateDevice( pd3dDevice ) );
 
// Initialize the font
V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
                OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
                L"Arial", &g_pFont ) );
 
// Initialize vertices for rendering a triangle
CUSTOMVERTEX vertices[] =
{
        {   0.0f, 0.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
        {       (float)pBackBufferSurfaceDesc->Width, 0.0f, 0.5f, 1.0f, 0xff00ff00, },
        {   (float)pBackBufferSurfaceDesc->Width, (float)pBackBufferSurfaceDesc->Height, 0.5f, 1.0f, 0xffff00ff, },
        {   0.0f, (float)pBackBufferSurfaceDesc->Height, 0.5f, 1.0f, 0xff0000ff, },
};
 
// Create the vertex buffer
V_RETURN( pd3dDevice->CreateVertexBuffer( sizeof(vertices),
                0, D3DFVF_CUSTOMVERTEX,
                D3DPOOL_MANAGED, &g_pVB, NULL ) );
 
VOID* pVertices;
V_RETURN( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) );
memcpy( pVertices, vertices, sizeof(vertices) );
g_pVB->Unlock();
 
// Initialize index buffer for rendering
WORDwIndeces[] = {0,1,2,0,2,3};
 
// Create the index buffer
V_RETURN( pd3dDevice->CreateIndexBuffer( sizeof(wIndeces),
        0, D3DFMT_INDEX16,
        D3DPOOL_MANAGED, &g_pIB, NULL) );
VOID* pIndeces;
V_RETURN( g_pIB->Lock( 0, sizeof(wIndeces), &pIndeces, 0) );
memcpy( pIndeces, wIndeces, sizeof(wIndeces) );
g_pIB->Unlock();
 
returnS_OK;
OnRender中BeginScene和EndScene之間
pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
pd3dDevice->SetIndices( g_pIB );
//pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2 );
OnDestroyDevice
SAFE_RELEASE( g_pVB );
SAFE_RELEASE( g_pIB );
下面是這段代碼的效果圖:
 挺PP的吧?
這段代碼和頂點緩衝最重要的不同在於DrawIndexedPrimitive函數。這個函數的使用方法請看下面的例子(整理自SDK文檔Rendering from Vertex and Index Buffers):
 
Scenario 1:畫兩個沒有索引緩衝的三角形(爲了方便現在僅列出三維座標的x,y值,下同)
 
  左圖上的正方形由兩個三角形組成,從右圖可以看出頂點緩衝程序採用了TRIANGLELIST的圖元方式分別畫出了兩個三角形,代碼如下:
DrawPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                  0,                  // StartVertex
                  2 );                // PrimitiveCount
Scenario 2:用索引緩衝畫兩個三角形
  右邊圖的是頂點緩衝,和場景1相比少了兩個重複定義的頂點,左邊的數組就是索引緩衝,方框中的數字就是右邊頂點緩衝的編號,其中頂點0, 1, 2構成一個獨立的三角形,頂點3, 0, 2獨立構成另一個獨立的三角形,代碼如下:
DrawIndexPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    0,                  // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    0,                  // StartIndex
                    2 );                // PrimitiveCount
  函數由DrawPrimitive換成了DrawIndexPrimitive,圖元類型仍然爲TRIANGLELIST。圖元數仍然爲2。
Scenario 3:使用索引渲染一個三角形
  這次需求變更,但是仍然想用上面的索引緩衝和頂點緩衝怎麼辦呢?具體來說,我們只想要畫由頂點0, 2, 3構成的三角形。研究DrawIndexPrimitive之後發現只要這樣調用就可以了:
DrawIndexPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    0,                  // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    3,                  // StartIndex
                    1 );                // PrimitiveCount
  StartIndex爲3,就是說從第三個元素開始使用索引緩衝,上圖中第三個元素對應的正好是頂點3。圖元數爲1,因爲我們只需要畫一個三角形。頂點個數仍然爲4。
Scenario 4:使用索引緩衝的Offset渲染一個三角形
    
  假如一個頂點緩衝特別大,頂點的標號已經達到50, 51, 52, 53這樣的數字,我們可以通過填寫Offset的方法來調用DrawIndexPrimitive。上圖的情況只要將Offset這個參數設爲50,就可以達到不變更上幾例中的索引緩衝內容的目的。這種情況下,中間一幅圖描述的索引信息就等同於左邊的索引信息,而下面函數渲染出的圖形就是由頂點53, 50, 52構成的三角形。
DrawIndexPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    50,                 // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    3,                  // StartIndex
                    1 );                // PrimitiveCount
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章