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);
DWORDGetFVF();
DWORDGetNumVertices();
DWORDGetNumBytesPerVertex();
DWORDGetNumFaces();
1子集和属性缓存
子集:mesh由子集构成,一个子集是网格中相同属性的三角新单元,每个子集有子集属性ID
属性缓存:三角形单元属性ID存储位置,和网格索引中三角形单元的数目相同,属性缓存项与网格索引缓存中的数据一一对应。
获得索引的办法:
HRESULTLockAttributeBuffer(DWORDFlags,DWORD**ppData);
HRESULTUnlockAttributeBuffer();
2绘制
HRESULTDrawSubset(DWORDAttribId);
3优化
对网格中的索引和顶点进行重组
4属性表
属性表经过D3DXMESHOPT_ATTRSORT标志排序后,相同属性的三角形面片的属性信息和顶点列表就会存储在连续的区域中,可以通过函数:
HRESULTGetAttributeTable(D3DXATTRIBUTERANGE*pAttribTable,DWORD*pAttribTableSize)
来获得网格中属性信息列表,属性信息列表的结构:
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;
}
相关文章推荐
- directX基础学习系列7 网格(自己创建)
- DirectX基础学习系列8 渐进网格以及外接体
- DirectX 基础学习系列6 字体
- EA&UML日拱一卒-0基础学习微信小程序(3)- 创建自己的小程序账号
- Linux基础学习系列:对于fork()函数的学习,及进程创建相关知识
- Linux基础学习系列:对于fork()函数的学习,及进程创建相关知识
- DirectX 基础学习系列5 纹理映射
- DirectX基础学习系列4 颜色和光照
- DirectX基础学习系列5 融合技术
- [转]Ultra Fractal教程系列09——学习基础技巧01——创建另一个分形
- docker学习系列(二):使用Dockerfile创建自己的镜像
- DirectX基础学习系列1
- DirectX 3D_基础之镜面效果 阴影 阴影矩阵 防止二次融合 网格 子集和属性缓存 绘制子集 网格优化 属性表 邻接信息 克隆 创建网格
- 零基础学习GitHub桌面版-6使用pages创建网站
- C++学习——第11章 创建自己的数据类型
- 零基础学习HTML5系列课程
- 深入学习jQuery选择器系列第一篇——基础选择器和层级选择器
- Python系列学习笔记(二)——基础语法规则
- Android基础学习-----创建第一个Android项目HelloWorld(二)
- 学习C语言和创建你自己编程语言在1000代码以内——第一章介绍