In DirectX mesh files, a texture may be shared by several materials. This is because vertices are grouped by Attributes. different attributes are required as long as the materials and textures are different. In general modeling software, textures are often used as part of materials. Each "material" has its own texture during export, this is also because sometimes the mesh uses the same texture in different parts but has different illumination characteristics. DirectX mesh also organizes materials, textures, and grids in the same way.
In the case provided by DirectX, each material loads a texture separately. However, debuggingProgramYou will find that sometimes only a few texture objects are loaded, and there are more than a dozen materials, so it is clear that the texture is loaded repeatedly, we can use the reference count of COM to avoid this problem.
Before loading the texture corresponding to a material, check whether the texture in front has the same name. If yes, copy the texture pointer to the texture pointer corresponding to the material, add a reference to the texture of the copied pointer. When releasing it in the future, you don't have to worry about whether the previous one has been released.
Com refers to the reference count. When a reference is added, the counter is incremented by 1. When the counter is released once, the counter is reduced by 1. If the counter is reduced to 0, it is released from the memory. If a smart pointer is used, the problem will be simpler. simply copy the pointer:
M_pmeshtextures [I] = m_pmeshtextures [J];
In the DirectX type declaration, we can see that,Lpdirect3dtexture9 is not a smart pointer:
Typedef Struct Idirect3dtexture9 * Lpdirect3dtexture9, * Pdirect3dtexture9;
Therefore, after copying the pointer, add 1 to the reference of this COM object.
M_pmeshtextures [J] -> Addref ();
M_pmeshmaterials = New D3dmaterial9 [m_dwnumofmaterials]; // Material pointer Array
M_pmeshtextures = New Lpdirect3dtexture9 [m_dwnumofmaterials]; // Texture pointer Array
For (DWORD I = 0 ; I < M_dwnumofmaterials; I ++ )
{
M_pmeshmaterials [I] = D3dxmaterials [I]. matd3d; // Copy material from the buffer
M_pmeshmaterials [I]. Ambient = M_pmeshmaterials [I]. Diffuse; // Set environment light attributes
M_pmeshtextures [I] = NULL; // Initial Blank
// Load Texture Based on the texture file name in the material
DWORD J = 0 ;
While (J < I)
{ // Avoid repeated texture Loading
If ( 0 = Strcmp (d3dxmaterials [J]. ptexturefilename, d3dxmaterials [I]. ptexturefilename) // locate the serial number of the texture with the same name
{< br> m_pmeshtextures [I] = m_pmeshtextures [J]; // directly copy the pointer instead of loading it once
m_pmeshtextures [J] -> addref (); // see Add 1
Break ;
} ;
J ++ ;
}
If ( ! M_pmeshtextures [I])
{
D3dxcreatetexturefromfile (m_pdevice,
D3dxmaterials [I]. ptexturefilename,&M_pmeshtextures [I]);
}
}
When releasing, follow the normal method to release it.
For (DWORD I = 0 ; I < M_dwnumofmaterials; I ++ )
{
Safe_release (m_pmeshtextures [I]);
}
Safe_delete_array (m_pmeshtextures );
Safe_delete_array (m_pmeshmaterials );