0

我正在尝试拥有一个灵活的几何实例化代码,能够处理具有多种材料的网格。对于具有一种材料的网格,一切都很好。我设法通过一次绘制调用渲染尽可能多的实例。

使用多种材料会使事情变得更加复杂。我的网格来自一个 .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 在调试模式下没有报告任何问题。

4

2 回答 2

0

我遇到了同样的问题,就我而言,问题在于用于实例化网格的池。我最初在 SYSTEM_MEMORY 中有这个网格,但在 POOL_DEFAULT 中有实例化网格。当我将实例化网格更改为默认内存时,一切都按预期工作。

希望能帮助到你。

于 2014-09-17T15:39:56.580 回答
0

请参阅着色器模型 3 文档

如果您在硬件中实现着色器,则不得将 vs_3_0 或 ps_3_0 与任何其他着色器版本一起使用,并且您不得将任一着色器类型与固定功能管道一起使用。这些更改使简化驱动程序和运行时成为可能。唯一的例外是纯软件 vs_3_0 着色器可以与任何像素着色器版本一起使用。

于 2013-02-10T00:40:40.860 回答