D3D Animation Basis(6)

D3D Animation Basis(6)

The second load_mesh function  is much like the first, except that instead of loading an entire .X file into one D3DXMESHCONTAINER_EX object, you are able to load a single mesh object (using the D3DXLoadSkinMeshFromXof function) as pointed to by a ID3DXFileData object (used while parsing an .X file). Here's the prototype:

HRESULT load_mesh(D3DXMESHCONTAINER_EX** ret_mesh_container,
  IDirect3DDevice9* device,
  ID3DXFileData* xfile_data,
  const char* texture_path,
  DWORD new_fvf,
  DWORD load_flags);

You'll notice that the xfile_data parameter is here instead of the filename parameter used by the first LoadMesh function. The xfile_data parameter is of the type ID3DXFileData, which is an object that represents the currently enumerated data object inside an .X file.

Calling the second load_mesh function is the same as calling the first (with the exception of providing a pointer to the enumerated data object).

HRESULT load_mesh(D3DXMESHCONTAINER_EX **  ret_mesh_container,
                  IDirect3DDevice9
*  device,
                  ID3DXFileData
*  xfile_data,                  
                  
const   char *  texture_path,
                  DWORD new_fvf,
                  DWORD load_flags)
{
    
//  error checking
     if (ret_mesh_container  ==  NULL  ||  device  ==  NULL  ||  xfile_data  ==  NULL  ||  texture_path  ==  NULL)
        
return  E_FAIL;

    
//  use system memory if converting FVF
     if (new_fvf)
        load_flags 
=  D3DXMESH_SYSTEMMEM;

    
//  load the mesh using D3DX routines

    ID3DXMesh
*         mesh;
    ID3DXSkinInfo
*   skin_info;
    ID3DXBuffer
*     material_buffer;
    ID3DXBuffer
*     adj_buffer;
    DWORD            num_materials;    

    HRESULT hr 
=  D3DXLoadSkinMeshFromXof(xfile_data, load_flags, device,  & adj_buffer,  & material_buffer, NULL,
                                         
& num_materials,  & skin_info,  & mesh);

    
if (FAILED(hr))
        
return  hr;

    
//  free skin info if no bones
     if (skin_info  &&  skin_info -> GetNumBones()  ==   0 )
        release_com(skin_info);

    
//  convert to new FVF first as needed (not with skinned models)
     if (new_fvf)
    {
        ID3DXMesh
*  clone_mesh;
        hr 
=  mesh -> CloneMeshFVF(load_flags, new_fvf, device,  & clone_mesh);

        
if (FAILED(hr))
        {
            release_com(mesh);
            release_com(skin_info);
            release_com(adj_buffer);
            release_com(material_buffer);            

            
return  hr;
        }

        
//  free prior mesh and store new pointer
        release_com(mesh);
        mesh 
=  clone_mesh; clone_mesh  =  NULL;
    }

    D3DXMESHCONTAINER_EX
*  mesh_container  =   new  D3DXMESHCONTAINER_EX;
    
* ret_mesh_container  =  mesh_container;

    
//  store mesh name (filename), type, and mesh pointer.

    DWORD size;
    xfile_data
-> GetName(NULL,  & size);

    
if (size)
    {
        mesh_container
-> Name  =   new   char [size];
        xfile_data
-> GetName(mesh_container -> Name,  & size);
    }
    
    mesh_container
-> MeshData.Type   =  D3DXMESHTYPE_MESH;
    mesh_container
-> MeshData.pMesh  =  mesh;
    mesh_container
-> pSkinInfo        =  skin_info;

    mesh      
=  NULL;
    skin_info 
=  NULL;

    
//  store adjacency information

    DWORD adj_buffer_size 
=  adj_buffer -> GetBufferSize();

    
if (adj_buffer_size)
    {
        mesh_container
-> pAdjacency  =  (DWORD * new   char [adj_buffer_size];
        memcpy(mesh_container
-> pAdjacency, adj_buffer -> GetBufferPointer(), adj_buffer_size);
    }

    release_com(adj_buffer);

    
//  create a duplicate mesh in case skinning is used
     if (mesh_container -> pSkinInfo)
    {
        mesh_container
-> MeshData.pMesh -> CloneMeshFVF( 0 , mesh_container -> MeshData.pMesh -> GetFVF(), device,
                                                     
& mesh_container -> skin_mesh);
    }

    
//  build material list

    mesh_container
-> NumMaterials  =  num_materials;

    
if (num_materials  ==   0 )
    {
        
//  create a default material
        mesh_container -> NumMaterials  =   1 ;
        mesh_container
-> pMaterials      =   new  D3DXMATERIAL[ 1 ];
        mesh_container
-> textures      =   new  IDirect3DTexture9 * [ 1 ];

        ZeroMemory(mesh_container
-> pMaterials,  sizeof (D3DXMATERIAL));

        mesh_container
-> pMaterials[ 0 ].MatD3D.Diffuse.r  =   1.0f ;
        mesh_container
-> pMaterials[ 0 ].MatD3D.Diffuse.g  =   1.0f ;
        mesh_container
-> pMaterials[ 0 ].MatD3D.Diffuse.b  =   1.0f ;
        mesh_container
-> pMaterials[ 0 ].MatD3D.Diffuse.a  =   1.0f ;
        mesh_container
-> pMaterials[ 0 ].MatD3D.Ambient    =  mesh_container -> pMaterials[ 0 ].MatD3D.Diffuse;
        mesh_container
-> pMaterials[ 0 ].MatD3D.Specular   =  mesh_container -> pMaterials[ 0 ].MatD3D.Diffuse;
        mesh_container
-> pMaterials[ 0 ].pTextureFilename  =  NULL;

        mesh_container
-> textures[ 0 ]                        =  NULL;
    }
    
else
    {
        
//  load the materials
        D3DXMATERIAL *  xmaterials    =  (D3DXMATERIAL * ) material_buffer -> GetBufferPointer();
        mesh_container
-> pMaterials  =   new  D3DXMATERIAL[mesh_container -> NumMaterials];
        mesh_container
-> textures    =   new  IDirect3DTexture9 * [mesh_container -> NumMaterials];

        
for (DWORD i  =   0 ; i  <  mesh_container -> NumMaterials; i ++ )
        {
            mesh_container
-> pMaterials[i].MatD3D  =  xmaterials[i].MatD3D;
            mesh_container
-> pMaterials[i].MatD3D.Ambient  =  mesh_container -> pMaterials[i].MatD3D.Diffuse;

            mesh_container
-> textures[i]  =  NULL;

            
//  load the texture if one exists
             if (xmaterials[i].pTextureFilename)
            {
                
char  texture_file[MAX_PATH];
                sprintf(texture_file, 
" %s%s " , texture_path, xmaterials[i].pTextureFilename);
                D3DXCreateTextureFromFile(device, texture_file, 
& mesh_container -> textures[i]);
            }
        }
    }

    release_com(material_buffer);

    mesh_container
-> MeshData.pMesh -> OptimizeInplace(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL);
    mesh_container 
=  NULL;

    
return  S_OK;
}
 

 

你可能感兴趣的:(D3D Animation Basis(6))