Original Post
While trying to adapt Johannes Leimbach's MD2 loader from (not sure if it's related)DX8 to DX9, I've come across a couple problems. When I load up an MD2 w/out animation information, the model and texture show up perfectly. However, when I load and render it using 2 other functions written for animation, the model animations but my texture looks like it's smeared across the entire mesh. Here's the md2 with animation loader: Here's the Render function: And here's what it looks like rendered: http://wow.scback.net/render.gif I've been staring at this code and trying many things for a while now with no luck. Any help would be greatly appreciated. I know many people have problems with this tutorial, but ti's the best I could find :) If anyone knows one any better for DirectX that'd be great too. Thanks
int CLoadMD2::Load( char *filename )
{
FILE *modelfile = NULL;
char g_skins[MAX_MD2SKINS][64];
dstvert_t base_st[MAX_VERTS];
byte buffer[MAX_VERTS*4+128];
SMD2Header modelheader;
dtriangle_t tri;
daliasframe_t *out;
if( (modelfile = fopen (filename, "rb")) == NULL )
return 0;
// Read the header
fread( &modelheader, 1, sizeof(modelheader), modelfile );
modelheader.framesize = (int)&((daliasframe_t *)0)->verts[modelheader.num_xyz];
//copy some data
m_frames = modelheader.num_frames;
m_vertices = modelheader.num_xyz;
m_triangles = modelheader.num_tris;
m_index_list = new make_index_list [modelheader.num_tris];
m_frame_list = new make_frame_list [modelheader.num_frames];
for( int i = 0; i < modelheader.num_frames; i++)
m_frame_list.vertex = new make_vertex_list [modelheader.num_xyz];
//read skin information
fread( g_skins, 1, modelheader.num_skins * MAX_SKINNAME, modelfile );
// read indice of the polygon meshes
fread( base_st, 1, modelheader.num_st * sizeof(base_st[0]), modelfile );
int max_tex_u = 0, max_tex_v = 0;
for( i = 0; i < modelheader.num_tris; i++ )
{
// read vertice
fread( &tri, 1, sizeof(dtriangle_t), modelfile);
(m_index_list).a = tri.index_xyz[2];
(m_index_list).b = tri.index_xyz[1];
(m_index_list).c = tri.index_xyz[0];
// read t&u
(m_index_list).a_s = base_st[tri.index_st[2]].s;
(m_index_list).a_t = base_st[tri.index_st[2]].t;
(m_index_list).b_s = base_st[tri.index_st[1]].s;
(m_index_list).b_t = base_st[tri.index_st[1]].t;
(m_index_list).c_s = base_st[tri.index_st[0]].s;
(m_index_list).c_t = base_st[tri.index_st[0]].t;
max_tex_u = max( max_tex_u, base_st[tri.index_st[0]].s );
max_tex_u = max( max_tex_u, base_st[tri.index_st[1]].s );
max_tex_u = max( max_tex_u, base_st[tri.index_st[2]].s );
max_tex_v = max( max_tex_v, base_st[tri.index_st[0]].t );
max_tex_v = max( max_tex_v, base_st[tri.index_st[1]].t );
max_tex_v = max( max_tex_v, base_st[tri.index_st[2]].t );
}
//convert t&u to be valid
for ( i = 0; i < modelheader.num_tris; i++ )
{
m_index_list[ i ].a_s /= max_tex_u;
m_index_list[ i ].b_s /= max_tex_u;
m_index_list[ i ].c_s /= max_tex_u;
m_index_list[ i ].a_t /= max_tex_v;
m_index_list[ i ].b_t /= max_tex_v;
m_index_list[ i ].c_t /= max_tex_v;
}
Write_Error ("Animation-names for : ");
Write_Error (filename);
Write_Error ("\n\n");
// Read vertexdata from all animations
for( i = 0; i < modelheader.num_frames; i++ )
{
out = (daliasframe_t *)buffer;
fread( out, 1, modelheader.framesize, modelfile );
if (out->name)
Write_Error (out->name);
Write_Error ("\n");
for( int j = 0; j < modelheader.num_xyz; j++ )
{
(m_frame_list).vertex[j].x = out->verts[j].v[0] * out->scale[0] + out->translate[0];
(m_frame_list).vertex[j].y = out->verts[j].v[1] * out->scale[1] + out->translate[1];
(m_frame_list).vertex[j].z = out->verts[j].v[2] * out->scale[2] + out->translate[2];
}
}
fclose (modelfile);
return Init();
}
int CLoadMD2::Init()
{
// For each animation we use one SMesh
for ( int i = 0; i < GetFrameCount(); i++ )
{
MODELVERTEX pVertex;
D3DXCOLOR LightColor(1.0f, 1.0f, 1.0f, 1.0f );
for( int j = 0; j < GetTriangleCount(); j++)
{
pVertex.m_vecPos.x = m_frame_list.vertex[m_index_list[j].a].x;
pVertex.m_vecPos.y = m_frame_list.vertex[m_index_list[j].a].z;
pVertex.m_vecPos.z = m_frame_list.vertex[m_index_list[j].a].y;
pVertex.m_vecTex.x = m_index_list[j].a_s;
pVertex.m_vecTex.y = m_index_list[j].a_t;
pVertex.m_dwDiffuse = LightColor;
m_data.vertex.push_back (pVertex);
pVertex.m_vecPos.x = m_frame_list.vertex[m_index_list[j].b].x;
pVertex.m_vecPos.y = m_frame_list.vertex[m_index_list[j].b].z;
pVertex.m_vecPos.z = m_frame_list.vertex[m_index_list[j].b].y;
pVertex.m_vecTex.x = m_index_list[j].b_s;
pVertex.m_vecTex.y = m_index_list[j].b_t;
pVertex.m_dwDiffuse = LightColor;
m_data.vertex.push_back (pVertex);
pVertex.m_vecPos.x = m_frame_list.vertex[m_index_list[j].c].x;
pVertex.m_vecPos.y = m_frame_list.vertex[m_index_list[j].c].z;
pVertex.m_vecPos.z = m_frame_list.vertex[m_index_list[j].c].y;
pVertex.m_vecTex.x = m_index_list[j].c_s;
pVertex.m_vecTex.y = m_index_list[j].c_t;
pVertex.m_dwDiffuse = LightColor;
m_data.vertex.push_back (pVertex);
}
}
return 1;
}
BOOL CLoadMD2::Render(char* name , BOOL b)
{
int play=-1;
//Loop through all animation names
for (int l=0;l<m_anim.size();l++)
{
//found it ???
if (strcmp (m_anim[l].name.c_str(), name)==0)
{
if (b)
m_anim[l].cur += .01;
//m_anim[l].cur += m_anim[l].add;
//restart animation
if (m_anim[l].cur >= m_anim[l].end)
m_anim[l].cur = m_anim[l].start;
play=l;
break;
}
}
g_pDevice->SetFVF (my_vertex_description);
if (play==-1) return FALSE;
if (play>=GetFrameCount()) return FALSE;
return (SUCCEEDED(g_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST,
GetTriangleCount (),
(BYTE**)&m_data[int(m_anim[l].cur)].vertex[0],
sizeof(MODELVERTEX))));
}