Sign in to follow this  
sakky

For the life of me, I can NOT get his MD2 to render

Recommended Posts

sakky    100
So uh, I have this model that I've downloaded off the net somewere and I'm using if for testing my loading routines. I get no erros during loading, only at runtime when I try to render it (Direct3D). I've turned off culling and set to just points & wires to see if the mesh is even exists, so far I see nothing so I guess it doesn't. I'll list this code so that you can help more. Thanks in avance.
/* structures blaw, blaw, blaw! */

typedef struct st_MD2HEADER * LPMD2HEADER, * PMD2HEADER ;
typedef struct st_MD2HEADER {
DWORD	dwMagic ; 
DWORD	dwVersion ; 
DWORD	dwSkinWidth ; 
DWORD	dwSkinHeight ;
DWORD	dwFrameSize ; 
DWORD	dwSkinCount ; 
DWORD	dwVertCount ;
DWORD	dwSkinUVCount ; 
DWORD	dwPolyCount ;
DWORD	dwTypeCount ; 
DWORD	dwFrameCount ;
DWORD	dwSkinOffset ; 
DWORD	dwSkinUVOffset ; 
DWORD	dwPolyOffset ; 
DWORD	dwFrameOffset ; 
DWORD	dwTypeOffset ; 
DWORD	dwEOF ;
} MD2HEADER, _MD2HEADER ;

typedef CHAR	MD2SKINNAME[ 64 ] ;

typedef struct st_MD2VERTEX * LPMD2VERTEX, * PMD2VERTEX ;
typedef struct st_MD2VERTEX {
BYTE	vVertices[ 3 ] ;
BYTE	iNormal ;
} MD2VERTEX, _MD2VERTEX ;

typedef struct st_MD2SKINUV * LPMD2SKINUV, * PMD2SKINUV ;
typedef struct st_MD2SKINUV {
SHORT	wU, wV ;
} MD2SKINUV, _MD2SKINUV ;

typedef struct st_MD2POLYGON * LPMD2POLYGON, * PMD2POLYGON ;
typedef struct st_MD2POLYGON {
SHORT	vVertices[ 3 ] ;
SHORT	vSkinUV[ 3 ] ;
} MD2POLYGON, _MD2POLYGON ;

typedef struct st_MD2FRAME * LPMD2FRAME, * PMD2FRAME ;
typedef struct st_MD2FRAME {
D3DXVECTOR3	vScale ;
D3DXVECTOR3	vTranslate ;
CHAR		szName[ 16 ] ;
MD2VERTEX	vVertices[ 1 ] ;
} MD2FRAME, _MD2FRAME ;

typedef struct st_MD2HASH * LPMD2HASH, * PMD2HASH ;
typedef struct st_MD2HASH {
DWORD		dwSkinWidth ; 
DWORD		dwSkinHeight ;
DWORD		dwSkinCount ; 
MD2SKINNAME*	lpSkins ;
DWORD		dwSkinUVCount ; 
LPMD2SKINUV	lpSkinUVs ;
DWORD		dwPolyCount ;
LPMD2POLYGON	lpPolygons ;
DWORD		dwFrameCount ;
DWORD		dwVertCount ;
LPMD2FRAME	lpFrames ;
} MD2HASH, _MD2HASH ;

typedef struct st_MD2MODEL * LPMD2MODEL, * PMD2MODEL ;
typedef struct st_MD2MODEL {
MD2HASH		hHash ;
PBYTE		pData ;
} MD2MODEL, _MD2MODEL ;

/* Here comes the acutal code that I use to laod & draw the MD2 */

// ---------------------------------------------------------------------------- //
// Name		: MD2_BufferFile( )
// Desc		: Buffers MD2 contents with hash table
// ---------------------------------------------------------------------------- //
HRESULT __stdcall MD2_BufferFile( LPCSTR lpszFileName, LPMD2MODEL lpMD2Model )
{
	FILE*							 pFile ;
	MD2HEADER						 hHeader ;
	DWORD							 I, dwIndex ;

	if ( NULL == ( pFile = fopen( lpszFileName, "rb" ) ) )
	{
		return ( E_FAIL ) ;
	}

	fread( &hHeader, sizeof( MD2HEADER ), 1, pFile ) ;
	fseek( pFile, 0, SEEK_SET ) ;

	if ( ( hHeader.dwMagic != MD2_MAGICNUMBER ) || ( hHeader.dwVersion != MD2_VERSION ) )
	{
		fclose ( pFile  ) ;
		return ( E_FAIL ) ;
	}

	if ( NULL == ( lpMD2Model->pData = new BYTE[ ( hHeader.dwEOF - ftell( pFile ) ) ] ) )
	{
		return ( E_OUTOFMEMORY ) ;
	}

	fread( lpMD2Model->pData, ( hHeader.dwEOF - ftell( pFile ) ), 1, pFile ) ;
	fclose( pFile ) ;

	lpMD2Model->hHash.lpSkinUVs		 = ( LPMD2SKINUV  )&lpMD2Model->pData[ hHeader.dwSkinUVOffset ] ;
	lpMD2Model->hHash.dwSkinUVCount	 = hHeader.dwSkinCount ;
	
	lpMD2Model->hHash.dwSkinWidth	 = hHeader.dwSkinWidth ;
	lpMD2Model->hHash.dwSkinHeight	 = hHeader.dwSkinHeight ;

	lpMD2Model->hHash.lpPolygons	 = ( LPMD2POLYGON )&lpMD2Model->pData[ hHeader.dwPolyOffset ] ;
	lpMD2Model->hHash.dwPolyCount	 = hHeader.dwPolyCount ;

	lpMD2Model->hHash.lpSkins		 = ( MD2SKINNAME* )&lpMD2Model->pData[ hHeader.dwSkinOffset ] ;
	lpMD2Model->hHash.dwSkinCount	 = hHeader.dwSkinCount ;

	for ( I = 0 ; I < hHeader.dwFrameCount ; I++ )
	{
		dwIndex						 = ( hHeader.dwFrameOffset + ( I * hHeader.dwFrameSize ) ) ;
		lpMD2Model->hHash.lpFrames	 = ( MD2FRAME* )&lpMD2Model->pData[ dwIndex ] ;
	}

	lpMD2Model->hHash.dwFrameCount	 = hHeader.dwFrameCount ;
	lpMD2Model->hHash.dwVertCount	 = hHeader.dwVertCount ;

	return ( S_OK ) ;
}

// ---------------------------------------------------------------------------- //
// Name		: MD2_ConvertFrame( )
// Desc		: Converts MD2 frame vertex information
// ---------------------------------------------------------------------------- //
HRESULT __stdcall MD2_ConvertFrame( LPMD2MODEL lpMD2, UINT uFrame, LPDIRECT3DVERTEXBUFFER9* ppD3DVertexBuffer )
{
	PMD2FRAME						 pFrame ;
	PVERTEX3D						 pVertices ;
	PVERTEX3D						 pWorkVert ;
	PMD2VERTEX						 pMD2Vert ;
	PMD2SKINUV						 pSkinUV ;
	HRESULT							 hRet ;

	if ( FAILED( hRet = ( *ppD3DVertexBuffer )->Lock( 0, ( sizeof( VERTEX3D ) * lpMD2->hHash.dwVertCount ),
													  ( void** )&pVertices, 0 ) ) )
	{
		return ( hRet ) ;
	}

	pFrame							 = &lpMD2->hHash.lpFrames[ uFrame ] ;

	for ( DWORD I = 0 ; I < lpMD2->hHash.dwPolyCount ; I++ )
	{
		for ( DWORD J = 0 ; J < 3 ; J ++ )
		{
			pWorkVert				 = &pVertices[ lpMD2->hHash.lpPolygons[ I ].vVertices[ J ] ] ;
//			pSkinUV					 = &lpMD2->hHash.lpSkinUVs[ lpMD2->hHash.lpPolygons[ I ].vSkinUV[ J ] ] ;
			pMD2Vert				 = &pFrame->vVertices[ lpMD2->hHash.lpPolygons[ I ].vVertices[ J ] ] ;

			pWorkVert->vPos.x		 = pMD2Vert->vVertices[ 0 ] * pFrame->vScale.x + pFrame->vTranslate.x ;
			pWorkVert->vPos.y		 = pMD2Vert->vVertices[ 1 ] * pFrame->vScale.y + pFrame->vTranslate.y ;
			pWorkVert->vPos.z		 = pMD2Vert->vVertices[ 2 ] * pFrame->vScale.z + pFrame->vTranslate.z ;

			pWorkVert->dwColor		 = D3DCOLOR_XRGB( 255, 255, 255 ) ;

//			pWorkVert->vTex.x		 = ( FLOAT )( pSkinUV->wU / lpMD2->hHash.dwSkinWidth ) ;
//			pWorkVert->vTex.y		 = ( FLOAT )( 1.0F - ( pSkinUV->wV / lpMD2->hHash.dwSkinWidth ) ) ;
		}
	}

	return ( ( *ppD3DVertexBuffer )->Unlock( ) ) ;
}

// ---------------------------------------------------------------------------- //
// Name		: MD2_ConvertPolys( )
// Desc		: Converts MD2 polygon information
// ---------------------------------------------------------------------------- //
HRESULT __stdcall MD2_ConvertPolys( LPMD2MODEL lpMD2, LPDIRECT3DINDEXBUFFER9* ppD3DIndexBuffer )
{
	WORD*							 pData ;
	HRESULT							 hRet ;

	if ( FAILED( hRet = ( *ppD3DIndexBuffer )->Lock( 0, ( 6 * lpMD2->hHash.dwPolyCount ), ( void** )&pData, 0 ) ) )
	{
		return ( hRet ) ;
	}

	for ( DWORD I = 0 ; I < lpMD2->hHash.dwPolyCount ; I++ )
	{
		memcpy( pData, lpMD2->hHash.lpPolygons[ I ].vVertices, 6 ) ;
		pData						+= 6 ;
	}

	return ( ( *ppD3DIndexBuffer )->Unlock( ) ) ;
}

I have parts of *one* function commented because I'm testing that one, I think the probelm may be there or when I load the file.

Share this post


Link to post
Share on other sites
sakky    100
Okay, I rewrote the code so that I can render a single frame for now. It's still not working either. I don't have a clue what the problem is, so .....??


FILE* pFile ;
MD2HEADER hMD2Header ;
MD2FRAME hMD2Frame ;
MD2VERTEX hMD2Vert ;
PVERTEX3D pVertices ;
HRESULT hRet ;

if ( NULL == ( pFile = fopen( lpszFileName, "rb" ) ) )
{
return ( E_FAIL ) ;
}

fread( &hMD2Header, sizeof( MD2HEADER ), 1, pFile ) ;

if ( FAILED( hRet = g_lpD3DDevice->CreateVertexBuffer(
sizeof( VERTEX3D ) * hMD2Header.dwVertCount, 0,
D3DFVF_VERTEX3D,
D3DPOOL_DEFAULT,
&g_lpD3DModel,
NULL ) ) )
{
fclose ( pFile ) ;
return ( hRet ) ;
}

if ( FAILED( hRet = g_lpD3DModel->Lock( 0,
( sizeof( VERTEX3D ) * hMD2Header.dwVertCount ),
( void** )&pVertices, 0 ) ) )
{
fclose ( pFile ) ;
return ( hRet ) ;
}

fseek( pFile, hMD2Header.dwFrameOffset, SEEK_SET ) ;
fread( &hMD2Frame, sizeof( MD2FRAME ), 1, pFile ) ;

for ( DWORD I = 0 ; I < hMD2Header.dwVertCount ; I++ ) {
fread( &hMD2Vert, sizeof( MD2VERTEX ), 1, pFile ) ;

pVertices->vPos.x = hMD2Vert.vVertices[ 0 ] * hMD2Frame.vScale.x + hMD2Frame.vTranslate.x ;
pVertices->vPos.y = hMD2Vert.vVertices[ 1 ] * hMD2Frame.vScale.y + hMD2Frame.vTranslate.y ;
pVertices->vPos.z = hMD2Vert.vVertices[ 2 ] * hMD2Frame.vScale.z + hMD2Frame.vTranslate.z ;
pVertices->dwColor = D3DCOLOR_XRGB( 255, 255, 255 ) ;
pVertices->vTex.x = 0.0F ;
pVertices->vTex.y = 0.0F ;
pVertices++ ;
}

g_lpD3DModel->Unlock( ) ;
fclose( pFile ) ;

g_dwPolyCount = hMD2Header.dwPolyCount ;



Notice I removed some of the error checking for valid MD2 file, I know it is. I've seen the model loaded into other programs and I know I have the file/path name correct.

Every thing loads fine... well I get no errors. But when I got to render the model I see nothing. So it has to be something during load time that is causing the mesh not to display proberly.

Share this post


Link to post
Share on other sites
dx elliot    325
I hope for

pFrame = &lpMD2->hHash.lpFrames[ uFrame ];

you meant to do

pFrame = lpMD2->hHash.lpFrames[ uFrame ];

I can't find anything else wrong, but you should really consider outputting the vectors and indexes to a file with a logging function to make sure nothing is bad data... it has saved me hours. Or, output point lists rather than the polygons - that way you'll narrow the problem down to either the vertexes, frames, camera, or drawing.

Share this post


Link to post
Share on other sites
sakky    100
Okay, well thanks for the reply. But, I thought that since the frames were an array and I wanted a pointer to one of them, that I had to reference that to the pointer. You know, basic C++ stuff

[Example]
int x ;
int *p ;
x = 2 ;
p = &x ;

That's what I was using the '&' with the frames. It's hard to beleive that is the problem, but I guess I can try it out.

Share this post


Link to post
Share on other sites
sakky    100
Okay, it's still not wokring. But I changed some of the code

[Render Code]

g_lpD3DDevice->SetFVF( D3DFVF_VERTEX3D ) ;
g_lpD3DDevice->SetStreamSource( 0, g_lpD3DModel, 0, sizeof( VERTEX3D ) ) ;
g_lpD3DDevice->SetTexture( 0, NULL ) ;

g_lpD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME ) ;
g_lpD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ) ;

g_lpD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, g_dwPolyCount ) ;



[Loading Code]

HRESULT __stdcall MD2_LoadModelFrame( LPCSTR lpszFileName, LPDIRECT3DVERTEXBUFFER9* ppD3DVertexBuffer )
{
FILE* pFile ;
MD2HEADER hHeader ;
MD2POLYGON vPolygons[ MD2_MAXPOLYGONS ] ;
MD2VERTEX vVertices[ MD2_MAXVERTICES ] ;
MD2SKINUV vSkinUVs[ MD2_MAXUVCOORDS ] ;
MD2FRAME hFrame ;
LPVERTEX3D lpVertices ;
DWORD I, J, dwSkin, dwVert, dwVertSize ;
HRESULT hRet ;

if ( NULL == ( pFile = fopen( lpszFileName, "rb" ) ) )
{
return ( E_FAIL ) ;
}

fread( &hHeader, sizeof( MD2HEADER ), 1, pFile ) ;

if ( ( MD2_MAGICNUMBER != hHeader.dwMagic ) || ( MD2_VERSION != hHeader.dwVersion ) )
{
fclose ( pFile ) ;
return ( E_FAIL ) ;
}

fseek( pFile, hHeader.dwPolyOffset, SEEK_SET ) ;
fread( vPolygons, sizeof( MD2POLYGON ), hHeader.dwPolyCount, pFile ) ;

fseek( pFile, hHeader.dwSkinUVOffset, SEEK_SET ) ;
fread( vSkinUVs, sizeof( MD2SKINUV ), hHeader.dwSkinUVCount, pFile ) ;

fseek( pFile, hHeader.dwFrameCount, SEEK_SET ) ;
fread( &hFrame, sizeof( MD2FRAME ), 1, pFile ) ;
fread( vVertices, sizeof( MD2VERTEX ), hHeader.dwVertCount, pFile ) ;

fclose( pFile ) ;

dwVertSize = ( sizeof( VERTEX3D ) * hHeader.dwVertCount ) ;

if ( FAILED( hRet = g_lpD3DDevice->CreateVertexBuffer( dwVertSize, 0,
D3DFVF_VERTEX3D,
D3DPOOL_DEFAULT,
ppD3DVertexBuffer,
NULL ) ) )
{
return ( hRet ) ;
}

if ( FAILED( hRet = ( *ppD3DVertexBuffer )->Lock( 0, dwVertSize,
( void** )&lpVertices, 0 ) ) )
{
return ( hRet ) ;
}

for ( I = 0 ; I < hHeader.dwVertCount ; I++ )
{
lpVertices[ I ].vPos.x = vVertices[ I ].vVertices[ 0 ] * ( hFrame.vScale.x + hFrame.vTranslate.x ) ;
lpVertices[ I ].vPos.y = vVertices[ I ].vVertices[ 1 ] * ( hFrame.vScale.y + hFrame.vTranslate.y ) ;
lpVertices[ I ].vPos.z = vVertices[ I ].vVertices[ 2 ] * ( hFrame.vScale.z + hFrame.vTranslate.z ) ;
lpVertices[ I ].dwColor = D3DCOLOR_XRGB( 200, 200, 200 ) ;
}

( *ppD3DVertexBuffer )->Unlock( ) ;

g_dwPolyCount = hHeader.dwPolyCount ;

return ( S_OK ) ;
}

Share this post


Link to post
Share on other sites
sakky    100
Holly cow, dx elliot! I did the log thing like you said, and every single vertex is set to zero! I log them to a file after I convert them and they are all zero! WTF?

Share this post


Link to post
Share on other sites
sakky    100
Okay, I see by my last post I didn't read what I wrote very well. What I mean is, I was fseek-ing to dwFrameCount, not dwFrameOffset. Now I have values, but they are huge! So I guess I have to scale them down by 900.0F because they are so damn big

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this