• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當(dāng)自強(qiáng)而不息

            網(wǎng)格模型高級(jí)技術(shù)(17)

            蒙皮骨骼動(dòng)畫網(wǎng)格模型接口是對(duì)上一節(jié)骨骼動(dòng)畫網(wǎng)格模型接口的擴(kuò)展,添加了處理蒙皮信息的功能。

             

            進(jìn)一步擴(kuò)展結(jié)構(gòu)體D3DXMESHCONTAINER

            為了在網(wǎng)格模型中包含蒙皮信息,需要進(jìn)一步擴(kuò)展D3DXMESHCONTAINER_DERIVEED,其定義如下:

            struct D3DXMESHCONTAINER_DERIVED : public D3DXMESHCONTAINER
            {
            IDirect3DTexture9** ppTextures;
            ID3DXMesh* pOrgMesh;
            DWORD MaxBonesInflPerVertex;
            DWORD NumAttrGroups;
            ID3DXBuffer* pBoneCombBuffer;
            D3DXMATRIX** ppBoneMatrices;
            D3DXMATRIX** ppBoneOffsetMatrices;
            DWORD NumMatrixPalettes;
            bool UseSoftwareVP;
            };

            當(dāng)加載原網(wǎng)格模型并由此生成一個(gè)蒙皮網(wǎng)格時(shí),會(huì)用D3DXMESHCONTAINER::MeshData::pMesh存儲(chǔ)所生成的蒙皮網(wǎng)格模型,這時(shí)需要將初始網(wǎng)格模型保存下來(lái),這就是pOrgMesh的作用。變量MaxBonesInflPerVertex表示每個(gè)頂點(diǎn)最多受多少骨骼的影響,指針變量pBoneCombBuffer指向骨骼結(jié)合表,骨骼結(jié)合表中的數(shù)據(jù)按屬性組結(jié)構(gòu)體D3DXBONECOMBINATION組織起來(lái),該結(jié)構(gòu)體定義如下:

            Describes a subset of the mesh that has the same attribute and bone combination.

            typedef struct D3DXBONECOMBINATION {
            DWORD AttribId;
            DWORD FaceStart;
            DWORD FaceCount;
            DWORD VertexStart;
            DWORD VertexCount;
            DWORD * BoneId;
            } D3DXBONECOMBINATION, *LPD3DXBONECOMBINATION;

            Members

            AttribId
            Attribute table identifier.
            FaceStart
            Starting face.
            FaceCount
            Face count.
            VertexStart
            Starting vertex.
            VertexCount
            Vertex count.
            BoneId

            Pointer to an array of values that identify each of the bones that can be drawn in a single drawing call. Note that the array can be of variable length to accommodate variable length bone combinations of ID3DXSkinInfo::ConvertToIndexedBlendedMesh.

            The size of the array varies based on the type of mesh generated. A non-indexed mesh array size is equal to the number of weights per vertex (pMaxVertexInfl in ID3DXSkinInfo::ConvertToBlendedMesh). An indexed mesh array size is equal to the number of bone matrix palette entries (paletteSize in ID3DXSkinInfo::ConvertToIndexedBlendedMesh).

            Remarks

            The subset of the mesh described by D3DXBONECOMBINATION can be rendered in a single drawing call.

            結(jié)構(gòu)體D3DXBONECOMBINATION用來(lái)描述網(wǎng)格中具有同樣屬性的部分,也就是網(wǎng)格模型的一個(gè)子集,這個(gè)網(wǎng)格模型子集也稱為屬性組。屬性組實(shí)際上是用來(lái)標(biāo)識(shí)網(wǎng)格模型中被指定的骨骼矩陣所影響的子網(wǎng)格,不同屬性組所標(biāo)識(shí)的子網(wǎng)格需要用不同的紋理、材質(zhì)進(jìn)行渲染,該子網(wǎng)格可以通過(guò)調(diào)用函數(shù)DrawIndexedPrimitive()或者DrawSubset()進(jìn)行繪制。

            成員變量BoneId指向一個(gè)數(shù)組,該數(shù)組表示的是在單獨(dú)的一次繪制中,即一次DrawSubset()函數(shù)調(diào)用中所用到的全部骨骼矩陣,該數(shù)組的大小與將要生成的蒙皮網(wǎng)格類型有關(guān),在索引頂點(diǎn)混合蒙皮網(wǎng)格中,它的大小等于函數(shù)ConvertToIndexedBlendedMesh()中的輸入?yún)?shù)paletteSize,也就是結(jié)構(gòu)體D3DXMESHCONTAINER_DERIVEED的成員變量NumMatrixPalettes。變量NumMatrixPalettes表示進(jìn)行索引頂點(diǎn)混合時(shí)所需要的矩陣調(diào)色板的容量,它的數(shù)值需要根據(jù)硬件設(shè)備能力進(jìn)行相應(yīng)的設(shè)置。

             

            cAllocateHierarchy類的設(shè)計(jì)實(shí)現(xiàn)

            蒙皮骨骼動(dòng)畫網(wǎng)格模型接口中cAllocateHierarchy類和骨骼動(dòng)畫網(wǎng)格模型接口中的cAllocateHierarchy類基本相同,區(qū)別較大的是CreateMeshContainer()函數(shù)中增加了對(duì)蒙皮信息的處理:

            // generate skin mesh
            if(skin_info != NULL)
            {
            new_mesh_container->pSkinInfo = skin_info;
            skin_info->AddRef();
            	new_mesh_container->pOrgMesh = mesh_ptr;
            mesh_ptr->AddRef();
            	UINT num_bones = skin_info->GetNumBones();
            new_mesh_container->ppBoneOffsetMatrices = new D3DXMATRIX*[num_bones];
            	if(new_mesh_container->ppBoneOffsetMatrices == NULL)
            {
            DestroyMeshContainer(new_mesh_container);
            return E_OUTOFMEMORY;
            }
            	for(UINT i = 0; i < num_bones; i++)
            new_mesh_container->ppBoneOffsetMatrices[i] = new_mesh_container->pSkinInfo->GetBoneOffsetMatrix(i);
            	hr = GenerateSkinnedMesh(new_mesh_container);
            	if(FAILED(hr))
            {
            DestroyMeshContainer(new_mesh_container);
            return hr;
            }
            }

            CreateMeshContainer()函數(shù)中處理蒙皮信息的關(guān)鍵是調(diào)用自定義函數(shù)GenerateSkinnedMesh()來(lái)生成蒙皮網(wǎng)格模型,其定義如下:

            HRESULT cAllocateHierarchy::GenerateSkinnedMesh(D3DXMESHCONTAINER_DERIVED* mesh_container)
            {
                ID3DXSkinInfo
            * skin_info = mesh_container->pSkinInfo;

                
            if(skin_info == NULL)
                    
            return S_OK;

                release_com(mesh_container
            ->MeshData.pMesh);
                release_com(mesh_container
            ->pBoneCombBuffer);

                HRESULT hr;
                IDirect3DIndexBuffer9
            * index_buffer;
                
                
            if(FAILED(hr = mesh_container->pOrgMesh->GetIndexBuffer(&index_buffer)))
                    
            return hr;

                DWORD max_faces_infl_per_triangle;
                hr 
            = skin_info->GetMaxFaceInfluences(index_buffer, mesh_container->pOrgMesh->GetNumFaces(), 
                                                     
            &max_faces_infl_per_triangle);

                index_buffer
            ->Release();

                
            if(FAILED(hr))
                    
            return hr;

                max_faces_infl_per_triangle 
            = min(max_faces_infl_per_triangle, 12);

                IDirect3DDevice9
            * device = DXUTGetD3DDevice();

                D3DCAPS9 caps;
                device
            ->GetDeviceCaps(&caps);

                
            if((caps.MaxVertexBlendMatrixIndex+1)/2 < max_faces_infl_per_triangle)
                {
                    
            // use software vertex processing
                    mesh_container->NumMatrixPalettes = min(256, skin_info->GetNumBones());
                    mesh_container
            ->UseSoftwareVP = true;
                }
                
            else
                {
                    
            // use hardware verterx processing
                    mesh_container->NumMatrixPalettes = min((caps.MaxVertexBlendMatrixIndex+1)/2, skin_info->GetNumBones());
                    mesh_container
            ->UseSoftwareVP = false;
                }

                hr 
            = skin_info->ConvertToIndexedBlendedMesh(mesh_container->pOrgMesh, 0, mesh_container->NumMatrixPalettes,
                        mesh_container
            ->pAdjacency, NULL, NULL, NULL, &mesh_container->MaxBonesInflPerVertex,
                        
            &mesh_container->NumAttrGroups, &mesh_container->pBoneCombBuffer, &mesh_container->MeshData.pMesh);

                
            return hr;
            }

             

            函數(shù)GenerateSkinnedMesh()判斷當(dāng)前網(wǎng)格容器是否包含蒙皮信息,如果當(dāng)前網(wǎng)格模型中不包含蒙皮信息,則直接退出該函數(shù)。接下來(lái)確定所需要的矩陣調(diào)色板的容量,最后調(diào)用函數(shù)ConvertToIndexedBlendedMesh()根據(jù)初始網(wǎng)格模型提供的相應(yīng)參數(shù)生成索引蒙皮網(wǎng)格模型。函數(shù)ConvertToIndexedBlendedMesh()的聲明如下:

            Takes a mesh and returns a new mesh with per-vertex blend weights, indices, and a bone combination table. The table describes which bone palettes affect which subsets of the mesh.

            HRESULT ConvertToIndexedBlendedMesh(
            LPD3DXMESH pMesh,
            DWORD Options,
            DWORD paletteSize,
            CONST DWORD * pAdjacencyIn,
            LPDWORD pAdjacencyOut,
            DWORD * pFaceRemap,
            LPD3DXBUFFER * ppVertexRemap,
            DWORD * pMaxVertexInfl,
            DWORD * pNumBoneCombinations,
            LPD3DXBUFFER * ppBoneCombinationTable,
            LPD3DXMESH * ppMesh
            );

            Parameters

            pMesh
            [in] The input mesh.
            Options
            [in] Currently unused.
            paletteSize
            [in] Number of bone matrices available for matrix palette skinning.
            pAdjacencyIn
            [in] Input mesh adjacency information.
            pAdjacencyOut
            [in] Output mesh adjacency information.
            pFaceRemap
            [out] An array of DWORDs, one per face, that identifies the original mesh face that corresponds to each face in the blended mesh. If the value supplied for this argument is NULL, face remap data is not returned.
            ppVertexRemap
            [out] Address of a pointer to an ID3DXBuffer interface, which contains a DWORD for each vertex that specifies how the new vertices map to the old vertices. This remap is useful if you need to alter external data based on the new vertex mapping. This parameter is optional; NULL may be used.
            pMaxVertexInfl
            [out] Pointer to a DWORD that will contain the maximum number of bone influences required per vertex for this skinning method.
            pNumBoneCombinations
            [out] Pointer to the number of bones in the bone combination table.
            ppBoneCombinationTable
            [out] Pointer to the bone combination table. The data is organized in a D3DXBONECOMBINATION structure.
            ppMesh
            [out] Pointer to the new mesh.

            Return Values

            If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.

            Remarks

            Each element in the remap arrays specifies the previous index for that position. For example, if a vertex was in position 3 but has been remapped to position 5, then the fifth element of pVertexRemap will contain 3.

            This method does not run on hardware that does not support fixed-function vertex blending.


            posted on 2008-06-13 12:39 lovedday 閱讀(3290) 評(píng)論(2)  編輯 收藏 引用

            評(píng)論

            # re: 網(wǎng)格模型高級(jí)技術(shù)(17) 2009-05-30 15:55 拜讀者

            你寫的內(nèi)容不錯(cuò),為什么不寫書出版呢?  回復(fù)  更多評(píng)論   

            # re: 網(wǎng)格模型高級(jí)技術(shù)(17)[未登錄](méi) 2010-09-14 15:31 1

            這些就是書上的內(nèi)容!  回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            午夜精品久久久久成人| 91精品国产综合久久香蕉| 亚洲一区精品伊人久久伊人| 久久人妻少妇嫩草AV蜜桃| 久久久久久午夜精品| 三上悠亚久久精品| 66精品综合久久久久久久| 伊人久久大香线蕉精品不卡| 色8久久人人97超碰香蕉987| 国产精品gz久久久| 人妻无码αv中文字幕久久| 久久久久国产精品| 亚洲精品乱码久久久久久中文字幕 | 99久久精品国产高清一区二区| 精品综合久久久久久97超人| 色偷偷88欧美精品久久久 | 久久久一本精品99久久精品66| 亚洲伊人久久大香线蕉苏妲己| 久久久国产视频| 久久久久亚洲AV无码去区首| 久久久精品一区二区三区| 亚洲欧美日韩中文久久| 深夜久久AAAAA级毛片免费看| 久久线看观看精品香蕉国产| 亚洲综合久久久| 合区精品久久久中文字幕一区| 久久国产高清字幕中文| 无码日韩人妻精品久久蜜桃| 一本色道久久88综合日韩精品| 久久午夜电影网| 91精品婷婷国产综合久久| 久久久久人妻一区精品性色av | 国产精品美女久久久久| 久久精品国产亚洲av麻豆色欲| 欧美日韩中文字幕久久久不卡| 国产激情久久久久影院| 成人国内精品久久久久影院VR| 热99re久久国超精品首页| 国产精品青草久久久久婷婷 | 久久精品国产99久久久香蕉| 天天久久狠狠色综合|