MD2模型結構解釋

哈... 最近正着手进行Android 3D游戏... 有些心得会陆续在后面陆续与大家分享.....

 

首先看看構成MD2的幾種基本結構

typedef struct
{
float X,Y,Z;
}tVector;

這個相信不用多說,凡是3D遊戲編程必然會有的一個結構--矢量;

typedef struct
{
float U;
float V;
}tTexCoord;

typedef struct
{
short U;
short V;
}tUVIndex;

這兩個幾乎一樣的結構,存儲了一個頂點的紋理座標--UV座標;不同之處在於一個是用於讀取MD2的,另一個是放入內存的,因此數據類型不一樣;

typedef struct
{
unsigned short MeshIndex[3];
unsigned short UVIndex[3];
}tMesh;

這個結構表示了一個多邊形,因為MD2是由Triangle構成的,所以每個多邊形需要有三個頂點.而tMesh結構僅僅存放了頂點和UV座標的索引,即需要時再到頂點列表(tVector * VertexList)和UV列表(tTexCoord * UV)查詢;

typedef struct
{
unsigned char Vertex[3];
unsigned char NormalIndex;
}tFramePoint;

這是一個頂點的結構,類似tVector;不同的是數據類型並不是float,unsigned char應該是MD2的規範,讀取時應用這種格式;

MD2模型是有動畫的,當然也就有關鍵幀了.MD2模型應該有一個總的頂點列表,存放所有幀的所有頂點,每一幀的頂點數和多邊形數都是一樣的.每一幀中都有一個頂點列表首地址,各幀的頂點列表內,頂點的順序都是相同的,因此多邊形列表(TriangleIndex)隻需要一個,當要顯示不同幀時,隻需要改變頂點列表的首地址即可顯示;UV列表也是一樣的道理;

typedef struct
{
float Scale[3];
float Translate[3];
char Name[16];
tFramePoint pFramePoint[1];
}tFrame;

這就是一幀的結構了,可以看到pFramePoint[1]即是幀內頂點列表的首地址;而Scale和Translate則用於拉伸移動變換,載入MD2文件時應當先載入一幀,再根據pFramePoint[J],Scale和Translate的關係把幀內每一個頂點數據存放到總的頂點列表內;

typedef struct
{
tTexTypes TextureType;
int Width;
int Height;
long int ScaleWidth;
long int ScaleHeight;
unsigned int TexIde;
unsigned char * Data;
unsigned char * Palette;
}tTexture;

紋理貼圖結構;重點理解的是TexIde與Data,使用gluBuild2DMidmaps()函數進行貼圖的載入;

typedef struct
{
int NumFrames;
int NumVertices;
int NumTriangles;
int NumUV;
int FrameSize;
int TexWidth,TexHeight;
int CurrentFrame;
int NextFrame;
float Interpol;
tMesh * TriIndex;
tTexCoord * UV;
tVector * VertexList;
tTexture * ModelTexture;
}tModelData;

這就是MD2文件的結構了,一開始需要重點理解的是tMesh * TriIndex,tTexCoord * UV,tVector * VertexList和tTexture * ModelTexture這四個結構:TriIndex即多邊形列表,存放了一幀的所有頂點的空間座標索引和UV座標索引,當繪製某個頂點,如第J個頂點,則根據索引值,向幀內頂點列表和UV列表查詢該點信息:

{

    ....

    tVector * VertexList=new tVector[NumFrames*NumVertices];//為頂點列表分配內存空間;

    tFrame * Frame=(tFrame *)&Buffer[OffsetFrame+FrameSize*KeyFrame];//填充某幀的結構;

    .....

    tVector * TmpVertexList=(tVector *)&VertexList[NumVertices*KeyFrame];

    glBegin(0X0004)//0X0004是OpenGL的TRIANGLE模式

    for(int J=0;J<NumTriangles;J++)

    {

        glTexCoord2fv((GLfloat *)&UV[TriIndex[J].UVIndex[2]]);

        glVertex3fv((GLfloat *)&TmpVertexList[TriIndex[J].MeshIndex[2]]);

        glTexCoord2fv((GLfloat *)&UV[TriIndex[J].UVIndex[1]]);

        glVertex3fv((GLfloat *)&TmpVertexList[TriIndex[J].MeshIndex[1]]);

        glTexCoord2fv((GLfloat *)&UV[TriIndex[J].UVIndex[0]]);

        glVertex3fv((GLfloat *)&TmpVertexList[TriIndex[J].MeshIndex[0]]);

    }

    glEnd();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值