CDXUTMesh文档格式.docx
《CDXUTMesh文档格式.docx》由会员分享,可在线阅读,更多相关《CDXUTMesh文档格式.docx(45页珍藏版)》请在冰点文库上搜索。
IDirect3DVertexDeclaration9*
m_pDecl;
DWORD
m_dwNumVertices;
m_dwNumFaces;
m_dwBytesPerVertex;
m_dwNumMaterials;
Materials
the
D3DMATERIAL9*
m_pMaterials;
CHAR
(*m_strMaterials)[MAX_PATH];
IDirect3DBaseTexture9**
m_pTextures;
bool
m_bUseMaterials;
Rendering
HRESULT
Render(
LPDIRECT3DDEVICE9
pd3dDevice,
bDrawOpaqueSubsets
=
true,
bDrawAlphaSubsets
true
);
ID3DXEffect
*pEffect,
D3DXHANDLE
hTexture
NULL,
hDiffuse
hAmbient
hSpecular
hEmissive
hPower
Mesh
GetMesh()
{
return
}
Rendering
options
void
UseMeshMaterials(
bFlag
)
m_bUseMaterials
bFlag;
SetFVF(
dwFVF
SetVertexDecl(
const
D3DVERTEXELEMENT9
*pDecl,
bAutoComputeNormals
true,
bAutoComputeTangents
bSplitVertexForOptimalTangents
false
Initializing
RestoreDeviceObjects(
pd3dDevice
InvalidateDeviceObjects();
Creation/destruction
Create(
LPCWSTR
strFilename
LPD3DXFILEDATA
pFileData
Create(LPDIRECT3DDEVICE9
ID3DXMesh*
pInMesh,
D3DXMATERIAL*
pd3dxMaterials,
dwMaterials);
CreateMaterials(LPCWSTR
strPath,
IDirect3DDevice9
*pd3dDevice,
d3dxMtrls,
dwNumMaterials);
Destroy();
CDXUTMesh(
strName
L"
CDXUTMeshFile_Mesh"
virtual
~CDXUTMesh();
};
该类中包含的成员函数按其作用可分为6类。
第一类是构造和析构函数,函数CDXUTMesh()和~CDXUTMesh()分别是该类的构造函数和析构函数,其作用分别是进行一些初始化工作以及在类CDXUTMesh的对象被销毁时完成最后的销毁工作。
CDXUTMesh:
:
CDXUTMesh(LPCWSTRstrName)
StringCchCopy(m_strName,512,strName);
m_pMesh=NULL;
m_pMaterials=NULL;
m_pTextures=NULL;
m_bUseMaterials=TRUE;
m_pVB=NULL;
m_pIB=NULL;
m_pDecl=NULL;
m_strMaterials=NULL;
m_dwNumMaterials=0;
m_dwNumVertices=0;
m_dwNumFaces=0;
m_dwBytesPerVertex=0;
~CDXUTMesh()
Destroy();
第二类是获取网格函数,它仅包含一个函数GetMesh(),实现也非常简单,即返回类CDXUTMesh的成员变量m_pMesh。
LPD3DXMESHGetMesh(){returnm_pMesh;
}
第三类是设备恢复和丢失时所采取的操作函数,这里所包含的两个成员函数RestoreDeviceObjects()和InvalidateDeviceObjects()分别是在设备恢复和丢失时调用,用于恢复和释放相应的资源。
HRESULTCDXUTMesh:
RestoreDeviceObjects(LPDIRECT3DDEVICE9pd3dDevice)
returnS_OK;
InvalidateDeviceObjects()
SAFE_RELEASE(m_pIB);
SAFE_RELEASE(m_pVB);
SAFE_RELEASE(m_pDecl);
第四类是创建和销毁函数,这里首先重载了3个创建网格模型函数Create(),它们依次用于从指定的.x文件创建网格模型,从接口ID3DXFileData创建网格模型,从输入的网格模型中创建新的网格模型。
函数CreateMaterials()用于创建网格模型中所需的材质和纹理。
函数Destroy()用来在程序退出时销毁指定的资源。
来看第一个Create()函数的实现:
)
strPath[MAX_PATH];
LPD3DXBUFFER
pAdjacencyBuffer
NULL;
pMtrlBuffer
hr;
Cleanup
previous
mesh
if
any
Find
path
file,
convert
it
to
ANSI
(for
D3DX
API)
DXUTFindDXSDKMediaFileCch(
sizeof(strPath)
/
sizeof(WCHAR),
Load
if(FAILED(hr
D3DXLoadMeshFromXW(strPath,
D3DXMESH_MANAGED,
&
pAdjacencyBuffer,
pMtrlBuffer,
m_dwNumMaterials,
m_pMesh)))
Optimize
performance
if(
FAILED(
hr
m_pMesh->
OptimizeInplace(
D3DXMESHOPT_COMPACT
|
D3DXMESHOPT_ATTRSORT
D3DXMESHOPT_VERTEXCACHE,
(DWORD*)
pAdjacencyBuffer->
GetBufferPointer(),
NULL,
NULL)))
SAFE_RELEASE(
Set
strPath
file
WCHAR*
pLastBSlash
wcsrchr(
L'
\\'
*(pLastBSlash
+
1)
\0'
;
else
*strPath
d3dxMtrls
(D3DXMATERIAL*)
pMtrlBuffer->
GetBufferPointer();
CreateMaterials(
m_dwNumMaterials
Extract
from
decl[MAX_FVF_DECL_SIZE];
m_dwNumVertices
GetNumVertices();
m_dwNumFaces
GetNumFaces();
m_dwBytesPerVertex
GetNumBytesPerVertex();
GetIndexBuffer(
m_pIB
GetVertexBuffer(
m_pVB
GetDeclaration(
decl
pd3dDevice->
CreateVertexDeclaration(
decl,
m_pDecl
函数首先销毁旧的资源,并调用DXUTFindDXSDKMediaFileCch()通过文件名查找文件所在的路径,接着调用D3DXLoadMeshFromXW()从文件中加载网格模型。
DXUTFindDXSDKMediaFileCch()的实现分析请参阅DXUT源码分析----媒体文件查找函数。
WCHARstrPath[MAX_PATH];
LPD3DXBUFFERpAdjacencyBuffer=NULL;
LPD3DXBUFFERpMtrlBuffer=NULL;
HRESULThr;
//Cleanuppreviousmeshifany
//Findthepathforthefile,andconvertittoANSI(fortheD3DXAPI)
DXUTFindDXSDKMediaFileCch(strPath,sizeof(strPath)/sizeof(WCHAR),strFilename);
//Loadthemesh
if(FAILED(hr=D3DXLoadMeshFromXW(strPath,D3DXMESH_MANAGED,pd3dDevice,&
pAdjacencyBuffer,&
pMtrlBuffer,NULL,
&
m_dwNumMaterials,&
{
returnhr;
接着调用OptimizeInplace()对网格模型进行优化,该函数调用时第一个参数的含义如下:
D3DXMESHOPT_COMPACT—从mesh中移除没有用的顶点和索引项。
D3DXMESHOPT_ATTRSORT—根据属性给三角形排序并调整属性表,这将使DrawSubset执行更有效。
D3DXMESHOPT_VERTEXCACHE—增加顶点缓存的命中率。
//Optimizethemeshforperformance
if(FAILED(hr=m_pMesh->
D3DXMESHOPT_COMPACT|D3DXMESHOPT_ATTRSORT|D3DXMESHOPT_VERTEXCACHE,
(DWORD*)pAdjacencyBuffer->
GetBufferPointer(),NULL,NULL,NULL)))
SAFE_RELEASE(pAdjacencyBuffer);
SAFE_RELEASE(pMtrlBuffer);
接下来,函数将模型文件所在的路径存储在strPath,如果没有路径,则strPath置为NULL。
//SetstrPathtothepathofthemeshfile
WCHAR*pLastBSlash=wcsrchr(strPath,L'
);
if(pLastBSlash)
*(pLastBSlash+1)=L'
else
*strPath=L'
接下来,函数调用CreateMaterials()创建存储材质和纹理的内存,并释放邻接信息缓存和材质缓存。
D3DXMATERIAL*d3dxMtrls=(D3DXMATERIAL*)pMtrlBuffer->
hr=CreateMaterials(strPath,pd3dDevice,d3dxMtrls,m_dwNumMaterials);
最后,函数获取模型的顶点数,面数,每个顶点所占的字节大小,顶点索引缓存,顶点缓存,顶点声明,以方便以后访问。
//Extractdatafromm_pMeshforeasyaccess
m_dwNumVertices=m_pMesh->
m_dwNumFaces=m_pMesh->
m_dwBytesPerVertex=m_pMesh->
m_pMesh->
GetIndexBuffer(&
m_pIB);
GetVertexBuffer(&
m_pVB);
GetDeclaration(decl);
pd3dDevice->
CreateVertexDeclaration(decl,&
m_pDecl);
DXUT源码分析----类CDXUTMesh
(2)
函数CreateMaterials()用于创建网格模型中所需的材质和纹理,我们来看看CreateMaterials()的实现:
dwNumMaterials
Get
material
info
mesh,
get
array
materials
out
buffer.
dwNumMaterials;
>
0
Allocate
memory
textures
m_pMaterials
new
D3DMATERIAL9[m_dwNumMaterials];
==
NULL
E_OUTOFMEMORY;
m_pTextures
LPDIRECT3DBASETEXTURE9[m_dwNumMaterials];
m_strMaterials
CHAR[m_dwNumMaterials][MAX_PATH];
Copy
each
create
its
texture
for(
i=0;
i<
i++
material
m_pMaterials[i]
d3dxMtrls[i].MatD3D;
m_pMaterials[i].Ambient
m_pMaterials[i].Diffuse;
add
by
me
m_pTextures[i]
Create
a
d3dxMtrls[i].pTextureFilename
StringCchCopyA(
m_strMaterials[i],
MAX_PATH,
strTexture[MAX_PATH];
strTextureTemp[MAX_PATH];
D3DXIMAGE_INFO
ImgInfo;
First
attempt
look