由于关于DirectD3D的很多基础知识在浅墨的博客http://blog.youkuaiyun.com/zhmxy555/article/category/1091031/2上都有详细的讲解,这里我只对自己学到的东西的进行简单的讲解。
填充领接信息
绘制
经过上面几步就可以绘制出一个正方体。
这里我加载了6张纹理图片.
这个前面也讲过,要对哪个物体绘制纹理,就在那个物体之前用SetTexture();来绘制;
本章我们主要学习如何用简单的使用ID3DXMesh接口来自定义网格图形。本章将绘制一个魔方
先定义一些全局变量
LPDIRECT3DTEXTURE9 g_pTexture[6]={0}; // 纹理接口对象,用于渐进纹理的存放
ID3DXMesh *g_pMesh=NULL; //网格接口
const DWORD g_NumSubsets = 6; //网格子集数
首先我们自定义顶点信息
typedef struct MyVecter
{
float _x,_y,_z;
float _nx,_ny,_nz;
float _u,_v;
MyVecter(float x,float y,float z,
float nx,float ny,float nz,
float u,float v)
:_x(x),_y(y),_z(z),
_nx(nx),_ny(ny),_nz(nz),
_u(u),_v(v){}
static const DWORD FVF_XYZ_NORMAL_TEX1;
}*LPMYVECTER;
const DWORD MyVecter::FVF_XYZ_NORMAL_TEX1=D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1;
可以根据自己的需求来修改顶点信息
接着我们用D3DXCreateMeshFVF来创建一个空的网格对象D3DXCreateMeshFVF定义入下:
HRESULT WINAPI D3DXCreateMeshFVF(
DWORD NumFaces, // 网格所具有的面片个数
DWORD NumVertices, // 网格所具有的顶点个数
DWORD Options, // 创建网格时所使用的创建标记
DWORD FVF, // 顶点的顶点灵活格式
LPDIRECT3DDEVICE9 pDevice, // 与该网格相关的设备指针
LPD3DXMESH *ppMesh // 所创建的网格对象的指针
);
用法:
D3DXCreateMeshFVF(
12,24,D3DXMESH_MANAGED,MyVecter::FVF_XYZ_NORMAL_TEX1,
g_pD3DDevice,&g_pMesh)
接着我们来填网格的充顶点缓存
//填充顶点缓存
MyVecter* v=0;
g_pMesh->LockVertexBuffer(0,(void**)&v);
// 正面
v[0] = MyVecter(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
v[1] = MyVecter(-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 3.0f);
v[2] = MyVecter( 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 3.0f, 3.0f);
v[3] = MyVecter( 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 3.0f, 0.0f);
// 背面
v[4] = MyVecter(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
v[5] = MyVecter( 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 3.0f);
v[6] = MyVecter( 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 3.0f, 3.0f);
v[7] = MyVecter(-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 3.0f, 0.0f);
// 顶面
v[8] = MyVecter(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
v[9] = MyVecter(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 3.0f);
v[10] = MyVecter( 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 3.0f, 3.0f);
v[11] = MyVecter( 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 3.0f, 0.0f);
// 底面
v[12] = MyVecter(-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f);
v[13] = MyVecter( 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 3.0f);
v[14] = MyVecter( 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 3.0f, 3.0f);
v[15] = MyVecter(-1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 3.0f, 0.0f);
// 左面
v[16] = MyVecter(-1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
v[17] = MyVecter(-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 3.0f);
v[18] = MyVecter(-1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 3.0f, 3.0f);
v[19] = MyVecter(-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 3.0f, 0.0f);
// 右面
v[20] = MyVecter( 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
v[21] = MyVecter( 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 3.0f);
v[22] = MyVecter( 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 3.0f, 3.0f);
v[23] = MyVecter( 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 3.0f, 0.0f);
g_pMesh->UnlockVertexBuffer();
//填充索引缓存
WORD* i=0;//这里用的不是DWORD是WORD
g_pMesh->LockIndexBuffer(0,(void**)&i);
// 正面
i[0] = 0; i[1] = 1; i[2] = 2;
i[3] = 0; i[4] = 2; i[5] = 3;
// 背面
i[6] = 4; i[7] = 5; i[8] = 6;
i[9] = 4; i[10] = 6; i[11] = 7;
// 顶面
i[12] = 8; i[13] = 9; i[14] = 10;
i[15] = 8; i[16] = 10; i[17] = 11;
// 底面
i[18] = 12; i[19] = 13; i[20] = 14;
i[21] = 12; i[22] = 14; i[23] = 15;
// 左面
i[24] = 16; i[25] = 17; i[26] = 18;
i[27] = 16; i[28] = 18; i[29] = 19;
// 右面
i[30] = 20; i[31] = 21; i[32] = 22;
i[33] = 20; i[34] = 22; i[35] = 23;
g_pMesh->UnlockIndexBuffer();
填充领接信息
//填充领接信息
DWORD* attributeBuffer=0;
int isubset=0;//子集序号
g_pMesh->LockAttributeBuffer(0,&attributeBuffer);
for (int i = 0; i < 12; i++)
{
attributeBuffer[i]=isubset;
if ( ( (i+1) % 2) == 0 )
{
isubset++;
}
}
g_pMesh->UnlockAttributeBuffer();
//网格优化
std::vector<DWORD> adjacencyBuffer(g_pMesh->GetNumFaces()*3);
g_pMesh->GenerateAdjacency(0.1f,&adjacencyBuffer[0]);
HR(g_pMesh->OptimizeInplace(
//三角形单元排序生存一个属性表,移除网格无用顶点,提高顶点高速缓存的命中率
D3DXMESHOPT_ATTRSORT|D3DXMESHOPT_COMPACT|D3DXMESHOPT_VERTEXCACHE,
&adjacencyBuffer[0],
0,0,0));
绘制
//网格绘制
for (int i=0;i<g_NumSubsets;i++)
{
g_pMesh->DrawSubset(i);
}
经过上面几步就可以绘制出一个正方体。
这样看来来只有干粑粑的正方体。我们可以给他加上纹理
//纹理创建(不加EX的方法不能使用多级渐进纹理)
D3DXCreateTextureFromFile(g_pD3DDevice,L"blue.png",&g_pTexture[0]);
D3DXCreateTextureFromFile(g_pD3DDevice,L"green.png",&g_pTexture[1]);
D3DXCreateTextureFromFile(g_pD3DDevice,L"red.png",&g_pTexture[2]);
D3DXCreateTextureFromFile(g_pD3DDevice,L"yellow.png",&g_pTexture[3]);
D3DXCreateTextureFromFile(g_pD3DDevice,L"purple.png",&g_pTexture[4]);
D3DXCreateTextureFromFile(g_pD3DDevice,L"Grey.png",&g_pTexture[5]);
这里我加载了6张纹理图片.
然后有个地方要改下:
//网格绘制
for (int i=0;i<g_NumSubsets;i++)
{
g_pD3DDevice->SetTexture(0,g_pTexture[i]);
g_pMesh->DrawSubset(i);
}
这个前面也讲过,要对哪个物体绘制纹理,就在那个物体之前用SetTexture();来绘制;
效果图
对上面的总结。
1.用D3DXCreateMeshFVF()来创建一个空网格。
2.填充网格的顶点信息。
3.访问属性缓存LockAttributeBuffer()和UnlockAttributeBuffer();
4.网格优化(看需求一般都要,可以不要)
5.绘制纹理(看需求,可以不要)
6.绘制。
由于时间关系博主没详细介绍各个方法和结构,想了解的可以参考《DIRECTX.9.0.3D游戏开发编程基础》:网格(一)的内容或者看看浅墨的博客http://blog.youkuaiyun.com/zhmxy555/article/category/1091031/2,写的很好。