|
|
今天在学习立方绘制时遇到了问题请高手指点。
绘制立方体时可以把立方体的顶点用IDirect3DVertexBuffer9写入缓冲区,然后再用IDirect3DIndexBuffer9建立顶点索引来确定绘制顺序,例如:
struct CUSTOMVERTEX
{
float x, y, z;
D3DCOLOR color; //typedef DWORD D3DCOLOR
};
#define CUSTOMVERTEX_FVF (D3DFVF_XYZ|D3DFVF_DIFFUSE)
CUSTOMVERTEX customVertex[]=
{
{-1.0f, 1.0f, -1.0f,D3DCOLOR_XRGB(255, 0, 0)}, //顶点0
{1.0f, 1.0f, -1.0f,D3DCOLOR_XRGB(255, 0, 0)}, //顶点1
{1.0f, -1.0f, -1.0f,D3DCOLOR_XRGB(255, 0, 0)}, //顶点2
{-1.0f, -1.0f, -1.0f,D3DCOLOR_XRGB(255, 0, 0)}, //顶点3
{-1.0f, 1.0f, 1.0f,D3DCOLOR_XRGB(255, 0, 0)}, //顶点4
{1.0f, 1.0f, 1.0f,D3DCOLOR_XRGB(255, 0, 0)}, //顶点5
{1.0f, -1.0f, 1.0f,D3DCOLOR_XRGB(255, 0, 0)}, //顶点6
{-1.0f, -1.0f, 1.0f,D3DCOLOR_XRGB(255, 0, 0)} //顶点7
};
BYTE* pVertexData;
//创建顶点缓冲区
if(FAILED(m_pIDirect3DDevice->CreateVertexBuffer(8 * sizeof(CUSTOMVERTEX),0,
CUSTOMVERTEX_FVF, D3DPOOL_MANAGED, &m_pVertexBuffer,NULL))){
return false;
}
//取得顶点缓冲区的指针
if(FAILED(m_pVertexBuffer->Lock(0, 0, (void**)&pVertexData, 0))){
return false;
}
//写入顶点数据到顶点缓冲区
memcpy(pVertexData, customVertex, sizeof(customVertex));
//解锁
m_pVertexBuffer->Unlock();
//创建顶点索引缓冲区
if(FAILED(m_pIDirect3DDevice->CreateIndexBuffer(36*sizeof(WORD),
0,D3DFMT_INDEX16,D3DPOOL_MANAGED,&m_pIndexBuffer,NULL))){
return false;
}
WORD* pIndexData;
if(FAILED(m_pIndexBuffer->Lock(0,0,(void**)&pIndexData, 0))){
return false;
}
//底面的个三角形
pIndexData[0]=0; pIndexData[1]=1; pIndexData[2]=2;
pIndexData[3]=0; pIndexData[4]=2; pIndexData[5]=3;
//顶面的个三角形
pIndexData[6]=4; pIndexData[7]=5; pIndexData[8]=6;
pIndexData[9]=4; pIndexData[10]=6; pIndexData[11]=7;
//左侧面的个三角形
pIndexData[12]=7; pIndexData[13]=4; pIndexData[14]=0;
pIndexData[15]=0; pIndexData[16]=7; pIndexData[17]=3;
//右侧面的个三角形
pIndexData[18]=1; pIndexData[19]=5; pIndexData[20]=6;
pIndexData[21]=1; pIndexData[22]=6; pIndexData[23]=2;
//前面的个三角形
pIndexData[30]=7; pIndexData[31]=6; pIndexData[32]=2;
pIndexData[33]=7; pIndexData[34]=3; pIndexData[35]=2;
//后面的个三角形
pIndexData[24]=4; pIndexData[25]=1; pIndexData[26]=5;
pIndexData[27]=4; pIndexData[28]=1; pIndexData[29]=0;
m_pIndexBuffer->Unlock();
但是如果绘制一个四面体,这个四面体带有法向量,这样的图形用IDirect3DIndexBuffer9索引的方式绘制好像不行。比如绘制一个四面体:
struct CUSTOMVERTEX
{
float x, y, z;
float nx, ny, nz;
};
#define CUSTOMVERTEX_FVF (D3DFVF_XYZ|D3DFVF_NORMAL)
CUSTOMVERTEX customVertex[12];
D3DXVECTOR3 v[]={
D3DXVECTOR3(5.0f, 6.0f, 5.0f), //左侧面三角形
D3DXVECTOR3(6.0f, 0.0f, 3.0f),
D3DXVECTOR3(1.0f, 0.0f, 7.0f),
D3DXVECTOR3(5.0f, 6.0f, 5.0f), //右侧面三角形
D3DXVECTOR3(10.0f, 0.0f, 8.0f),
D3DXVECTOR3(6.0f, 0.0f, 3.0f),
D3DXVECTOR3(5.0f, 6.0f, 5.0f), //背面三角形
D3DXVECTOR3(1.0f, 0.0f, 7.0f),
D3DXVECTOR3(10.0f, 0.0f, 8.0f),
D3DXVECTOR3(1.0f, 0.0f, 7.0f), //底面三角形
D3DXVECTOR3(6.0f, 0.0f, 3.0f),
D3DXVECTOR3(10.0f, 0.0f, 8.0f)
};
D3DVECTOR tmpNor;
for(int i=0;i<12;i+=3){ //逐个三角形面计算法向量
ComputeTriNormal(v,v[i+1],v[i+2],tmpNor);
for(int j=0;j<3;j++){ //每个三角形面的顶点和顶点法向量坐标
customVertex[i+j].x=v[i+j].x;
customVertex[i+j].y=v[i+j].y;
customVertex[i+j].z=v[i+j].z;
customVertex[i+j].nx=tmpNor.x;
customVertex[i+j].ny=tmpNor.y;
customVertex[i+j].nz=tmpNor.z;
}
}
BYTE* pVertexData;
//创建顶点缓冲区
if(FAILED(m_pIDirect3DDevice->CreateVertexBuffer(12* sizeof(CUSTOMVERTEX),0,
CUSTOMVERTEX_FVF, D3DPOOL_DEFAULT, &m_pVertexBuffer,NULL))){
return false;
}
//取得顶点缓冲区的指针
if(FAILED(m_pVertexBuffer->Lock(0, 0, (void**)&pVertexData, 0))){
return false;
}
//写入顶点数据到顶点缓冲区
memcpy(pVertexData, customVertex, sizeof(customVertex));
//解锁
m_pVertexBuffer->Unlock();
本来四面体只有四个顶点,但是不得不用12个点来表示,因为就算顶点的坐标一样但是这个顶点的法向量不一样。在这种情况下有没有方法能够使用索引的方法来绘制立方体?
谢谢! |
|