DirectX9 SDK Samples(15) OptimizedMesh Sample

来源:互联网 发布:怎么招募淘宝客 编辑:程序博客网 时间:2024/05/16 10:52

优化网格,主要是将triangle list优化成triangle strip。

主要用到的API有:ID3DX10Mesh::Optimize,D3DXConvertMeshSubsetToSingleStrip,D3DXConvertMeshSubsetToStrips

而渲染的时候对应用到的函数有:IDirect3DDevice9::SetStreamSource,IDirect3DDevice9::SetIndices,IDirect3DDevice9::DrawIndexedPrimitive

struct SStripData{    LPDIRECT3DINDEXBUFFER9 m_pStrips;          // strip indices (single strip)    LPDIRECT3DINDEXBUFFER9 m_pStripsMany;      // strip indices (many strips)    DWORD m_cStripIndices;    DWORD* m_rgcStripLengths;    DWORD m_cStrips;//省略构造函数};struct SMeshData{    LPD3DXMESH m_pMeshSysMem;      // System memory copy of mesh    LPD3DXMESH m_pMesh;            // Local version of mesh, copied on resize    LPDIRECT3DVERTEXBUFFER9 m_pVertexBuffer;    // vertex buffer of mesh    SStripData* m_rgStripData;      // strip indices split by attribute    DWORD m_cStripDatas;//省略析构构造函数};
上面是两个这次例子定义的结构体。

1OnCreateDevice

    // Load mesh    hr = LoadMeshData( pd3dDevice, MESHFILENAME, &pMeshSysMem, &pAdjacencyBuffer );    if( SUCCEEDED( hr ) )    {        hr = OptimizeMeshData( pMeshSysMem, pAdjacencyBuffer, D3DXMESHOPT_ATTRSORT, &g_MeshAttrSorted );        if( SUCCEEDED( hr ) )            hr = OptimizeMeshData( pMeshSysMem, pAdjacencyBuffer, D3DXMESHOPT_STRIPREORDER, &g_MeshStripReordered );        if( SUCCEEDED( hr ) )            hr = OptimizeMeshData( pMeshSysMem, pAdjacencyBuffer,                                   D3DXMESHOPT_VERTEXCACHE, &g_MeshVertexCacheOptimized );    //省略
这里用到了自定义函数LoadMeshData,没什么特别,就是载入网格、材质和纹理。

然后分别进行了3种优化,根据属性排序、strip顺序和顶点缓存。


2OptimizeMeshData

    // Attribute sort - the un-optimized mesh option    // remember the adjacency for the vertex cache optimization    hr = pMeshSysMem->Optimize( dwOptFlags | D3DXMESH_SYSTEMMEM,                                ( DWORD* )pAdjacencyBuffer->GetBufferPointer(),                                NULL, NULL, NULL, &pMeshData->m_pMeshSysMem );
第一种优化,优化效果见注释

    pMeshData->m_cStripDatas = g_dwNumMaterials;    pMeshData->m_rgStripData = new SStripData[ pMeshData->m_cStripDatas ];    if( pMeshData->m_rgStripData == NULL )    {        hr = E_OUTOFMEMORY;        goto End;    }    g_bCantDoSingleStrip = false;    for( DWORD iMaterial = 0; iMaterial < g_dwNumMaterials; iMaterial++ )    {        hr = D3DXConvertMeshSubsetToSingleStrip( pMeshData->m_pMeshSysMem, iMaterial,                                                 D3DXMESH_IB_MANAGED, &pMeshData->m_rgStripData[iMaterial].m_pStrips,                                                 &pMeshData->m_rgStripData[iMaterial].m_cStripIndices );//检查strip个数是否超出设备支持范围
对每一种材质先进行单个strip优化。
        hr = D3DXConvertMeshSubsetToStrips( pMeshData->m_pMeshSysMem, iMaterial,                                            D3DXMESH_IB_MANAGED, &pMeshData->m_rgStripData[iMaterial].m_pStripsMany,                                            NULL, &pbufTemp, &pMeshData->m_rgStripData[iMaterial].m_cStrips );        pMeshData->m_rgStripData[iMaterial].m_rgcStripLengths = new            DWORD[pMeshData->m_rgStripData[iMaterial].m_cStrips];        memcpy( pMeshData->m_rgStripData[iMaterial].m_rgcStripLengths,                pbufTemp->GetBufferPointer(),                sizeof( DWORD ) * pMeshData->m_rgStripData[iMaterial].m_cStrips );
然后进行多strip优化。注意,这里pbufTemp返回了各个strip的长度,相当于一个DWORD数组(这里用的DWORD)。

3DrawMeshData

在OnFrameRender中调用。

        for( DWORD iMaterial = 0; iMaterial < g_dwNumMaterials; iMaterial++ )        {            if( !g_bShowStrips && !g_bShowSingleStrip )            {                V( pMeshData->m_pMesh->DrawSubset( iMaterial ) );            }            else  // drawing strips            {//省略                V( pd3dDevice->SetFVF( dwFVF ) );                V( pd3dDevice->SetStreamSource( 0, pMeshData->m_pVertexBuffer, 0, cBytesPerVertex ) );                if( g_bShowSingleStrip )                {                    if( !g_bCantDoSingleStrip )                    {                        V( pd3dDevice->SetIndices( pMeshData->m_rgStripData[iMaterial].m_pStrips ) );                        V( pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0,                                                             0, pMeshData->m_pMesh->GetNumVertices(),                                                             0, pMeshData->m_rgStripData[iMaterial].m_cStripIndices -                                                             2 ) );                    }                }                else                {                    V( pd3dDevice->SetIndices( pMeshData->m_rgStripData[iMaterial].m_pStripsMany ) );                    iCurFace = 0;                    for( iStrip = 0; iStrip < pMeshData->m_rgStripData[iMaterial].m_cStrips; iStrip++ )                    {                        V( pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0,                                                             0, pMeshData->m_pMesh->GetNumVertices(),                                                             iCurFace,                                                             pMeshData->m_rgStripData[iMaterial].m_rgcStripLengths[iStrip] ) );                        iCurFace += 2 + pMeshData->m_rgStripData[iMaterial].m_rgcStripLengths[iStrip];                    }                }            }        }
其中iCurFace是本次渲染的起始顶点的索引,CurrentFace,其实这名字有歧义,不是Face,而是Vertex。

原创粉丝点击