遊戲開發基礎(三)

來源:互聯網
上載者:User

 

第三章
頂點緩衝是一個包含頂點資料的連續記憶體空間
索引緩衝是一個包含索引資料的連續的記憶體空間
之所以用頂點緩衝和索引緩衝而非數組來儲存資料,是因為頂點緩衝和索引緩衝可以被放置在顯存中
頂點緩衝 IDirect3DVertexBuffer9表示,索引緩衝用介面IDirectIndexBuffer9表示
建立頂點緩衝
HRESULT IDirect3DDevice9::CreateVertexBuffer(
     UINT Length,
     DWORD Usage,
     DWORD FVF,
     D3DPOOL Pool ,
     IDirect3DVertexBuffer9** ppVertexBuffer,
     HANDLE* pShareHandle
     ); 
建立索引緩衝
HRESULT IDirect3DDevice9::CreateIndexBuffer(
     UINT Length,
     DWORD Usage,
     D3DFORMAT Format,
     D3DPOOL Pool ,
     IDirect3DIndexBuffer9** ppIndexBuffer,
     HANDLE* pShareHandle
     );
*Length 為緩衝分配的位元組數
*Usage 指定關於如何使用緩衝的一些屬性。該值為0(表明無需附加屬性)
    # D3DUSAGE_DYNAMIC 將緩衝設為動態緩衝
    # D3DUSAGE_POINTS  儲存點圖元
    # D3DUSAGE_SOFTWAREPROCESSING  指定軟體頂點運算方式
    # D3DUSAGE_WRITEONLY  應用程式對緩衝的操作模式為“唯寫”
*FVF 儲存在頂點緩衝中頂點的靈活頂點格式
*Pool 容納緩衝的記憶體池
*ppVertexBuffer 用於接收所建立的頂點緩衝的指標
*pSharedHandle 不使用,為0
*Format 指定索引的大小,設為D3DFMT_INDEX16表示16為索引,設為D3DFMT_INDEX32表示32為索引
*ppIndexBuffer 用於接收所建立的索引緩衝的指標
靜態緩衝一般放置在顯存中
動態緩衝一般放置在AGP中
對顯存和AGP儲存區進行讀操作非常慢

例:建立一個可容納8個Vertex類型的頂點的靜態頂點緩衝

IDirect3DVertexBuffer9* vb;
device -> CreateVertexBuffer(8*sizeof(Vertex),0,D3DFVF_XYZ,D3DPOOL_MANAGED,&vb,0);
建立一個動態緩衝的例子,所建立的動態緩衝可容納36個16為索引
IDirect3DIndexBuffer9* ib;
device -> CreateIndexBuffer(36*sizeof(WORD),D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&ib,0);
訪問緩衝內容
藉助方法Lock來擷取緩衝內容指標。
如果常見頂點緩衝或索引緩衝時,使用了D3DUSAGE_WRITEONLY標記,便無法對該緩衝進行讀操作
HRESULT IDirect3DVertexBuffer9::Lock(UINT OffsetToLock,
     UINT SizeToLock,
     BYTE** ppbData,//指定被鎖定儲存區的起始位置的指標
     DWORD Flags//標記鎖存方式
     );
HRESULT IDirect3DIndexBuffer9::Lock(UINT OffsetToLock,
     UINT SizeToLock,
     BYTE** ppbData,
     DWORD Flags
     );

*Flags 標記鎖存方式,可以是0
#D3DLOCK_DISCARD 僅用動態緩衝。它指示硬體將緩衝內容丟棄,並返回一個指向重新分配的緩衝的指標的指標。該標記十分有用,因為這

允許在我們訪問新分配的記憶體時,硬體能夠繼續使用被丟棄的緩衝中的資料進行繪製,這樣硬體的繪製就不會中止
#D3DLOCK_NOOVERWTITE 僅用動態緩衝,該標記資料只能以追加方式寫入緩衝,可以保證在緩衝中增加資料時,硬體仍可持續進行繪製
#D3DLOCK_READONLY 表示所鎖定的緩衝只可讀而不可寫,利用這一點可以作一些內部最佳化

例: Lock使用方法
Vertex* vertices;
_vb->Lock(0,0,(void**)&vertices,0);
vertices[0] = Vertex(-1.0f,0.0f,2.0f);
vertices[1] = Vertex(0.0f,1.0f,2.0f);
vertices[2] = Vertex(1.0f,0.0f,2.0f);
_vb->Unlock();

擷取頂點緩衝和索引緩衝資訊
D3DVERTEXBUFFER_DESC vbDescription;
vertexBuffer->GetDesc(&vbDescription);

D3DINDEXBUFFER_DESC ibDescription;
indexBuffer->GetDesc(&ibDescription);

D3DVERTEXBUFFER_DESC 和 D3DINDEXBUFFER_DESC 結構:
typedef struct _D3DVERTEXBUFFER_DESC{
 D3DFORMAT Format;
 D3DRESOURCETYPE Type;
 DWORD Usage;
 D3DPOOL Pool ;
 UINT Size;
 DWORD FVF;
}D3DVERTEXBUFFER_DESC

typedef struct _D3DINDEXBUFFER_DESC{
 D3DFORMAT Format;
 D3DRESOURCETYPE Type;
 DWORD Usage;
 D3DPOOL Pool ;
 UINT Size;
 DWORD FVF;
}D3DINDEXBUFFER_DESC

 

Direct3D封裝了多種繪製狀態(rendering state)
HRESULT IDirect3DDevice9::SetRenderState(
     D3DRENDERSTATETYPE State,
     DWORD Value 
     );
例:
_device->SetRenderState(D3DRS_FILLMODE,D3DFILL_WRITEFRAME);

一旦我們建立了頂點緩衝以及索引緩衝,我們基本上已經可以準備對其所儲存的內容進行繪製了,但是繪製之前,還有3個步驟需要完成:
(1)指定資料流輸入源。將頂點緩衝和資料流進行連結,實質是將幾何體的資訊傳輸到繪製流水線中。

//設定頂點資料流的輸入源
HRESULT IDirect3DDevice9::SetStreamSource(
     UINT StreamNumber,//標識與頂點緩衝建立連結的資料流。
     IDirect3DVertexBuffer9* pStreamData,//與給定資料流建立連結的頂點緩衝的指標
     UINT offsetInBytes,自資料流的起始點算起的一個位移量,單位為位元組
     UINT Stride//將要連結到資料流的頂點緩衝中每個元素的大小,單位為位元組
     );
例:假定vb是一個儲存為Vertex類型的頂點資料的頂點緩衝
_device->SetStreamSource(0,vb,0,sizeof(Vertex));
(2)設定頂點格式:指定後續繪製調用中使用的頂點格式
_device->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEXI);
(3)設定索引緩衝。
_device->SetIndices(_ib);

使用DrawPrimitive或DrawIndexdPrimitive方法將待繪幾何體資訊通過繪製流水線傳輸,這兩個方法從頂點資料流中擷取頂點資訊,並從

當前設定的索引緩衝中提取索引資訊

//該方法可用於繪製未使用索引資訊的圖元
HRESULT IDirect3DDevice9::DrawPrimitve(
     D3DPRIMITIVETYPE PrimitiveType,//所要繪製的圖元類型,#D3DPT_TRIANGLELIST三角形
     UINT StartVertex,//頂點資料流中標識頂點資料讀取起點的元素的索引
     UINT PrimitiveCount//所要繪製的圖元數量
     );
HRESULT IDirect3DDevice9::DrawIndexedPrimitve(
     D3DPRIMITIVETYPE Type,//繪製圖元類型
     INT BaseVertexIndex,//索引增加的一個基數
     UINT MinIndex,//允許引用的最小索引值
     UINT NumVertices,//本次調用中將引用的頂點總數
     UINT StartIndex,//頂點緩衝中標識索引的讀取起始點的元素的索引
     UINT PrimitiveCount //所要繪製的圖元總數
     );
所有繪製方法都必須在IDirect3DDevice9::BeginScene和IDirect3DDevice9::EndScene構成的方法之間進行調用
例:
_device->BeginScene();
_device->DrawPrimitive(...);
_device->EndScene();

D3DX庫提供了一些用於產生簡單3D幾何體的網格資料方法
D3DX庫提供如下6個網格建立函數
*D3DXCreateBox
*D3DXCreateSphere
*D3DXCreateCylinder
*D3DXCreateTeapot
*D3DXCreatePolygon
*D3DXCreateTorus
這6個方法都非常相似,並且都使用D3DX網格資料結構ID3DXMesh和ID3DXBuffer介面。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.