我想要一個靈活的幾何實例代碼能夠處理具有多種材質的網格。對於一種材料的網格,一切都很好。我設法通過一次繪製調用渲染儘可能多的實例。DirectX9對具有多種材質的網格使用幾何實例
事情會因多種材料而變得更加複雜。我的網格來自.x文件。它有一個頂點緩衝區,一個索引緩衝區,但有幾個材質。要爲每個子集(材質)渲染的索引都存儲在屬性數組中。
這裏是我使用的代碼:
d3ddev->SetVertexDeclaration(m_vertexDeclaration);
d3ddev->SetIndices(m_indexBuffer);
d3ddev->SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | m_numInstancesToDraw));
d3ddev->SetStreamSource(0, m_vertexBuffer, 0, D3DXGetDeclVertexSize(m_geometryElements, 0));
d3ddev->SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INSTANCEDATA | 1ul));
d3ddev->SetStreamSource(1, m_instanceBuffer, 0, D3DXGetDeclVertexSize(m_instanceElements, 1));
m_effect->Begin(NULL, NULL); // begin using the effect
m_effect->BeginPass(0); // begin the pass
for(DWORD i = 0; i < m_numMaterials; ++i) // loop through each subset.
{
d3ddev->SetMaterial(&m_materials[i]); // set the material for the subset
if(m_textures[i] != NULL)
{
d3ddev->SetTexture(0, m_textures[i]);
}
d3ddev->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST, // Type
0, // BaseVertexIndex
m_attributes[i].VertexStart, // MinIndex
m_attributes[i].VertexCount, // NumVertices
m_attributes[i].FaceStart * 3, // StartIndex
m_attributes[i].FaceCount // PrimitiveCount
);
}
m_effect->EndPass();
m_effect->End();
d3ddev->SetStreamSourceFreq(0,1);
d3ddev->SetStreamSourceFreq(1,1);
此代碼將只對第一材料工作。當我說第一個我指的是索引0時,因爲如果我用第二個材質開始我的循環,它不會被渲染。但是,通過調試PIX中的頂點緩衝區,我可以看到所有正在處理的資料。所以在頂點着色器之後發生了一些事情。
另一個奇怪的問題是,如果我將包含實例數據的流源設置爲頂點大小爲零,則所有材質都將呈現。
因此取而代之的是:
d3ddev->SetStreamSource(1, m_instanceBuffer, 0, D3DXGetDeclVertexSize(m_instanceElements, 1));
我被替換爲:
d3ddev->SetStreamSource(1, m_instanceBuffer, 0, 0);
但當然,與此代碼,我的所有實例都在相同的位置呈現,因爲我重用相同實例數據一遍又一遍。
最後一點,如果我用D3DCREATE_SOFTWARE_VERTEXPROCESSING創建我的設備,一切正常。只有硬件有問題,但不幸的是,DirectX在調試模式下不報告任何問題。