MD2模型格式是Quake2(雷神之锤2)中的所用到的模型格式。虽然MD2是10年前的技术了,但是作为学习逐帧动画,还是不错的。
以下是在学习使用MD2过程所犯下的一些错误。
1、数组下标计算失误。
在组织三角形数据时,采用了逐个三角形计算的方法,但是在数组下标的时候失误,导致三角形数组中的数据组织失败。错误代码如下:
for(int i = 0; i < NumTriangles; i++)
{
//Vertices 组成三角形的顶点,包含xyz坐标等
Vertices[i].x = ...
Vertices[i].x = ...
Vertices[i].x = ...
Vertices[i + 1].x = ...
Vertices[i + 1].x = ...
Vertices[i + 1].x = ...
Vertices[i + 2].x = ...
Vertices[i + 2].x = ...
Vertices[i + 2].x = ...
...
}
乍一看没什么问题,也是三个点组成一个三角形。但是由于i是代表三角形个数的,所以顶点数组的下标应该是:
Vertices[i * 3 + 0]
Vertices[i * 3 + 1]
Vertices[i * 3 + 2]
2、纹理计算失误
众所周知,D3D中的纹理坐标都是依附在顶点上的,每个顶点都有相应的坐标,在贴纹理时根据顶点上的 纹理坐标来进行纹理映射。
MD2是IdSoft的格式,卡马克使用的图形库是OpenGL。OpenGl中进行纹理映射的时候可以直接设置,并不需要非得依附到顶点上。
如果使用DX绘制模型直接使用顶点加索引的话,会导致模型上的部分纹理是扭曲的。我的修正方法是,不 使用索引,将所有的三角形表示出来,这样的话就不会出现同一个顶点的坐标他的纹理坐标却不一致的事情发生。
当然弊端就是无法重用顶点,从而导致了空间的浪费。
3、动画差值失误
MD2文件记录的是每一帧的顶点的位置。如果一帧一帧绘制的话,会造成动作的不平滑,而且会收到帧速 的影响,帧速快了动作就快,慢了动作就慢,这样的话在不同机器上他的效果可能会相差很大。
由于MD2的初衷也是按照时间在两帧之间插值,所以我在实现过程中也进行了插值。但是在插值过程中由 于对最后一帧的处理失误导致动画的结果是有跳动现象就是最后一帧没有绘制。
比如:MD2动画中的第二个动作是跑步,帧数是40 - 45帧。问题就在与最后一帧上,最后一帧并不是所有 的顶点归位,而是只是最接近初始位置。就好比钟表的秒针最后一个位置是59,而不是0。0是第一个位置,所以当绘制到最后一帧时,还要对最后一帧和第一帧进行插值。
让我找了老半天的错误基本上就这些,修正之后,可以正常显示了。
图一
图二