.MD2 model rendering problems

Started by
14 comments, last by Klown9 20 years, 8 months ago
Hi, The past couple of days of have been playing around with a md2 model loading/rendering class in c++ and vb and I am getting some strange rendering problems in both cases. It seems to be leaving out some polygons. When I change the render state to points only, it appears to be rendering the points correctly and their position seems to be right and there seem to be the right amount of vertices, so I'm guessing its something to do with the order im rendering them in. I have basically followed this tutorial ( here) but I haven't used any of the texture coordinates code yet as I just wanted to get the polygons rendering right first. I hate to post a heap of code but I think the problem might be in the following.

  for(framenum = 0;framenum < m_HeaderInfo.m_numframes;framenum++)
    {
        
        for(verticenum = 0;verticenum < m_HeaderInfo.m_numvertices; verticenum++)
        {
            m_ConvertedFrames[framenum].m_vertices[verticenum].m_Position.x = (m_Frames[framenum].m_vertices[verticenum].m_vertex[0] * 
                m_Frames[framenum].m_scale[0]) + m_Frames[framenum].m_translate[0];
                
                sprintf(tmpstring,"m_ConvertedFrames[framenum].m_vertices[verticenum].m_Position.x = %f", m_ConvertedFrames[framenum].m_vertices[verticenum].m_Position.x);
               

            m_ConvertedFrames[framenum].m_vertices[verticenum].m_Position.y = (m_Frames[framenum].m_vertices[verticenum].m_vertex[1] * 
                m_Frames[framenum].m_scale[1]) + m_Frames[framenum].m_translate[1];

            m_ConvertedFrames[framenum].m_vertices[verticenum].m_Position.z = (m_Frames[framenum].m_vertices[verticenum].m_vertex[2] * 
                m_Frames[framenum].m_scale[2]) + m_Frames[framenum].m_translate[2];

        }
    }    

    int i = 0; //Vertice counter

    for(framenum = 0;framenum< m_HeaderInfo.m_numframes;framenum++)
    {
        i = 0;
        for(trianglenum = 0;trianglenum < m_HeaderInfo.m_numtriangles; trianglenum++)
        {            
            m_RenderVertices[framenum].m_vertices[i].m_Position.x = m_ConvertedFrames[framenum].m_vertices[m_index_list[trianglenum].m_a].m_Position.x;
            m_RenderVertices[framenum].m_vertices[i].m_Position.y = m_ConvertedFrames[framenum].m_vertices[m_index_list[trianglenum].m_a].m_Position.z;
            m_RenderVertices[framenum].m_vertices[i].m_Position.z = m_ConvertedFrames[framenum].m_vertices[m_index_list[trianglenum].m_a].m_Position.y;
            m_RenderVertices[framenum].m_vertices[i].m_DiffuseColor = D3DCOLOR_XRGB(255,255,255);
            sprintf(tmpstring,"m_RenderVertices[framenum].m_vertices.m_Position.x = %f"</font>, m_RenderVertices[<font color=purple>framenum</font>].m_vertices[<font color=purple>i</font>].m_Position.x);
            
            i++;
           
            m_RenderVertices[<font color=purple>framenum</font>].m_vertices[<font color=purple>i</font>].m_Position.x = m_ConvertedFrames[<font color=purple>framenum</font>].m_vertices[<font color=purple>m_index_list[trianglenum</font>].m_b].m_Position.x;
            m_RenderVertices[<font color=purple>framenum</font>].m_vertices[<font color=purple>i</font>].m_Position.y = m_ConvertedFrames[<font color=purple>framenum</font>].m_vertices[<font color=purple>m_index_list[trianglenum</font>].m_b].m_Position.z;
            m_RenderVertices[<font color=purple>framenum</font>].m_vertices[<font color=purple>i</font>].m_Position.z = m_ConvertedFrames[<font color=purple>framenum</font>].m_vertices[<font color=purple>m_index_list[trianglenum</font>].m_b].m_Position.y;
            m_RenderVertices[<font color=purple>framenum</font>].m_vertices[<font color=purple>i</font>].m_DiffuseColor = D3DCOLOR_XRGB(255,255,255);
            i++;
            
            m_RenderVertices[<font color=purple>framenum</font>].m_vertices[<font color=purple>i</font>].m_Position.x = m_ConvertedFrames[<font color=purple>framenum</font>].m_vertices[<font color=purple>m_index_list[trianglenum</font>].m_c].m_Position.x;
            m_RenderVertices[<font color=purple>framenum</font>].m_vertices[<font color=purple>i</font>].m_Position.y = m_ConvertedFrames[<font color=purple>framenum</font>].m_vertices[<font color=purple>m_index_list[trianglenum</font>].m_c].m_Position.z;
            m_RenderVertices[<font color=purple>framenum</font>].m_vertices[<font color=purple>i</font>].m_Position.z = m_ConvertedFrames[<font color=purple>framenum</font>].m_vertices[<font color=purple>m_index_list[trianglenum</font>].m_c].m_Position.y;
            m_RenderVertices[<font color=purple>framenum</font>].m_vertices[<font color=purple>i</font>].m_DiffuseColor = D3DCOLOR_XRGB(255,255,255);
        }    
    }   

</pre><!–ENDSCRIPT–>
Like I said all of the vertice data seems ok and all the header info is loading correctly so it is possibly something to do with the order the polygons are being rendered. 

And if you are interested the actual rendering code:
   <!–STARTSCRIPT–><pre class="source">
<font color=blue>void</font> CMD2::Render(<font color=blue>long</font> frame)
{   
    g_pD3DDevice-&gt;SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);
    g_pD3DDevice-&gt;SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
    g_pD3DDevice-&gt;SetVertexShader(D3DFVF_CUSTOMVERTEX);
    g_pD3DDevice-&gt;DrawPrimitiveUP(D3DPT_TRIANGLELIST, m_HeaderInfo.m_numtriangles, &m_RenderVertices[<font color=purple>frame</font>].m_vertices[<font color=purple>0</font>], <font color=blue>sizeof</font>(CVertex));
  
}
</pre><!–ENDSCRIPT–>

m_ConvertedFrames is the vertice data after the scaling/translating from the compressed format has been made.
m_RenderedVertices is the final vertex data to be rendered. Slightly dodgy variable names but its fairly unplanned <img src="smile.gif" width=15 height=15 align=middle>

I have searched these forums and it doesn't seem like anyone else has had this problem as far as I could see. I have looked at other MD2 loading code and the &#111;nly thing that is different from what I can see is that some of the other code uses the glcommands which i'm not.

Any help is greatly appreciated. If you require any more info please let me know.

Thanks,
Harley.   


<a href="http://www.geocities.com/klowned999">BreakoutX</a>

<SPAN CLASS=editedby>[edited by - klown9 &#111;n August 16, 2003 8:19:46 AM]</SPAN>

<SPAN CLASS=editedby>[edited by - klown9 &#111;n August 16, 2003 8:25:45 AM]</SPAN>

<SPAN CLASS=editedby>[edited by - klown9 &#111;n August 16, 2003 8:34:28 AM]</SPAN>   
Advertisement
I have downloaded some time ago the MD2 file format. I code in Visualbasic, so I can''t help you with source code, but i also had some problems rendering Md2 animation.

I have created an array of vertex, based on the information inside the md2 file, then render this.

Also, you might try to set up a blank texture for your geometry,
especially if you don''t handle texturecoordinates.
I also had this problem, because my mesh was black, and I did not see the model, although it was there.

Oh, and try to clean up your code, look for either a small mistake, or rewrite the code entirely. (i had to rewrite myself)

ANyiway, for further info, try to be more specific.
"Find the path, follow the Master... Follow the master, understand the master... Overcome the master !"
I am currently having this problem (Im using VC++ and DX8.1).
I used the turorial from gametutorials.com, i used the MD2 loading and animation tutorial.

Since all of the tutorials there are in OpenGL, i convertd it to direct3d. no matter what i tried i get the same problem as you - a 3d md2 model with incorrect polygon drawing.
i tried disabling culling, CW, CCW, triangle lists, strips, fans, and went back to the code to figure out what could be wrong.

Sadly, I cant see anything wrong.
Im afraid that I will have to look into the format of the MD2 file to narrow down the problem''s source.
Dark_Guy,
I dont suppose you have some code for vb do you? I am also coding this in VB with exactly the same rendering problems (Im making a simple viewer in VB just for learning purposes and making a class in c++ for the game im currently working on)

Sorry I cant really be more specific other than it looks like its drawing them in the wrong order. If i change renderstate to solid polygons are missing, but also it looks like some polygon's vertices are joined to others it shouldn't (in either renderstate). If you would like a screen shot just let me know and I will put one on my site (unless it can be done in the forums?)

GekkoCube - hehe at least someone else IS having the same troubles as me. I have looked at about 3 different tuts on this and cant figure out what im doing wrong.


[edited by - klown9 on August 16, 2003 8:10:29 PM]
Dark_Guy,
Just curious but what would be the purpose of setting a blank texture for geometry when im not using textures. In fact i would be happy just to get the wireframe rendering properly! Do the vertices need it?
This wasn''t intended as a flame by the way.

BTW I just redid the code based on another md2 loader I downloaded from somewhere (cant remember, just found it on my hdd) and STILL get the same results. Its driving me nuts.

Thanks
Harley


BreakoutX
Klown9, why dont u use indexed primitives?

Your first code will load the vertexbuffers of each frame.

next copy the indices into a index buffer, heres my code
   		for(j=0; j < currentFrame->numFaces; j++)		{						currentFrame->pFaces[j].vertIndex[0] = m_pTriangles[j].vertexIndices[0];			currentFrame->pFaces[j].vertIndex[1] = m_pTriangles[j].vertexIndices[1];			currentFrame->pFaces[j].vertIndex[2] = m_pTriangles[j].vertexIndices[2]; // vertex indices			currentFrame->pTexFaces[j].coordIndex[0] = m_pTriangles[j].textureIndices[0];			currentFrame->pTexFaces[j].coordIndex[1] = m_pTriangles[j].textureIndices[1];			currentFrame->pTexFaces[j].coordIndex[2] = m_pTriangles[j].textureIndices[2]; // tex coord indices		}


To render this u have to render each face individually, unless u change the tex coord indices so they represent the tex coords of the vertices in the index buffer.
Or in D3D u can assign the texcoords to the vertices (in the MD2 the texcoords are stored only for frame 0 so you'll have to copy them for the other frames). If u do this then animation will be just vertex blending between 2 VBs





Death to the gaming industry! Long live games. /*ilici*/

[edited by - Ilici on August 17, 2003 5:33:38 AM]
Ilici,
Thanks for the suggestion but im not too sure it will fix my problem however (i could be wrong, im certainly no expert here)
Im just using the DrawPrimitiveUP function for simplicity and then once thats working i will look at optimisations. I have tried looping through each triangle in the frame and calling DrawPrimitiveUP for each triangle (slooooooow hehe) but that didn't make a difference.

I know im asking a lot here, but is someone able to maybe explain the steps involved in loading the models? I think maybe im getting confused with the triangle index lists. Or maybe im missing a step or something. I'm sure that my code matches the others ive looked at but I must be missing something. Bah I feel so frustated and stupid. 3 tuts and I still cant get it!!!
Thanks for listening to me whinge,
Harley.

[edited by - klown9 on August 17, 2003 6:20:57 AM]
IIRC, md2 stores the triangles as indices into the vertex-list, so if you just use indexed primitives, you should be alright.
Until you get to texturing, once there you''ll have to duplicate vertices that has more than one set of texture coordinates, but that''s later.

ok, i''ll post the entire MD2 class so u can get an ideea about the loading (i actually modified the MD2 loading tutorial on gametutorials)

But, about the MD2 format
Each frame contains the vertices, the vertex indices and the tex coord indices. Only the first frame contains the tex coords.

Loading is quite easy (as in the MD2 tutorial, i first load the data with MD2 format structures so it''s easyer, and then convert them to my structures, which are very similar to the ones in the tutorial)
So:
1. Load the header
	fread(&m_Header, 1, sizeof(tMd2Header), fp);	if(m_Header.version != 8)	{		lprintf("Invalid file format (Version not 8): %s!", strFileName);		return SYS_ERR;	}

2. Load the skins, tex coords, indices and vertices
	unsigned char buffer[MD2_MAX_FRAMESIZE];	m_pSkins     = new tMd2Skin [m_Header.numSkins];	m_pTexCoords = new tMd2TexCoord [m_Header.numTexCoords];	m_pTriangles = new tMd2Face [m_Header.numTriangles];	m_pFrames    = new tMd2Frame [m_Header.numFrames];	if (!m_pSkins || !m_pTexCoords || !m_pTriangles || !m_pFrames)	{		lprintf("ERROR: Cannot allocate memory for model\n");		return SYS_ERR;	}	fseek(fp, m_Header.offsetSkins, SEEK_SET);		fread(m_pSkins, sizeof(tMd2Skin), m_Header.numSkins, fp);		fseek(fp, m_Header.offsetTexCoords, SEEK_SET);	fread(m_pTexCoords, sizeof(tMd2TexCoord), m_Header.numTexCoords, fp);	fseek(fp, m_Header.offsetTriangles, SEEK_SET);	fread(m_pTriangles, sizeof(tMd2Face), m_Header.numTriangles, fp);				fseek(fp, m_Header.offsetFrames, SEEK_SET);	for (i = 0; i < m_Header.numFrames; i++)	{		tMd2AliasFrame *pFrame = (tMd2AliasFrame *) buffer;		m_pFrames[i].pVertices = NULL;		m_pFrames[i].pVertices =	new tMd2Triangle [m_Header.numVertices];		if (!m_pFrames[i].pVertices) 		{			lprintf("ERROR: Cannot allocate memory for model\n");			return SYS_ERR;		}		fread(pFrame, 1, m_Header.frameSize, fp);		strcpy(m_pFrames[i].strName, pFrame->name);				tMd2Triangle *pVertices = m_pFrames[i].pVertices;		for (int j=0; j < m_Header.numVertices; j++)		{			pVertices[j].vertex[0] = pFrame->aliasVertices[j].vertex[0] * pFrame->scale[0] + pFrame->translate[0];			pVertices[j].vertex[2] = -1 * (pFrame->aliasVertices[j].vertex[1] * pFrame->scale[1] + pFrame->translate[1]);			pVertices[j].vertex[1] = pFrame->aliasVertices[j].vertex[2] * pFrame->scale[2] + pFrame->translate[2];		}	}


3. Parse the anims
	memset(pModel, 0, sizeof(t3DModel));		pModel->numObjects = m_Header.numFrames;	tAnimationInfo animation;	string strLastName = "";	for(i = 0; i < pModel->numObjects; i++)	{		string strName  = m_pFrames.strName;<br>		int frameNum = 0;<br>		<br>		for(j = 0; j &lt; strName.length(); j++)<br>		{<br>			if( isdigit(strName[j]) && j &gt;= strName.length() - 2)<br>			{<br>				frameNum = atoi(&strName[j]);<br>				strName.erase(j, strName.length() - j);<br>				for (int k = 0; k &lt; strName.size(); k++) strName[k] = tolower(strName[k]);<br>				break;<br>			}<br>		}<br><br>		if(strName != strLastName || i == pModel-&gt;numObjects - 1)<br>		{<br>			if(strLastName != "</font>")<br>			{<br>				strcpy(animation.strName, strLastName.c_str());<br>				animation.endFrame = i - 1;				<br>				pModel-&gt;pAnimations.push_back(animation);<br>				memset(&animation, 0, <font color=blue>sizeof</font>(tAnimationInfo));<br>				<br>				pModel-&gt;numOfAnimations++;<br>			}<br><br>			animation.startFrame = frameNum - 1 + i;<br>		}<br>		strLastName = strName;<br>	}<br></pre><!–ENDSCRIPT–><br><br>4. Convert the structures to the app''s structures<br>   <!–STARTSCRIPT–><pre class="source"><br>	Model.numObjects = pModel-&gt;numObjects;<br>	Model.numMaterials = pModel-&gt;numMaterials;<br><br>	Model.pObjects = <font color=blue>new</font> t3DObject[<font color=purple>Model.numObjects</font>];<br><br>	<font color=blue>for</font> (i = 0; i &lt; pModel-&gt;numObjects; i++)<br>	{<br>		t3DObject* currentFrame = &Model.pObjects[<font color=purple>i</font>];<br><br>		currentFrame-&gt;numVerts     = m_Header.numVertices;<br>		currentFrame-&gt;numTexCoords = m_Header.numTexCoords;<br>		currentFrame-&gt;numFaces     = m_Header.numTriangles;<br><br>		currentFrame-&gt;pVerts    = <font color=blue>new</font> CVector3 [<font color=purple>currentFrame-&gt;numVerts</font>];<br>		<font color=blue>if</font> (!currentFrame-&gt;pVerts)<br>		{<br>			lprintf(<font color=darkred>"ERROR: Cannot allocate memory for model\n"</font>);<br>			<font color=blue>return</font> SYS_ERR;<br>		}<br><br>		<font color=blue>for</font> (j=0; j &lt; currentFrame-&gt;numVerts; j++)<br>		{<br>			currentFrame-&gt;pVerts[<font color=purple>j</font>].x = m_pFrames[<font color=purple>i</font>].pVertices[<font color=purple>j</font>].vertex[<font color=purple>0</font>];<br>			currentFrame-&gt;pVerts[<font color=purple>j</font>].y = m_pFrames[<font color=purple>i</font>].pVertices[<font color=purple>j</font>].vertex[<font color=purple>1</font>];<br>			currentFrame-&gt;pVerts[<font color=purple>j</font>].z = m_pFrames[<font color=purple>i</font>].pVertices[<font color=purple>j</font>].vertex[<font color=purple>2</font>];<br>		}<br><br>		<font color=blue>delete</font> [] m_pFrames[<font color=purple>i</font>].pVertices;<br>		m_pFrames[<font color=purple>i</font>].pVertices = NULL;<br>		<br>		currentFrame-&gt;pFaces    = <font color=blue>new</font> tFace [<font color=purple>currentFrame-&gt;numFaces</font>];<br>		currentFrame-&gt;pTexFaces = <font color=blue>new</font> tTexFace [<font color=purple> currentFrame-&gt;numFaces</font>];<br>		<font color=blue>for</font>(j=0; j &lt; currentFrame-&gt;numFaces; j++)<br>		{<br>			<br>			currentFrame-&gt;pFaces[<font color=purple>j</font>].vertIndex[<font color=purple>0</font>] = m_pTriangles[<font color=purple>j</font>].vertexIndices[<font color=purple>0</font>];<br>			currentFrame-&gt;pFaces[<font color=purple>j</font>].vertIndex[<font color=purple>1</font>] = m_pTriangles[<font color=purple>j</font>].vertexIndices[<font color=purple>1</font>];<br>			currentFrame-&gt;pFaces[<font color=purple>j</font>].vertIndex[<font color=purple>2</font>] = m_pTriangles[<font color=purple>j</font>].vertexIndices[<font color=purple>2</font>];<br><br>			currentFrame-&gt;pTexFaces[<font color=purple>j</font>].coordIndex[<font color=purple>0</font>] = m_pTriangles[<font color=purple>j</font>].textureIndices[<font color=purple>0</font>];<br>			currentFrame-&gt;pTexFaces[<font color=purple>j</font>].coordIndex[<font color=purple>1</font>] = m_pTriangles[<font color=purple>j</font>].textureIndices[<font color=purple>1</font>];<br>			currentFrame-&gt;pTexFaces[<font color=purple>j</font>].coordIndex[<font color=purple>2</font>] = m_pTriangles[<font color=purple>j</font>].textureIndices[<font color=purple>2</font>];<br>		}<br><br>		<font color=blue>if</font>(i &gt; 0)<br>		{			<br>			<font color=blue>continue</font>;	<br>		}<br><br>		currentFrame-&gt;pTexCoords = <font color=blue>new</font> CVector2 [<font color=purple>currentFrame-&gt;numTexCoords</font>];<br>		<font color=blue>for</font>(j = 0; j &lt; currentFrame-&gt;numTexCoords; j++)<br>		{<br>			currentFrame-&gt;pTexCoords[<font color=purple>j</font>].x = (<font color=blue>float</font>)m_pTexCoords[<font color=purple>j</font>].u / <font color=blue>float</font>(m_Header.skinWidth);<br>			currentFrame-&gt;pTexCoords[<font color=purple>j</font>].y = 1.0f - (<font color=blue>float</font>)m_pTexCoords[<font color=purple>j</font>].v / <font color=blue>float</font>(m_Header.skinHeight);<br>		}		<br>	}<br><br>	fclose(fp);						<font color=gray>// Close the current file pointer<br></font><br></pre><!–ENDSCRIPT–><br>5. Free temp stuff<br>   <!–STARTSCRIPT–><pre class="source"><br>	<font color=blue>int</font> last = strlen(strFileName) - 1;<br>	<br>	strFileName[<font color=purple>last    </font>] = ''p'';<br>	strFileName[<font color=purple>last - 1</font>] = ''m'';<br>	strFileName[<font color=purple>last - 2</font>] = ''b'';<br><br>	<font color=blue>if</font> (tex.LoadFromFile(strFileName)) <font color=blue>return</font> SYS_ERR;<br><br>	<font color=blue>if</font>(m_pSkins)	 <font color=blue>delete</font> [] m_pSkins;		<br>	<font color=blue>if</font>(m_pTexCoords) <font color=blue>delete</font> m_pTexCoords;		<br>	<font color=blue>if</font>(m_pTriangles) <font color=blue>delete</font> m_pTriangles;		<br>	<font color=blue>if</font>(m_pFrames)	 <font color=blue>delete</font> m_pFrames;			<br><br>	m_pSkins		= NULL;<br>	m_pTexCoords	= NULL;<br>	m_pTriangles	= NULL;<br>	m_pFrames		= NULL;<br><br>	<font color=blue>return</font> SYS_OK;<br></pre><!–ENDSCRIPT–><br><br>The rendering uses GL so u have to convert to D3D:<br>   <!–STARTSCRIPT–><pre class="source"><br><font color=blue>void</font> CModelMD2::Render()<br>{<br>	tAnim3DModel* pModel = &Model;<br>	<font color=blue>if</font>(pModel-&gt;numObjects &lt;= 0) <font color=blue>return</font>;<br><br>	tAnimationInfo *pAnim = &(pModel-&gt;pAnimations[<font color=purple>pModel-&gt;currentAnim</font>]);<br><br>	<font color=blue>int</font> nextFrame; <br><br>	<font color=blue>if</font>(pModel-&gt;currentFrame == pAnim-&gt;endFrame) <br>	{<br>		<font color=blue>if</font> (loopAnim)<br>		{<br>			nextFrame = pAnim-&gt;startFrame;<br>		}<br>		<font color=blue>else</font><br>		{<br>			nextFrame = pAnim-&gt;endFrame;<br>		}<br>	}<br>	<font color=blue>else</font> <br>	{<br>		nextFrame = pModel-&gt;currentFrame + 1;<br>	}<br><br>	t3DObject *pFrame =		 &pModel-&gt;pObjects[<font color=purple>pModel-&gt;currentFrame</font>];<br>	t3DObject *pNextFrame =  &pModel-&gt;pObjects[<font color=purple>nextFrame</font>];<br>	t3DObject *pFirstFrame = &pModel-&gt;pObjects[<font color=purple>0</font>];<br><br>	CVector3 vPoint1;<br>	CVector3 vPoint2;<br>	<br>	glFrontFace(GL_CW);<br>	glPushMatrix();<br>	glTranslatef(vPos.x, vPos.y + 32, vPos.z);<br>	glRotatef(ang, 0, 1, 0);<br><br>	glDisable(GL_LIGHTING);<br><br>	glEnable(GL_TEXTURE_2D);<br>	glColor3f(1.0f, 1.0f, 1.0f);<br>	glBindTexture(GL_TEXTURE_2D, tex.texnum);<br><br>	glBegin(GL_TRIANGLES);<br>		<font color=blue>for</font>(<font color=blue>int</font> j = 0; j &lt; pFrame-&gt;numFaces; j++)<br>		{<br>			<font color=blue>for</font>(<font color=blue>int</font> whichVertex = 0; whichVertex &lt; 3; whichVertex++)<br>			{<br>				<font color=blue>int</font> vertIndex = pFirstFrame-&gt;pFaces[<font color=purple>j</font>].vertIndex[<font color=purple>whichVertex</font>];<br>				<font color=blue>int</font> texIndex  = pFirstFrame-&gt;pTexFaces[<font color=purple>j</font>].coordIndex[<font color=purple>whichVertex</font>];<br><br>				<font color=blue>float</font> f = t; <font color=gray>//(1 - cos(t * PI)) / 2	;<br></font><br><br>				vPoint1 = pFrame-&gt;pVerts[<font color=purple> vertIndex </font>];<br>				vPoint2 = pNextFrame-&gt;pVerts[<font color=purple> vertIndex </font>];<br><br>				glTexCoord2fv((<font color=blue>float</font> *)&pFirstFrame-&gt;pTexCoords[<font color=purple> texIndex </font>]);<br>				glVertex3fv((<font color=blue>float</font> *)&(vPoint1 + (vPoint2 - vPoint1) * f)); <br>			}<br>		}<br>	glEnd();	<br><br>	glEnable(GL_LIGHTING);<br>	<br>	glPopMatrix();<br>	glFrontFace(GL_CCW);<br><br>}<br></pre><!–ENDSCRIPT–><br><br>To do it in D3D u have to assign the tex coords to each of the verts: loop across the texcoord indices and assign them to the verices. <br><br>   <!–STARTSCRIPT–><pre class="source"><br>  <font color=blue>for</font> (i = 0; i &lt; Model.NumObjects; i++) <font color=gray>// for each object<br></font><br>  {<br>    pObj = &Mode.pObjects[<font color=purple>i</font>]; <font color=gray>//obj pointer<br></font><br>    <font color=blue>for</font>(<font color=blue>int</font> j = 0; j &lt; pObj-&gt;numFaces; j++)<br>    {<br>	<font color=blue>for</font>(<font color=blue>int</font> whichVertex = 0; whichVertex &lt; 3; whichVertex++)<br>        {<br>            <font color=gray>//now assign the tex coord to the vertex<br></font><br>         	<font color=blue>int</font> vertIndex = pFirstFrame-&gt;pFaces[<font color=purple>j</font>].vertIndex[<font color=purple>whichVertex</font>];<br>            <font color=gray>// pFirstFrame is a pointer to the first frame obj<br></font><br>            <font color=blue>int</font> texIndex  = pFirstFrame-&gt;pTexFaces[<font color=purple>j</font>].coordIndex[<font color=purple>whichVertex</font>];<br>            <font color=gray>//in the D3DCustomVertex u have to put the u and v coords<br></font><br><font color=gray>/* Start: This is code for D3D (pVertices is a D3DCUSTOMVERTEX array */</font><br>            pObject-&gt;pVertices[<font color=purple>vertIndex</font>].u = pFirstFrame-&gt;pTexCoords[<font color=purple>texindex</font>].x;<br>            pObject-&gt;pVertices[<font color=purple>vertIndex</font>].v = pFirstFrame-&gt;pTexCoords[<font color=purple>texindex</font>].y; <font color=gray>// <br></font><br><font color=gray>/*end code for d3d*/</font><br>         }<br>      }<br></pre><!–ENDSCRIPT–><br><br>the entire source for MD2.cpp:<br>   <!–STARTSCRIPT–><pre class="source"><br><br><font color=green>#include</font> <font color=darkred>"stdafx.h"</font><br><font color=green>#include</font> <font color=darkred>"Md2.h"</font><br><font color=green>#include</font> <font color=darkred>"log.h"</font><br><font color=green>#include</font> <font color=darkred>"opengl.h"</font><br><font color=green>#include</font> &lt;string&gt;<br><font color=green>#include</font> <font color=darkred>"3dm.h"</font><br><br><font color=blue>struct</font> tMd2Header<br>{ <br>   <font color=blue>int</font> magic;					<font color=gray>// This is used to identify the file<br></font><br>   <font color=blue>int</font> version;					<font color=gray>// The version number of the file (Must be 8)<br></font><br>   <font color=blue>int</font> skinWidth;				<font color=gray>// The skin width in pixels<br></font><br>   <font color=blue>int</font> skinHeight;				<font color=gray>// The skin height in pixels<br></font><br>   <font color=blue>int</font> frameSize;				<font color=gray>// The size in bytes the frames are<br></font><br>   <font color=blue>int</font> numSkins;				<font color=gray>// The number of skins associated with the model<br></font><br>   <font color=blue>int</font> numVertices;				<font color=gray>// The number of vertices (constant for each frame)<br></font><br>   <font color=blue>int</font> numTexCoords;			<font color=gray>// The number of texture coordinates<br></font><br>   <font color=blue>int</font> numTriangles;			<font color=gray>// The number of faces (polygons)<br></font><br>   <font color=blue>int</font> numGlCommands;			<font color=gray>// The number of gl commands<br></font><br>   <font color=blue>int</font> numFrames;				<font color=gray>// The number of animation frames<br></font><br>   <font color=blue>int</font> offsetSkins;				<font color=gray>// The offset in the file for the skin data<br></font><br>   <font color=blue>int</font> offsetTexCoords;			<font color=gray>// The offset in the file for the texture data<br></font><br>   <font color=blue>int</font> offsetTriangles;			<font color=gray>// The offset in the file for the face data<br></font><br>   <font color=blue>int</font> offsetFrames;			<font color=gray>// The offset in the file for the frames data<br></font><br>   <font color=blue>int</font> offsetGlCommands;		<font color=gray>// The offset in the file for the gl commands data<br></font><br>   <font color=blue>int</font> offsetEnd;				<font color=gray>// The end of the file offset<br></font><br>};<br><br><br><font color=blue>struct</font> tMd2AliasTriangle<br>{<br>   byte vertex[<font color=purple>3</font>];<br>   byte lightNormalIndex;<br>};<br><br><font color=blue>struct</font> tMd2Triangle<br>{<br>   <font color=blue>float</font> vertex[<font color=purple>3</font>];<br>   <font color=blue>float</font> normal[<font color=purple>3</font>];<br>};<br><br><font color=blue>struct</font> tMd2Face<br>{<br>   <font color=blue>short</font> vertexIndices[<font color=purple>3</font>];<br>   <font color=blue>short</font> textureIndices[<font color=purple>3</font>];<br>};<br><br><font color=blue>struct</font> tMd2TexCoord<br>{<br>   <font color=blue>short</font> u, v;<br>};<br><br><font color=blue>struct</font> tMd2AliasFrame<br>{<br>   <font color=blue>float</font> scale[<font color=purple>3</font>];<br>   <font color=blue>float</font> translate[<font color=purple>3</font>];<br>   <font color=blue>char</font> name[<font color=purple>16</font>];<br>   tMd2AliasTriangle aliasVertices[<font color=purple>1</font>];<br>};<br><br><font color=blue>struct</font> tMd2Frame<br>{<br>   <font color=blue>char</font> strName[<font color=purple>16</font>];<br>   tMd2Triangle *pVertices;<br>};<br><br><font color=blue>typedef</font> <font color=blue>char</font> tMd2Skin[<font color=purple>64</font>];<br><br><font color=blue>void</font> CModelMD2::Render()<br>{<br>	tAnim3DModel* pModel = &Model;<br>	<font color=blue>if</font>(pModel-&gt;numObjects &lt;= 0) <font color=blue>return</font>;<br><br>	tAnimationInfo *pAnim = &(pModel-&gt;pAnimations[<font color=purple>pModel-&gt;currentAnim</font>]);<br><br>	<font color=blue>int</font> nextFrame; <br><br>	<font color=blue>if</font>(pModel-&gt;currentFrame == pAnim-&gt;endFrame) <br>	{<br>		<font color=blue>if</font> (loopAnim)<br>		{<br>			nextFrame = pAnim-&gt;startFrame;<br>		}<br>		<font color=blue>else</font><br>		{<br>			nextFrame = pAnim-&gt;endFrame;<br>		}<br>	}<br>	<font color=blue>else</font> <br>	{<br>		nextFrame = pModel-&gt;currentFrame + 1;<br>	}<br><br>	t3DObject *pFrame =		 &pModel-&gt;pObjects[<font color=purple>pModel-&gt;currentFrame</font>];<br>	t3DObject *pNextFrame =  &pModel-&gt;pObjects[<font color=purple>nextFrame</font>];<br>	t3DObject *pFirstFrame = &pModel-&gt;pObjects[<font color=purple>0</font>];<br><br>	CVector3 vPoint1;<br>	CVector3 vPoint2;<br>	<br>	glFrontFace(GL_CW);<br>	glPushMatrix();<br>	glTranslatef(vPos.x, vPos.y + 32, vPos.z);<br>	glRotatef(ang, 0, 1, 0);<br><br>	glDisable(GL_LIGHTING);<br><br>	glEnable(GL_TEXTURE_2D);<br>	glColor3f(1.0f, 1.0f, 1.0f);<br>	glBindTexture(GL_TEXTURE_2D, tex.texnum);<br><br>	glBegin(GL_TRIANGLES);<br>		<font color=blue>for</font>(<font color=blue>int</font> j = 0; j &lt; pFrame-&gt;numFaces; j++)<br>		{<br>			<font color=blue>for</font>(<font color=blue>int</font> whichVertex = 0; whichVertex &lt; 3; whichVertex++)<br>			{<br>				<font color=blue>int</font> vertIndex = pFirstFrame-&gt;pFaces[<font color=purple>j</font>].vertIndex[<font color=purple>whichVertex</font>];<br>				<font color=blue>int</font> texIndex  = pFirstFrame-&gt;pTexFaces[<font color=purple>j</font>].coordIndex[<font color=purple>whichVertex</font>];<br><br>				<font color=blue>float</font> f = t; <font color=gray>//(1 - cos(t * PI)) / 2	;<br></font><br><br>				vPoint1 = pFrame-&gt;pVerts[<font color=purple> vertIndex </font>];<br>				vPoint2 = pNextFrame-&gt;pVerts[<font color=purple> vertIndex </font>];<br><br>				glTexCoord2fv((<font color=blue>float</font> *)&pFirstFrame-&gt;pTexCoords[<font color=purple> texIndex </font>]);<br>				glVertex3fv((<font color=blue>float</font> *)&(vPoint1 + (vPoint2 - vPoint1) * f)); <br>			}<br>		}<br>	glEnd();	<br><br>	glEnable(GL_LIGHTING);<br>	<br>	glPopMatrix();<br>	glFrontFace(GL_CCW);<br><br>}<br><br><font color=blue>void</font> CModelMD2::SetPosition(CVector3 v)<br>{<br>	vPos = v;<br>}<br><br><font color=blue>void</font> CModelMD2::SetRotation(<font color=blue>float</font> a)<br>{<br>	ang = a;<br>}<br><br>CModelMD2::CModelMD2()<br>{<br>	t = 0.0f;	<br>	loopAnim = <font color=blue>true</font>;<br>}<br><br><font color=blue>void</font> CModelMD2::Destroy()<br>{<br>	DestroyModel(&Model);<br>}<br><br><font color=blue>void</font> CModelMD2::SetAnimation(<font color=blue>int</font> anim)<br>{<br>	<font color=blue>char</font> aName[<font color=purple>255</font>];<br><br>	<font color=blue>switch</font> (anim)<br>	{<br>		<font color=blue>case</font> MD2_ANIM_STAND:  strcpy(aName, <font color=darkred><font color=darkred>"stand"</font></font>);  loopAnim = <font color=blue>true</font>; <font color=blue>break</font>;<br>		<font color=blue>case</font> MD2_ANIM_WALK:   strcpy(aName, <font color=darkred><font color=darkred>"run"</font></font>);    loopAnim = <font color=blue>true</font>; <font color=blue>break</font>;<br>		<font color=blue>case</font> MD2_ANIM_DEATH1: strcpy(aName, <font color=darkred><font color=darkred>"death1"</font></font>); loopAnim = <font color=blue>false</font>; <font color=blue>break</font>;<br>		<font color=blue>case</font> MD2_ANIM_DEATH2: strcpy(aName, <font color=darkred><font color=darkred>"death2"</font></font>); loopAnim = <font color=blue>false</font>; <font color=blue>break</font>;<br>		<font color=blue>case</font> MD2_ANIM_DEATH3: strcpy(aName, <font color=darkred><font color=darkred>"death3"</font></font>); loopAnim = <font color=blue>false</font>; <font color=blue>break</font>;<br>	}<br><br>	<font color=blue>for</font> (<font color=blue>int</font> i = 0; i &lt; Model.pAnimations.size(); i++)<br>	{<br>		<font color=blue>if</font> (strcmp(Model.pAnimations[<font color=purple>i</font>].strName, aName) == 0)<br>		{<br>			Model.currentFrame = Model.pAnimations[<font color=purple>i</font>].startFrame;<br>			Model.currentAnim = i;<br>			<font color=blue>return</font>;<br>		}<br>	}<br>}<br><br><font color=blue>int</font> CModelMD2::GetAnimation()<br>{<br>	<font color=blue>char</font> str[<font color=purple>255</font>];<br>	strcpy(str, Model.pAnimations[<font color=purple>Model.currentAnim</font>].strName);<br>	<br>	<font color=blue>if</font> (strcmp(str, <font color=darkred><font color=darkred>"stand"</font></font>) == 0)  <font color=blue>return</font> MD2_ANIM_STAND;<br>	<font color=blue>if</font> (strcmp(str, <font color=darkred><font color=darkred>"run"</font></font>) == 0)    <font color=blue>return</font> MD2_ANIM_WALK;<br>	<font color=blue>if</font> (strcmp(str, <font color=darkred><font color=darkred>"death1"</font></font>) == 0) <font color=blue>return</font> MD2_ANIM_DEATH1;<br>	<font color=blue>if</font> (strcmp(str, <font color=darkred><font color=darkred>"death2"</font></font>) == 0) <font color=blue>return</font> MD2_ANIM_DEATH2;<br>	<font color=blue>if</font> (strcmp(str, <font color=darkred><font color=darkred>"death3"</font></font>) == 0) <font color=blue>return</font> MD2_ANIM_DEATH3;<br><br>	<font color=blue>return</font> -1;<br>}<br><br><font color=blue>void</font> CModelMD2::SetAnimLoop(<font color=blue>bool</font> b)<br>{<br>	loopAnim = b;<br>}<br><br><font color=blue>void</font> CModelMD2::Update()<br>{	<br>	tAnimationInfo* pAnim = &Model.pAnimations[<font color=purple>Model.currentAnim</font>];<br><br>	<font color=blue>if</font> (t &gt; 1.0f) <br>	{			<br>		<font color=blue>if</font> (Model.currentFrame == pAnim-&gt;endFrame)<br>		{<br>			<font color=blue>if</font> (loopAnim)<br>			{<br>				Model.currentFrame = pAnim-&gt;startFrame;<br>				t = 0.0f;<br>			}<br>			<font color=blue>else</font><br>			{<br>				Model.currentFrame = pAnim-&gt;endFrame;<br>				t = 1.1f;<br>			}<br>		}<br>		<font color=blue>else</font><br>		{<br>			Model.currentFrame++;<br>			t = 0.0f;<br>		}<br>	}<br>	<font color=blue>else</font><br>	{<br>		t += rFrameInterval * 5.0f;	<br>	}<br>}<br><br><font color=blue>int</font>  CModelMD2::LoadFromFile(<font color=blue>char</font>* fname)<br>{<br>	tMd2Header				m_Header;			<br>	tMd2Skin				*m_pSkins		= NULL;			<br>	tMd2TexCoord			*m_pTexCoords	= NULL;					<br>	tMd2Face				*m_pTriangles	= NULL;					<br>	tMd2Frame				*m_pFrames		= NULL;						<br>	tAnim3DModel*			pModel = &Model;<br><br>	<font color=blue>char</font> strFileName[<font color=purple>255</font>];<br>	<font color=blue>int</font> i, j;<br>	<br>	strcpy(strFileName, fname);<br><br>	FILE* fp = fopen(strFileName, <font color=darkred>"rb"</font>);<br><br>	<font color=blue>if</font>(!fp) <br>	{<br>		lprintf(<font color=darkred>"Unable to find the file: %s!"</font>, strFileName);<br>		<font color=blue>return</font> SYS_ERR;<br>	}<br>	<br>	fread(&m_Header, 1, <font color=blue>sizeof</font>(tMd2Header), fp);<br><br>	<font color=blue>if</font>(m_Header.version != 8)<br>	{<br>		lprintf(<font color=darkred>"Invalid file format (Version not 8): %s!"</font>, strFileName);<br>		<font color=blue>return</font> SYS_ERR;<br>	}<br><br>	lprintf(<font color=darkred>"Loading MD2 model %s"</font>, strFileName);<br><br>	<font color=blue>unsigned</font> <font color=blue>char</font> buffer[<font color=purple>MD2_MAX_FRAMESIZE</font>];<br><br>	m_pSkins     = <font color=blue>new</font> tMd2Skin [<font color=purple>m_Header.numSkins</font>];<br>	m_pTexCoords = <font color=blue>new</font> tMd2TexCoord [<font color=purple>m_Header.numTexCoords</font>];<br>	m_pTriangles = <font color=blue>new</font> tMd2Face [<font color=purple>m_Header.numTriangles</font>];<br>	m_pFrames    = <font color=blue>new</font> tMd2Frame [<font color=purple>m_Header.numFrames</font>];<br><br>	<font color=blue>if</font> (!m_pSkins || !m_pTexCoords || !m_pTriangles || !m_pFrames)<br>	{<br>		lprintf(<font color=darkred>"ERROR: Cannot allocate memory for model\n"</font>);<br>		<font color=blue>return</font> SYS_ERR;<br>	}<br><br>	fseek(fp, m_Header.offsetSkins, SEEK_SET);	<br>	fread(m_pSkins, <font color=blue>sizeof</font>(tMd2Skin), m_Header.numSkins, fp);	<br><br>	fseek(fp, m_Header.offsetTexCoords, SEEK_SET);<br>	fread(m_pTexCoords, <font color=blue>sizeof</font>(tMd2TexCoord), m_Header.numTexCoords, fp);<br><br>	fseek(fp, m_Header.offsetTriangles, SEEK_SET);<br>	fread(m_pTriangles, <font color=blue>sizeof</font>(tMd2Face), m_Header.numTriangles, fp);			<br><br>	fseek(fp, m_Header.offsetFrames, SEEK_SET);<br><br>	<font color=blue>for</font> (i = 0; i &lt; m_Header.numFrames; i++)<br>	{<br>		tMd2AliasFrame *pFrame = (tMd2AliasFrame *) buffer;<br><br>		m_pFrames[<font color=purple>i</font>].pVertices = NULL;<br>		m_pFrames[<font color=purple>i</font>].pVertices =	<font color=blue>new</font> tMd2Triangle [<font color=purple>m_Header.numVertices</font>];<br>		<font color=blue>if</font> (!m_pFrames[<font color=purple>i</font>].pVertices) <br>		{<br>			lprintf(<font color=darkred>"ERROR: Cannot allocate memory for model\n"</font>);<br>			<font color=blue>return</font> SYS_ERR;<br>		}<br><br>		fread(pFrame, 1, m_Header.frameSize, fp);<br><br>		strcpy(m_pFrames[<font color=purple>i</font>].strName, pFrame-&gt;name);		<br><br>		tMd2Triangle *pVertices = m_pFrames[<font color=purple>i</font>].pVertices;<br><br>		<font color=blue>for</font> (<font color=blue>int</font> j=0; j &lt; m_Header.numVertices; j++)<br>		{<br>			pVertices[<font color=purple>j</font>].vertex[<font color=purple>0</font>] = pFrame-&gt;aliasVertices[<font color=purple>j</font>].vertex[<font color=purple>0</font>] * pFrame-&gt;scale[<font color=purple>0</font>] + pFrame-&gt;translate[<font color=purple>0</font>];<br>			pVertices[<font color=purple>j</font>].vertex[<font color=purple>2</font>] = -1 * (pFrame-&gt;aliasVertices[<font color=purple>j</font>].vertex[<font color=purple>1</font>] * pFrame-&gt;scale[<font color=purple>1</font>] + pFrame-&gt;translate[<font color=purple>1</font>]);<br>			pVertices[<font color=purple>j</font>].vertex[<font color=purple>1</font>] = pFrame-&gt;aliasVertices[<font color=purple>j</font>].vertex[<font color=purple>2</font>] * pFrame-&gt;scale[<font color=purple>2</font>] + pFrame-&gt;translate[<font color=purple>2</font>];<br>		}<br>	}<br><br>	memset(pModel, 0, <font color=blue>sizeof</font>(t3DModel));	<br>	pModel-&gt;numObjects = m_Header.numFrames;<br><br>	tAnimationInfo animation;<br>	string strLastName = "<font color=darkred>";<br><br>	for(i = 0; i &lt; pModel-&gt;numObjects; i++)<br>	{<br>		string strName  = m_pFrames.strName;<br>		int frameNum = 0;<br>		<br>		for(j = 0; j &lt; strName.length(); j++)<br>		{<br>			if( isdigit(strName[j]) && j &gt;= strName.length() - 2)<br>			{<br>				frameNum = atoi(&strName[j]);<br>				strName.erase(j, strName.length() - j);<br>				for (int k = 0; k &lt; strName.size(); k++) strName[k] = tolower(strName[k]);<br>				break;<br>			}<br>		}<br><br>		if(strName != strLastName || i == pModel-&gt;numObjects - 1)<br>		{<br>			if(strLastName != "</font>")<br>			{<br>				strcpy(animation.strName, strLastName.c_str());<br>				animation.endFrame = i - 1;				<br>				pModel-&gt;pAnimations.push_back(animation);<br>				memset(&animation, 0, <font color=blue>sizeof</font>(tAnimationInfo));<br>				<br>				pModel-&gt;numOfAnimations++;<br>			}<br><br>			animation.startFrame = frameNum - 1 + i;<br>		}<br>		strLastName = strName;<br>	}<br><br>	Model.numObjects = pModel-&gt;numObjects;<br>	Model.numMaterials = pModel-&gt;numMaterials;<br><br>	Model.pObjects = <font color=blue>new</font> t3DObject[<font color=purple>Model.numObjects</font>];<br><br>	<font color=blue>for</font> (i = 0; i &lt; pModel-&gt;numObjects; i++)<br>	{<br>		t3DObject* currentFrame = &Model.pObjects[<font color=purple>i</font>];<br><br>		currentFrame-&gt;numVerts     = m_Header.numVertices;<br>		currentFrame-&gt;numTexCoords = m_Header.numTexCoords;<br>		currentFrame-&gt;numFaces     = m_Header.numTriangles;<br><br>		currentFrame-&gt;pVerts    = <font color=blue>new</font> CVector3 [<font color=purple>currentFrame-&gt;numVerts</font>];<br>		<font color=blue>if</font> (!currentFrame-&gt;pVerts)<br>		{<br>			lprintf(<font color=darkred>"ERROR: Cannot allocate memory for model\n"</font>);<br>			<font color=blue>return</font> SYS_ERR;<br>		}<br><br>		<font color=blue>for</font> (j=0; j &lt; currentFrame-&gt;numVerts; j++)<br>		{<br>			currentFrame-&gt;pVerts[<font color=purple>j</font>].x = m_pFrames[<font color=purple>i</font>].pVertices[<font color=purple>j</font>].vertex[<font color=purple>0</font>];<br>			currentFrame-&gt;pVerts[<font color=purple>j</font>].y = m_pFrames[<font color=purple>i</font>].pVertices[<font color=purple>j</font>].vertex[<font color=purple>1</font>];<br>			currentFrame-&gt;pVerts[<font color=purple>j</font>].z = m_pFrames[<font color=purple>i</font>].pVertices[<font color=purple>j</font>].vertex[<font color=purple>2</font>];<br>		}<br><br>		<font color=blue>delete</font> [] m_pFrames[<font color=purple>i</font>].pVertices;<br>		m_pFrames[<font color=purple>i</font>].pVertices = NULL;<br>		<br>		currentFrame-&gt;pFaces    = <font color=blue>new</font> tFace [<font color=purple>currentFrame-&gt;numFaces</font>];<br>		currentFrame-&gt;pTexFaces = <font color=blue>new</font> tTexFace [<font color=purple> currentFrame-&gt;numFaces</font>];<br>		<font color=blue>for</font>(j=0; j &lt; currentFrame-&gt;numFaces; j++)<br>		{<br>			<br>			currentFrame-&gt;pFaces[<font color=purple>j</font>].vertIndex[<font color=purple>0</font>] = m_pTriangles[<font color=purple>j</font>].vertexIndices[<font color=purple>0</font>];<br>			currentFrame-&gt;pFaces[<font color=purple>j</font>].vertIndex[<font color=purple>1</font>] = m_pTriangles[<font color=purple>j</font>].vertexIndices[<font color=purple>1</font>];<br>			currentFrame-&gt;pFaces[<font color=purple>j</font>].vertIndex[<font color=purple>2</font>] = m_pTriangles[<font color=purple>j</font>].vertexIndices[<font color=purple>2</font>];<br><br>			currentFrame-&gt;pTexFaces[<font color=purple>j</font>].coordIndex[<font color=purple>0</font>] = m_pTriangles[<font color=purple>j</font>].textureIndices[<font color=purple>0</font>];<br>			currentFrame-&gt;pTexFaces[<font color=purple>j</font>].coordIndex[<font color=purple>1</font>] = m_pTriangles[<font color=purple>j</font>].textureIndices[<font color=purple>1</font>];<br>			currentFrame-&gt;pTexFaces[<font color=purple>j</font>].coordIndex[<font color=purple>2</font>] = m_pTriangles[<font color=purple>j</font>].textureIndices[<font color=purple>2</font>];<br>		}<br><br>		<font color=blue>if</font>(i &gt; 0)<br>		{			<br>			<font color=blue>continue</font>;	<br>		}<br><br>		currentFrame-&gt;pTexCoords = <font color=blue>new</font> CVector2 [<font color=purple>currentFrame-&gt;numTexCoords</font>];<br>		<font color=blue>for</font>(j = 0; j &lt; currentFrame-&gt;numTexCoords; j++)<br>		{<br>			currentFrame-&gt;pTexCoords[<font color=purple>j</font>].x = (<font color=blue>float</font>)m_pTexCoords[<font color=purple>j</font>].u / <font color=blue>float</font>(m_Header.skinWidth);<br>			currentFrame-&gt;pTexCoords[<font color=purple>j</font>].y = 1.0f - (<font color=blue>float</font>)m_pTexCoords[<font color=purple>j</font>].v / <font color=blue>float</font>(m_Header.skinHeight);<br>		}		<br>	}<br><br>	fclose(fp);						<font color=gray>// Close the current file pointer<br></font><br><br>	<font color=blue>int</font> last = strlen(strFileName) - 1;<br>	<br>	strFileName[<font color=purple>last    </font>] = ''p'';<br>	strFileName[<font color=purple>last - 1</font>] = ''m'';<br>	strFileName[<font color=purple>last - 2</font>] = ''b'';<br><br>	<font color=blue>if</font> (tex.LoadFromFile(strFileName)) <font color=blue>return</font> SYS_ERR;<br><br>	<font color=blue>if</font>(m_pSkins)	 <font color=blue>delete</font> [] m_pSkins;		<br>	<font color=blue>if</font>(m_pTexCoords) <font color=blue>delete</font> m_pTexCoords;		<br>	<font color=blue>if</font>(m_pTriangles) <font color=blue>delete</font> m_pTriangles;		<br>	<font color=blue>if</font>(m_pFrames)	 <font color=blue>delete</font> m_pFrames;			<br><br>	m_pSkins		= NULL;<br>	m_pTexCoords	= NULL;<br>	m_pTriangles	= NULL;<br>	m_pFrames		= NULL;<br><br>	<font color=blue>return</font> SYS_OK;<br>}<br><br><br></pre><!–ENDSCRIPT–><br><br>and for MD2.h<br>   <!–STARTSCRIPT–><pre class="source"><br><font color=green>#ifndef </font>_MD2_H<br><font color=green>#define</font> _MD2_H<br><br><font color=green>#include</font> <font color=darkred>"3dm.h"</font><br><font color=green>#include</font> <font color=darkred>"textures.h"</font><br><font color=green>#include</font> <font color=darkred>"physics.h"</font><br><br><font color=green>#define</font> MD2_MAX_TRIANGLES		4096<br><font color=green>#define</font> MD2_MAX_VERTICES		2048<br><font color=green>#define</font> MD2_MAX_TEXCOORDS		2048<br><font color=green>#define</font> MD2_MAX_FRAMES			512<br><font color=green>#define</font> MD2_MAX_SKINS			32<br><font color=green>#define</font> MD2_MAX_FRAMESIZE		(MD2_MAX_VERTICES * 4 + 128)<br><br><font color=green>#define</font> kAnimationSpeed			5.0f<br><br><font color=blue>struct</font> tAnimationInfo<br>{<br>	<font color=blue>char</font> strName[<font color=purple>255</font>];			<font color=gray>// This stores the name of the animation (Jump, Pain, etc..)<br></font><br>	<font color=blue>int</font> startFrame;				<font color=gray>// This stores the first frame number for this animation<br></font><br>	<font color=blue>int</font> endFrame;				<font color=gray>// This stores the last frame number for this animation<br></font><br>};<br><br><font color=blue>struct</font> tAnim3DModel : <font color=blue>public</font> t3DModel <br>{<br>	<font color=blue>int</font> numOfAnimations;				<font color=gray>// The number of animations in this model (NEW)<br></font><br>	<font color=blue>int</font> currentAnim;					<font color=gray>// The current index into pAnimations list (NEW)<br></font><br>	<font color=blue>int</font> currentFrame;					<font color=gray>// The current frame of the current animation (NEW)<br></font><br><br>	vector&lt;tAnimationInfo&gt; pAnimations; <font color=gray>// The list of animations (NEW)<br></font><br>};<br><br><font color=green>#define</font> MD2_ANIM_STAND  0<br><font color=green>#define</font> MD2_ANIM_WALK   1<br><font color=green>#define</font> MD2_ANIM_DEATH1 2<br><font color=green>#define</font> MD2_ANIM_DEATH2 3<br><font color=green>#define</font> MD2_ANIM_DEATH3 4<br><br><font color=blue>class</font> CModelMD2<br>{<br><font color=blue>public</font>:<br>	CModelMD2();<br><br>	<font color=blue>int</font>  LoadFromFile(<font color=blue>char</font>* fname);<br>	<font color=blue>void</font> Destroy();<br><br>	<font color=blue>void</font> Render();<br>	<font color=blue>void</font> Update();<br><br>	<font color=blue>void</font> SetAnimation(<font color=blue>int</font> anim);<br>	<font color=blue>int</font>  GetAnimation();<br>	<font color=blue>void</font> SetPosition(CVector3 vPos);<br>	<font color=blue>void</font> SetRotation(<font color=blue>float</font> ang);<br><br>	<font color=blue>void</font> SetAnimLoop(<font color=blue>bool</font>);<br><font color=blue>private</font>:<br><br>	tAnim3DModel Model;<br>	CTexture tex;<br><br>	<font color=blue>float</font>	t;<br><br>	<font color=blue>bool</font>	loopAnim;<br><br>	<font color=blue>float</font>	ang;<br>	CVector3 vPos;<br>};<br><br><br><br><font color=green>#endif</font><br><br></pre><!–ENDSCRIPT–><br><br>For the anims: add some #defines for each anim (i &#111;nly used run, stand, death0-3)<br><br>Hope this will make it clear 4 U<br>   <br><br>Death to the gaming industry! Long live games. /*ilici*/   
Thanks for putting in the time and effort Ilici to post that. I will have a look through this as it is different again from any of the tuts I have gone through. Really appreciate it.
Below are the steps in how I load and render the models. Im wondering if someone could pick something up that im not?

-retrieve header info (NumTriangles, NumVertices etc - all working correctly)
-retrieve triangle data (vertex indices)
-retrieve frame data (compressed vertex coords)
-Convert the compressed coords to the right coordinates by mulitplying scale and adding the translation values in the frame data, using the triangle indices in the vertex arrays as the array element (if i'm not making sense, just let me know). I put these values into my own D3d structure to make it a bit cleaner
-Render my using DrawPrimitiveUP

Is this right? Is there anything that I should be aware of in any of these steps? I could just copy and paste code if I wanted to but as I ultimately want to make my own format I would like to get this working first (and I hate giving up on things)

I will look through your code now and see if I can see what im doing wrong.

Thanks again,
Harley.





[edited by - klown9 on August 19, 2003 6:58:59 AM]

This topic is closed to new replies.

Advertisement