Creating Subsets in ID3DxMesh

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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值