DirectX9 Use Geometry Instancing for a Mesh with multiple materials

Started by
-1 comments, last by Liemarzac 11 years, 4 months ago

I am trying to have a flexible Geometry Instancing code able to handle meshes with multiple materials. For a mesh with one material everything is fine. I manage to render as many instances as I want with a single draw call.
Things get a bit more complicated with multiple materials. My mesh comes from an .x file. It has one vertex buffer, one index buffer but several materials. The indexes to render for each subset (materials) is stored in an attribute array.
Here is the code I use:
[source lang="cpp"] 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); // set the material for the subset
if(m_textures != NULL)
{
d3ddev->SetTexture( 0, m_textures );
}

d3ddev->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST, // Type
0, // BaseVertexIndex
m_attributes.VertexStart, // MinIndex
m_attributes.VertexCount, // NumVertices
m_attributes.FaceStart * 3, // StartIndex
m_attributes.FaceCount // PrimitiveCount
);
}

m_effect->EndPass();
m_effect->End();

d3ddev->SetStreamSourceFreq(0,1);
d3ddev->SetStreamSourceFreq(1,1);[/source]
This code will work for the first material only. When I say the first I meant the one at index 0 because if I start my loop with the second material, it will not be rendered. However, by debugging the vertex buffer in PIX, I can see all my materials being processed properly. So something happens after the vertex shader.
Another weird issue, all my materials will be rendered if I set my stream source containing the instance data to be a vertex size of zero.
So Instead of this:
[source lang="cpp"] d3ddev->SetStreamSource(1, m_instanceBuffer, 0, D3DXGetDeclVertexSize( m_instanceElements, 1 ) );[/source]
I replace it by:
[source lang="cpp"] d3ddev->SetStreamSource(1, m_instanceBuffer, 0, 0 );[/source]
But of course, with this code, all my instances are rendered at the same position since I reuse the same instance data over and over again.
And last point, everything works fine if I create my device with D3DCREATE_SOFTWARE_VERTEXPROCESSING. Only Hardware has the issue but unfortunately DirectX does not report any problem in debug mode.
I have spent several days on this and I am out of ideas. Any help would be much appreciated smile.png
Thanks

This topic is closed to new replies.

Advertisement