您的位置:首页 > 其它

directX基础学习系列7 网格(自己创建)

2013-10-27 23:11 477 查看
D3DXMesh以及D3DXPMesh都是从ID3DXBaseMesh类中集成,mesh基本是对三角单元进行操作

ID3DXBaseMesh主要函数:

HRESULTDrawSubset(DWORDAttribId);

HRESULTGetIndexBuffer(LPDIRECT3DINDEXBUFFER9*ppIB);

HRESULTGetVertexBuffer(LPDIRECT3DVERTEXBUFFER9*ppVB);

HRESULTLockIndexBuffer(DWORDFlags,LPVOID*ppData);

HRESULTUnlockIndexBuffer();

HRESULTCloneMesh(DWORDOptions,CONSTD3DVERTEXELEMENT9*pDeclaration,LPDIRECT3DDEVICE9pDevice,LPD3DXMESH*ppCloneMesh);

HRESULTCloneMeshFVF(DWORDOptions,DWORDFVF,LPDIRECT3DDEVICE9pDevice,LPD3DXMESH*ppCloneMesh);

DWORDGetOptions();获得当前网格的选项

DWORDGetFVF();

DWORDGetNumVertices();

DWORDGetNumBytesPerVertex();

DWORDGetNumFaces();

1子集和属性缓存

子集:mesh由子集构成,一个子集是网格中相同属性的三角新单元,每个子集有子集属性ID

属性缓存:三角形单元属性ID存储位置,和网格索引中三角形单元的数目相同,属性缓存项与网格索引缓存中的数据一一对应。

获得索引的办法:

HRESULTLockAttributeBuffer(DWORDFlags,DWORD**ppData);

HRESULTUnlockAttributeBuffer();

2绘制

HRESULTDrawSubset(DWORDAttribId);

3优化

对网格中的索引和顶点进行重组

HRESULTOptimizeInplace(
DWORDFlags,优化标记
CONSTDWORD*pAdjacencyIn,指向未经优化的网格临街信息数组的指针
DWORD*pAdjacencyOut,指向优化后的网格临街信息数组的指针3*GetNumFaces()
DWORD*pFaceRemap,优化过程中原始面片被移动到新的面片位置GetNumFaces()
LPD3DXBUFFER*ppVertexRemap顶点被移动到新的顶点位置GetNumFaces()
);

//优化标记

typedefenumD3DXMESHOPT
{
D3DXMESHOPT_COMPACT=0x01000000,移除没用的顶点和索引
D3DXMESHOPT_ATTRSORT=0x02000000,根据属性重新排序
D3DXMESHOPT_VERTEXCACHE=0x04000000,提高顶点高速缓存的命中率
D3DXMESHOPT_STRIPREORDER=0x08000000,对索引进行重组
D3DXMESHOPT_IGNOREVERTS=0x10000000,
D3DXMESHOPT_DONOTSPLIT=0x20000000,
D3DXMESHOPT_DEVICEINDEPENDENT=0x40000000,
}D3DXMESHOPT,*LPD3DXMESHOPT;

另一个优化函数:会修改原始网格数据

HRESULTOptimize(DWORDFlags,CONST
DWORD*pAdjacencyIn,DWORD*
pAdjacencyOut,DWORD*pFaceRemap,
LPD3DXBUFFER*ppVertexRemap,LPD3DXMESH*
ppOptMesh);

4属性表

属性表经过D3DXMESHOPT_ATTRSORT标志排序后,相同属性的三角形面片的属性信息和顶点列表就会存储在连续的区域中,可以通过函数:

HRESULTGetAttributeTable(D3DXATTRIBUTERANGE*pAttribTable,DWORD*pAttribTableSize)

来获得网格中属性信息列表,属性信息列表的结构:

typedefstructD3DXATTRIBUTERANGE{
DWORDAttribId;属性ID
DWORDFaceStart;索引缓存中的其实位置3*FaceStart
DWORDFaceCount;面片数目
DWORDVertexStart;顶点缓存其实位置
DWORDVertexCount;
}D3DXATTRIBUTERANGE,*LPD3DXATTRIBUTERANGE;

属性表获取:

GetAttributeTable(0,&num);

D3DXATTRIBUTERANGEtable=newD3DXATTRIBUTERANGE[num];

GetAttributeTable(table,&num);

设置属性表:

HRESULTSetAttributeTable(CONSTD3DXATTRIBUTERANGE*
pAttribTable,DWORDcAttribTableSize);

5邻接信息

每个三角形面片有三个边,最多三个邻接信息,无效邻接信息为-1或者ULONG_MAX

邻接数组大小为GetFaceNun*3

获得邻接数据函数:

HRESULTGenerateAdjacency(FLOATEpsilon,DWORD*pAdjacency);

Epsilon:指定两个点距离多近可以算作同一个点

pAdjacency:DWORD数组

6网格顶点复制

HRESULTCloneMeshFVF(DWORDOptions,DWORDFVF,LPDIRECT3DDEVICE9pDevice,LPD3DXMESH*ppCloneMesh);

Options:创建网格副本是的可选项

FVF:灵活顶点格式

DWORDGetOptions();获得当前网格的选项

7创建网格

HRESULTD3DXCreateMesh(DWORDNumFaces,
DWORDNumVertices,DWORDOptions,
CONSTLPD3DVERTEXELEMENT9*pDeclaration,
LPDIRECT3DDEVICE9pD3DDevice,LPD3DXMESH*
ppMesh);

HRESULTD3DXCreateMeshFVF(DWORDNumFaces,
DWORDNumVertices,DWORDOptions,
DWORDFVF,LPDIRECT3DDEVICE9
pD3DDevice,LPD3DXMESH*ppMesh);

typedefstructD3DVERTEXELEMENT9{
WORDStream;
WORDOffset;
BYTEType;
BYTEMethod;
BYTEUsage;
BYTEUsageIndex;
}D3DVERTEXELEMENT9,*LPD3DVERTEXELEMENT9;


8网格创建与绘制

1创建网格对象

2将面片数据写入网格缓存

3指定每个面片所属的子集

4生成邻接信息,优化网格

5绘制网格


#include"d3dUtility.h"
#include<fstream>
#include<vector>

//
//Globals
//

IDirect3DDevice9*Device=0;

constintWidth=640;
constintHeight=480;

ID3DXMesh*Mesh=0;
constDWORDNumSubsets=3;
IDirect3DTexture9*Textures[3]={0,0,0};//textureforeachsubset

std::ofstreamOutFile;//usedtodumpmeshdatatofile

//
//Prototypes
//

voiddumpVertices(std::ofstream&outFile,ID3DXMesh*mesh);
voiddumpIndices(std::ofstream&outFile,ID3DXMesh*mesh);
voiddumpAttributeBuffer(std::ofstream&outFile,ID3DXMesh*mesh);
voiddumpAdjacencyBuffer(std::ofstream&outFile,ID3DXMesh*mesh);
voiddumpAttributeTable(std::ofstream&outFile,ID3DXMesh*mesh);

//
//ClassesandStructures
//
structVertex
{
Vertex(){}
Vertex(floatx,floaty,floatz,
floatnx,floatny,floatnz,floatu,floatv)
{
_x=x;_y=y;_z=z;
_nx=nx;_ny=ny;_nz=nz;
_u=u;_v=v;
}

float_x,_y,_z,_nx,_ny,_nz,_u,_v;

staticconstDWORDFVF;
};
constDWORDVertex::FVF=D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1;

//
//Frameworkfunctions
//
boolSetup()
{
HRESULThr=0;

//
//Wearegoingtofilltheemptymeshwiththegeometryofabox,
//soweneed12trianglesand24vetices.
//

hr=D3DXCreateMeshFVF(
12,
24,
D3DXMESH_MANAGED,
Vertex::FVF,
Device,
&Mesh);

if(FAILED(hr))
{
::MessageBox(0,"D3DXCreateMeshFVF()-FAILED",0,0);
returnfalse;
}

//
//Fillinverticesofabox
//
Vertex*v=0;
Mesh->LockVertexBuffer(0,(void**)&v);

//fillinthefrontfacevertexdata
v[0]=Vertex(-1.0f,-1.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,0.0f);
v[1]=Vertex(-1.0f,1.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,1.0f);
v[2]=Vertex(1.0f,1.0f,-1.0f,0.0f,0.0f,-1.0f,1.0f,1.0f);
v[3]=Vertex(1.0f,-1.0f,-1.0f,0.0f,0.0f,-1.0f,1.0f,0.0f);

//fillinthebackfacevertexdata
v[4]=Vertex(-1.0f,-1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f);
v[5]=Vertex(1.0f,-1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,1.0f);
v[6]=Vertex(1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,1.0f,1.0f);
v[7]=Vertex(-1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f);

//fillinthetopfacevertexdata
v[8]=Vertex(-1.0f,1.0f,-1.0f,0.0f,1.0f,0.0f,0.0f,0.0f);
v[9]=Vertex(-1.0f,1.0f,1.0f,0.0f,1.0f,0.0f,0.0f,1.0f);
v[10]=Vertex(1.0f,1.0f,1.0f,0.0f,1.0f,0.0f,1.0f,1.0f);
v[11]=Vertex(1.0f,1.0f,-1.0f,0.0f,1.0f,0.0f,1.0f,0.0f);

//fillinthebottomfacevertexdata
v[12]=Vertex(-1.0f,-1.0f,-1.0f,0.0f,-1.0f,0.0f,0.0f,0.0f);
v[13]=Vertex(1.0f,-1.0f,-1.0f,0.0f,-1.0f,0.0f,0.0f,1.0f);
v[14]=Vertex(1.0f,-1.0f,1.0f,0.0f,-1.0f,0.0f,1.0f,1.0f);
v[15]=Vertex(-1.0f,-1.0f,1.0f,0.0f,-1.0f,0.0f,1.0f,0.0f);

//fillintheleftfacevertexdata
v[16]=Vertex(-1.0f,-1.0f,1.0f,-1.0f,0.0f,0.0f,0.0f,0.0f);
v[17]=Vertex(-1.0f,1.0f,1.0f,-1.0f,0.0f,0.0f,0.0f,1.0f);
v[18]=Vertex(-1.0f,1.0f,-1.0f,-1.0f,0.0f,0.0f,1.0f,1.0f);
v[19]=Vertex(-1.0f,-1.0f,-1.0f,-1.0f,0.0f,0.0f,1.0f,0.0f);

//fillintherightfacevertexdata
v[20]=Vertex(1.0f,-1.0f,-1.0f,1.0f,0.0f,0.0f,0.0f,0.0f);
v[21]=Vertex(1.0f,1.0f,-1.0f,1.0f,0.0f,0.0f,0.0f,1.0f);
v[22]=Vertex(1.0f,1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,1.0f);
v[23]=Vertex(1.0f,-1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f);

Mesh->UnlockVertexBuffer();

//
//Definethetrianglesofthebox
//
WORD*i=0;
Mesh->LockIndexBuffer(0,(void**)&i);

//fillinthefrontfaceindexdata
i[0]=0;i[1]=1;i[2]=2;
i[3]=0;i[4]=2;i[5]=3;

//fillinthebackfaceindexdata
i[6]=4;i[7]=5;i[8]=6;
i[9]=4;i[10]=6;i[11]=7;

//fillinthetopfaceindexdata
i[12]=8;i[13]=9;i[14]=10;
i[15]=8;i[16]=10;i[17]=11;

//fillinthebottomfaceindexdata
i[18]=12;i[19]=13;i[20]=14;
i[21]=12;i[22]=14;i[23]=15;

//fillintheleftfaceindexdata
i[24]=16;i[25]=17;i[26]=18;
i[27]=16;i[28]=18;i[29]=19;

//fillintherightfaceindexdata
i[30]=20;i[31]=21;i[32]=22;
i[33]=20;i[34]=22;i[35]=23;

Mesh->UnlockIndexBuffer();

//
//Specifythesubseteachtrianglebelongsto,inthisexample
//wewillusethreesubsets,thefirsttwofacesofthecubespecified
//willbeinsubset0,thenexttwofaceswillbeinsubset1and
//thethelasttwofaceswillbeinsubset2.
//
DWORD*attributeBuffer=0;
Mesh->LockAttributeBuffer(0,&attributeBuffer);

for(inta=0;a<4;a++)
attributeBuffer[a]=0;

for(intb=4;b<8;b++)
attributeBuffer[b]=1;

for(intc=8;c<12;c++)
attributeBuffer[c]=2;

Mesh->UnlockAttributeBuffer();

//
//Optimizethemeshtogenerateanattributetable.
//

std::vector<DWORD>adjacencyBuffer(Mesh->GetNumFaces()*3);
Mesh->GenerateAdjacency(0.0f,&adjacencyBuffer[0]);

hr=Mesh->OptimizeInplace(
D3DXMESHOPT_ATTRSORT|
D3DXMESHOPT_COMPACT|
D3DXMESHOPT_VERTEXCACHE,
&adjacencyBuffer[0],
0,0,0);

//
//DumptheMeshDatatofile.
//

OutFile.open("MeshDump.txt");

dumpVertices(OutFile,Mesh);
dumpIndices(OutFile,Mesh);
dumpAttributeTable(OutFile,Mesh);
dumpAttributeBuffer(OutFile,Mesh);
dumpAdjacencyBuffer(OutFile,Mesh);

OutFile.close();

//
//Loadthetexturesandsetfilters.
//

D3DXCreateTextureFromFile(
Device,
"brick0.jpg",
&Textures[0]);

D3DXCreateTextureFromFile(
Device,
"brick1.jpg",
&Textures[1]);

D3DXCreateTextureFromFile(
Device,
"checker.jpg",
&Textures[2]);

Device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
Device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
Device->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_POINT);

//
//Disablelighting.
//

Device->SetRenderState(D3DRS_LIGHTING,false);

//
//Setcamera.
//

D3DXVECTOR3pos(0.0f,0.f,-4.0f);
D3DXVECTOR3target(0.0f,0.0f,0.0f);
D3DXVECTOR3up(0.0f,1.0f,0.0f);

D3DXMATRIXV;
D3DXMatrixLookAtLH(
&V,
&pos,
&target,
&up);

Device->SetTransform(D3DTS_VIEW,&V);

//
//Setprojectionmatrix.
//

D3DXMATRIXproj;
D3DXMatrixPerspectiveFovLH(
&proj,
D3DX_PI*0.5f,//90-degree
(float)Width/(float)Height,
1.0f,
1000.0f);
Device->SetTransform(D3DTS_PROJECTION,&proj);

returntrue;
}

voidCleanup()
{
d3d::Release<ID3DXMesh*>(Mesh);
d3d::Release<IDirect3DTexture9*>(Textures[0]);
d3d::Release<IDirect3DTexture9*>(Textures[1]);
d3d::Release<IDirect3DTexture9*>(Textures[2]);
}

boolDisplay(floattimeDelta)
{
if(Device)
{
//
//Update:Rotatethecube.
//

D3DXMATRIXxRot;
D3DXMatrixRotationX(&xRot,D3DX_PI*0.2f);

staticfloaty=0.0f;
D3DXMATRIXyRot;
D3DXMatrixRotationY(&yRot,y);
y+=timeDelta;

if(y>=6.28f)
y=0.0f;

D3DXMATRIXWorld=xRot*yRot;

Device->SetTransform(D3DTS_WORLD,&World);

//
//Render
//

Device->Clear(0,0,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0x00000000,1.0f,0);
Device->BeginScene();

for(inti=0;i<NumSubsets;i++)
{
Device->SetTexture(0,Textures[i]);
Mesh->DrawSubset(i);
}

Device->EndScene();
Device->Present(0,0,0,0);
}
returntrue;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: