Jump to content
  • Advertisement
Sign in to follow this  

MD2 Animation Texture

This topic is 5062 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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:
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++ )
		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;

Here's the Render function:
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;


	g_pDevice->SetFVF (my_vertex_description);

	if (play==-1) return FALSE;
	if (play>=GetFrameCount()) return FALSE;

	return (SUCCEEDED(g_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST,
												GetTriangleCount (),

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

Share this post

Link to post
Share on other sites
You have to modify the texture coords to match how your animation is moving.

Its been awhile sense ive done a md2 model loader, ill look around and see if I can find it.

Share this post

Link to post
Share on other sites
Another thing you arent interpolating the frames. The MD2 file does NOT hold each frame of the animation(this was done to save space), but rather holds keyframes of the animation. Meaning it holds the keypoints in the animation rather then the entire thing.

This book is a bit old, and its for OpenGL but it describes how to load a MD2 file, and animate it. Even though its old, it still has some nice concepts, and is really nice for reference. "OpenGl Game Programming" by Kevin Hawkins, Dave Astle and Andre LaMothe.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!