Creating Subsets in ID3DxMesh

来源:互联网 发布:webpackconfig.js vue 编辑:程序博客网 时间:2024/06/04 23:25
Note: While D3DXMESHOPT_ATTRSORT is sufficient to set up the attribute tables, it does not provide further optimization to improve vertex cache performance.  It is highly recommended that you instead use the D3DXMESHOPT_VERTEXCACHE flag, which will create the attribute table and also reorder the vertices to make optimum use of the vertex cache.

Here is an example of a function that divides a mesh into a series of irregularly sized subsets, allowing subsets to consist of non-contiguous series of faces:

// define subset info we will assign
DWORD faceCount[] = {  50, 100,  50, 100, 200,   0};
DWORD subsetNum[] = {   0,   1,   0,   2,   3 };
// First 50 faces (0-49) belong to subset 0
// Next 100 faces (50-149) belong to subset 1
// Next 50 faces (150-199) also belong to subset 0
// Next 100 faces (200-299) belong to subset 2
// Next 200 faces (300-499) belong to subset 3
// 0 faces in final faceCount[] index denotes end of list

if (FAILED(SetSubsets(pMesh,faceCount,subsetNum)) {
    // handle error
    ...
}

DWORD SetSubsets(ID3DXMesh *pMesh,DWORD *pFaceCount,DWORD *pSubsetNum) {
   
    // Get face count, used to ensure we don't overrun attribute buffer
    DWORD numFaces=pMesh->GetFaceCount();
 
    // lock the attribute buffer
    DWORD *attribBuf;
    HRESULT hr;
    if (SUCCEEDED(hr=pMesh->LockAttributeBuffer(D3DLOCK_DISCARD,&attribBuf))) {

        // initialize face counter
        DWORD faceNum=0;

        // loop through the subsets
        for (int i=0;pFaceCount[i];i++) {

            // make sure there are enough faces for this subset
            if (faceNum+pFaceCount[i]>=numFaces) {
                // not enough faces, unlock the attribute buffer and return error code
                pMesh->UnlockAttributeBuffer();
                return E_INVALIDARG;
            }
 
            // loop through the faces for this range
            for (int j=0;j<pFaceCount[i];i++) {

                // set the subset number of each face in this range
                attribBuf[faceNum]=pSubsetNum[i];
           
                // increment face counter
                faceNum++;
            }
        }

        // unlock the attribute buffer
        pMesh->UnlockAttributeBuffer();

        // allocate storage and generate adjacency data
        DWORD *pAdj=new DWORD[numFaces*3];
        if (!pAdj)
            return E_OUTOFMEMORY;
        if (FAILED(hr=pMesh->GenerateAdjacency(0.0f,pAdj) {
            delete pAdj;
            return hr;
        }
        // optimize the mesh with attribute sorting
        // D3DXMESHOPT_ATTRSORT
        if (FAILED(hr=pMesh->OptimizeInPlace(D3DXMESHOPT_VERTEXCACHE,pAdj,NULL,NULL,NULL)) {
            delete pAdj;
            return hr;
        }

        // de-allocate adjacency data storage
        delete pAdj;

    } else

        // return error code on failure to lock attribute buffer
        return hr;

    // return success
    return S_OK;
}

Note that if you already have adjacency data for the mesh, you won't have to re-compute it in the function as I have here - I included that for simplicity.  If you already have adjacency data you can pass it to the optimization function, and may also need to provide a pointer to an array to contain the new adjacency information, as a parameter to the optimization function, if you have further use for this data.

原创粉丝点击