Original Post
Hey, My MD2 model isn't texturing properly. You can download the exe and source MD2 problem. Dont mind the memory allocation mess, I can get quite messy when figuring things out ;) My CPP file My H file [Edited by - rpg_code_master on January 20, 2005 5:19:04 AM]
// UltraLight_MD2_Load_Save.cpp : Defines the entry point for the DLL application.
//
#include "UltraLight_MD2_Load_Save.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
//===========================================================================================\\
// this is the main method that actaully creates the plugin
extern "C" {
UL_PLUGIN IPlugin* CreatePlugin( void* )
{
return new CUltraLight_MD2_Load_Save( );
} // end CreatePlugin
}; // end extern "C"
//===========================================================================================\\
/*********************************************************************************************/
//
// CLASS: CMeshPlugin
//
// DESC: This is a mesh loader/saver
//
/*********************************************************************************************/
// this returns the plugins ID
// it takes nothing
// it returns the plugins ID
char* CMeshPlugin::GetID( void )
{
return PLUGID_MESH;
} // end CMeshPlugin::GetID
// this runs the plugin
// it takes the nessercary data
// it retruns the nessercary data
void* CMeshPlugin::Run( void* pData )
{
// do noting... ;)
return 0;
} // end CMeshPlugin::Run
// this returns a new instance of the plugin if needed
// it takes nothing
// it returns the plugin instance
void* CMeshPlugin::CreateInstance( void )
{
return new CUltraLight_MD2_Load_Save;
} // end CMeshPlugin::CreateInstance
/*********************************************************************************************/
//
// CLASS: CUltraLight_MD2_Load_Save
//
// DESC: This is a md2 model loader/saver
//
/*********************************************************************************************/
// this loads the md2 model file
// it takes the filename of the file to open
// it returns true upon success else returns false
bool CUltraLight_MD2_Load_Save::Load( const char* strFName )
{
// load in the model
m_pModel = LoadMD2( (char *const)strFName, "" );
if ( !m_pModel )
return false;
return true;
} // end CUltraLight_MD2_Load_Save::Load
// this loads the md2 model file
// it takes the filename of the file to save
// it returns true upon success else returns false
bool CUltraLight_MD2_Load_Save::Save( const char* strFName )
{
return true;
} // end CUltraLight_MD2_Load_Save::Save
// this returns the extension of this file format, .md2
// it takes nothing
// it returns the extension of this file format
char* CUltraLight_MD2_Load_Save::GetExt( void )
{
return "md2";
} // end CUltraLight_MD2_Load_Save::GetExt
// this returns the animation type
eMeshAnimTypes CUltraLight_MD2_Load_Save::GetAnimationType( void )
{
return eKeyFrame;
} // end CUltraLight_MD2_Load_Save::GetAnimationType
// these return the mesh data
// they take noting
// they return the mesh data
LPVERTEX CUltraLight_MD2_Load_Save::GetVertexs( void )
{
return m_pModel->m_pVerts;
} // end CUltraLight_MD2_Load_Save::GetVertexs
// this takes the animation to return
LPKEYFRAMEANIMATION CUltraLight_MD2_Load_Save::GetAnimation( int nFrame )
{
return &m_pModel->m_Anim;
} // end CUltraLight_MD2_Load_Save::GetKeyFrame
int CUltraLight_MD2_Load_Save::GetNumAnimations( void )
{
return 1;
} // end CUltraLight_MD2_Load_Save::GetNumKeyFrames
unsigned long CUltraLight_MD2_Load_Save::GetNumVertexs( void )
{
return m_pModel->m_nNumTriangles*3;
} // end CUltraLight_MD2_Load_Save::GetNumVertexs
unsigned short* CUltraLight_MD2_Load_Save::GetVertexIndex( void )
{
return m_pModel->m_psVertIndex;
} // end CUltraLight_MD2_Load_Save::GetVertexIndex
unsigned long CUltraLight_MD2_Load_Save::GetNumVertexsIndex( void )
{
return m_pModel->m_nNumTriangles*3;
} // end CUltraLight_MD2_Load_Save::GetNumVertexsIndex
unsigned long CUltraLight_MD2_Load_Save::GetNumTriangles( void )
{
return m_pModel->m_nNumTriangles;
} // end CUltraLight_MD2_Load_Save::GetNumTriangles
CVector3 CUltraLight_MD2_Load_Save::GetPos( void )
{
return CVector3( );
} // end CUltraLight_MD2_Load_Save::GetPos
CVector3 CUltraLight_MD2_Load_Save::GetRot( void )
{
return CVector3( );
} // end CUltraLight_MD2_Load_Save::GetRot
CVector3 CUltraLight_MD2_Load_Save::GetScale( void )
{
return CVector3( 1,1,1 );
} // end CUltraLight_MD2_Load_Save::GetScale
//===========================================================================================\\
// this loads the md2 model
// it takes the filename of the md2 model to load and the filename(s) of the skins to load
// it returns the loaded model upon success else returns NULL
LPMD2 LoadMD2( char *const strFName, char *const strFTexName )
{
FILE* fp;
int nFileLen;
char *pBuff;
LPMD2 pModel;
LPMD2HEADER pModelHeader;
LPMD2FRAME pFrame;
LPVERTEX pVecList;
unsigned short *psVertIndex, *psTexIndex, *psBufIndex, *index;
LPMD2TEXCOORDINDEX pTexIndex;
LPMD2TRIANGLE pTri, pTriBuff;
// open the file
fp = fopen( strFName, "rb" );
if ( !fp )
return NULL;
// find the length of the file
fseek( fp, 0, SEEK_END );
nFileLen = ftell( fp );
fseek( fp, 0, SEEK_SET );
// read the entire file into the buffer
pBuff = (char*)malloc( sizeof( char ) * ( nFileLen + 1 ) );
if ( !pBuff )
return NULL;
fread( pBuff, sizeof( char ), nFileLen, fp );
// extract the model header
pModelHeader = (LPMD2HEADER)pBuff;
// create model memory
pModel = (LPMD2)malloc( sizeof( MD2 ) );
if ( !pModel )
return NULL;
// create vertex memory
pModel->m_pVerts = (LPVERTEX)malloc( sizeof( VERTEX ) * pModelHeader->m_nNumTris * 3 * pModelHeader->m_nNumFrames );
if ( !pModel->m_pVerts )
return false;
pTri = (LPMD2TRIANGLE)malloc( sizeof( MD2TRIANGLE ) * pModelHeader->m_nNumTris * pModelHeader->m_nNumFrames );
if ( !pModel->m_pVerts )
return false;
// set member vars.
pModel->m_nNumPoints = pModelHeader->m_nNumXYZ;
pModel->m_nNumST = pModelHeader->m_nNumST;
pModel->m_nNumFrames = pModelHeader->m_nNumFrames;
pModel->m_nFrameSize = pModelHeader->m_nFrameSize;
// setup the animation
pModel->m_Anim.m_Frames.Init( pModel->m_nNumFrames );
pModel->m_Anim.m_nNumKeyFrames = pModel->m_nNumFrames;
pModel->m_Anim.m_nCurrentKeyFrame = 0;
pModel->m_Anim.m_fIntroperlate = 0.0f;
// compute all of the models verts
for ( int n = 0; n < pModel->m_nNumFrames; n++ ) {
pFrame = (LPMD2FRAME)&pBuff[ pModelHeader->m_nOffsetFrames + pModelHeader->m_nFrameSize * n ];
// calculate the vert positions based on the frame details
int nNumXYZ = pModelHeader->m_nNumXYZ;
pVecList = (LPVERTEX)&pModel->m_pVerts[ pModelHeader->m_nNumXYZ * n ];
for ( int i = 0; i < nNumXYZ; i++ )
{
pVecList[ i ].x = pFrame->m_fScale[ 0 ] * pFrame->m_fp[ i ].v[ 0 ] + pFrame->m_fTranslate[ 0 ];
pVecList[ i ].y = pFrame->m_fScale[ 1 ] * pFrame->m_fp[ i ].v[ 1 ] + pFrame->m_fTranslate[ 1 ];
pVecList[ i ].z = pFrame->m_fScale[ 2 ] * pFrame->m_fp[ i ].v[ 2 ] + pFrame->m_fTranslate[ 2 ];
} // end for
//pModel->m_Anim.m_Frames[ n ].m_pVerts = pVecList; // set the verts
} // end for
// load in the verts
// create the vert memory
index = (unsigned short*)malloc( sizeof( unsigned short ) * pModelHeader->m_nNumTris * 3 );
// set the number of tris
pModel->m_nNumTriangles = pModelHeader->m_nNumTris;
pModel->m_psVertIndex = index;
// point to the tri indecies in the buff
pTriBuff = (LPMD2TRIANGLE)&pBuff[ pModelHeader->m_nOffsetTris ];
// point to the texture coords
pTexIndex = (LPMD2TEXCOORDINDEX)&pBuff[ pModelHeader->m_nOffsetST ];
// set the mesh
int nNumTris = pModelHeader->m_nNumTris;
// calculate the normals and set the texture coords
for ( int x = 0; x < pModel->m_nNumFrames; x++ ) {
pVecList = (LPVERTEX)&pModel->m_pVerts[ pModelHeader->m_nNumXYZ * x ];
pModel->m_Anim.m_Frames[ x ].m_pVerts = new VERTEX[ pModelHeader->m_nNumTris * 3 ];
pModel->m_Anim.m_Frames[ x ].m_fTime = 0.05f;
pModel->m_Anim.m_Frames[ x ].m_nNumVerts = pModelHeader->m_nNumTris * 3;
for ( int i = 0, j = 0, t = 0; i < nNumTris; i++, j += 3 )
{
// save the texture coord
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+0 ].x = pVecList[ pTriBuff[ i ].m_nVertIndicies[ 0 ] ].x;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+0 ].y = pVecList[ pTriBuff[ i ].m_nVertIndicies[ 0 ] ].y;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+0 ].z = pVecList[ pTriBuff[ i ].m_nVertIndicies[ 0 ] ].z;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+0 ].u1 = pTexIndex[ pTriBuff[ i ].m_nTexIndicies[ 0 ] ].s;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+0 ].v1 = pTexIndex[ pTriBuff[ i ].m_nTexIndicies[ 0 ] ].t;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+1 ].x = pVecList[ pTriBuff[ i ].m_nVertIndicies[ 1 ] ].x;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+1 ].y = pVecList[ pTriBuff[ i ].m_nVertIndicies[ 1 ] ].y;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+1 ].z = pVecList[ pTriBuff[ i ].m_nVertIndicies[ 1 ] ].z;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+1 ].u1 = pTexIndex[ pTriBuff[ i ].m_nTexIndicies[ 1 ] ].s;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+1 ].v1 = pTexIndex[ pTriBuff[ i ].m_nTexIndicies[ 1 ] ].t;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+2 ].x = pVecList[ pTriBuff[ i ].m_nVertIndicies[ 2 ] ].x;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+2 ].y = pVecList[ pTriBuff[ i ].m_nVertIndicies[ 2 ] ].y;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+2 ].z = pVecList[ pTriBuff[ i ].m_nVertIndicies[ 2 ] ].z;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+2 ].u1 = pTexIndex[ pTriBuff[ i ].m_nTexIndicies[ 2 ] ].s;
pModel->m_Anim.m_Frames[ x ].m_pVerts[ j+2 ].v1 = pTexIndex[ pTriBuff[ i ].m_nTexIndicies[ 2 ] ].t;
// set the new index buffer
index[ j+0 ] = j+0;
index[ j+1 ] = j+1;
index[ j+2 ] = j+2;
/*
Tri[ i ].m_nVertIndicies[ 0 ]pVecList[ psVertIndex[ j+0 ] ].u1 = pTexIndex[ psTexIndex[ j+0 ] ].s;
pVecList[ psVertIndex[ j+0 ] ].v1 = pTexIndex[ psTexIndex[ j+0 ] ].t;
pVecList[ psVertIndex[ j+1 ] ].u1 = pTexIndex[ psTexIndex[ j+1 ] ].s;
pVecList[ psVertIndex[ j+1 ] ].v1 = pTexIndex[ psTexIndex[ j+1 ] ].t;
pVecList[ psVertIndex[ j+2 ] ].u1 = pTexIndex[ psTexIndex[ j+2 ] ].s;
pVecList[ psVertIndex[ j+2 ] ].v1 = pTexIndex[ psTexIndex[ j+2 ] ].t;
*/} // end for
//pModel->m_Anim.m_Frames[ n ].m_pVerts = pVecList; // set the verts
} // end for
// finish up
fclose( fp );
fflush( fp );
// free( psTexIndex );
// free( psVertIndex );
free( pBuff );
return pModel;
} // end LoadMD2
// FILE: UltraLight_MD2_Load_Save.h by Richard Hughes. 10/07/2004
//
// DESC: This defnes all the needed classes etc... to allow the UltraLight(r) game engine to load and save
// .md2 model files
#ifndef UltraLight_MD2_Load_Save
#define UltraLight_MD2_Load_Save
// INCLUDES
#include "..\\..\\UltraLight\\UltraLight\\MeshPlugin.h"
/*********************************************************************************************/
//
// STRUCT: tagMD2Vec
//
// DESC: This is a simple vector to be used with the loading and saving of the md2 model
//
/*********************************************************************************************/
typedef struct tagMD2Vec {
float x,y,z;
}MD2VEC, *LPMD2VEC;
/*********************************************************************************************/
//
// STRUCT: tagMD2TexCoordIndex
//
// DESC: This is a simple tex coord index obj. to be used with the loading and saving of the md2 model
//
/*********************************************************************************************/
typedef struct tagMD2TexCoordIndex {
unsigned short s,t;
}MD2TEXCOORDINDEX, *LPMD2TEXCOORDINDEX;
/*********************************************************************************************/
//
// STRUCT: tagMD2FramePoint
//
// DESC: This is a md2 framepoint
//
/*********************************************************************************************/
typedef struct tagMD2FramePoint {
unsigned char v[ 3 ];
unsigned char m_cNormalIndex;
}MD2FRAMEPOINT, *LPMD2FRAMEPOINT;
/*********************************************************************************************/
//
// STRUCT: tagMD2Frame
//
// DESC: This is a md2 frame
//
/*********************************************************************************************/
typedef struct tagMD2Frame {
float m_fScale[ 3 ];
float m_fTranslate[ 3 ];
char m_strName[ 16 ];
MD2FRAMEPOINT m_fp[ 1 ];
}MD2FRAME, *LPMD2FRAME;
/*********************************************************************************************/
//
// STRUCT: tagMD2Triangle
//
// DESC: This is an md2 triangle
//
/*********************************************************************************************/
typedef struct tagMD2Triangle {
unsigned short m_nVertIndicies[ 3 ];
unsigned short m_nTexIndicies[ 3 ];
}MD2TRIANGLE, *LPMD2TRIANGLE;
/*********************************************************************************************/
//
// STRUCT: tagMD2Header
//
// DESC: This is the md2 model header
//
/*********************************************************************************************/
typedef struct tagMD2Header {
int m_nIdent;
int m_nVersion;
int m_nSkinWidth;
int m_nSkinHeight;
int m_nFrameSize;
int m_nNumSkins;
int m_nNumXYZ;
int m_nNumST;
int m_nNumTris;
int m_nNumGLCommands;
int m_nNumFrames;
int m_nOffsetSkins;
int m_nOffsetST;
int m_nOffsetTris;
int m_nOffsetFrames;
int m_nOffsetGLCommands;
int m_nOffsetEnd;
}MD2HEADER, *LPMD2HEADER;
/*********************************************************************************************/
//
// STRUCT: tagMD2
//
// DESC: This is the md2 model
//
/*********************************************************************************************/
typedef struct tagMD2 {
int m_nNumFrames;
int m_nNumPoints;
int m_nNumTriangles;
int m_nNumST;
int m_nFrameSize;
int m_nTexWidth, m_nTexHeight;
int m_nCurrentFrame;
float m_fInterpole;
unsigned short *m_psTexIndex;
unsigned short *m_psVertIndex;
LPVERTEX m_pVerts;
KEYFRAMEANIMATION m_Anim;
}MD2, *LPMD2;
// this loads the md2 model
// it takes the filename of the md2 model to load and the filename(s) of the skins to load
// it returns the loaded model upon success else returns NULL
LPMD2 LoadMD2( char *const strFName, char *const strFTexName );
/*********************************************************************************************/
//
// CLASS: CUltraLight_MD2_Load_Save
//
// DESC: This is a md2 model loader/saver
//
/*********************************************************************************************/
class CUltraLight_MD2_Load_Save : public CMeshPlugin {
LPMD2 m_pModel;
public:
CUltraLight_MD2_Load_Save( void )
: m_pModel( NULL )
{
}
~CUltraLight_MD2_Load_Save( void )
{
}
// this loads the md2 model file
bool Load( const char* strFName );
// this saves the md2 model file
bool Save( const char* strFName );
// this returns the extension of this file format, .md2
char* GetExt( void );
// this returns the animation type
eMeshAnimTypes GetAnimationType( void );
// these return the mesh data
LPVERTEX GetVertexs( void );
LPKEYFRAMEANIMATION GetAnimation( int nFrame );
int GetNumAnimations( void );
unsigned long GetNumVertexs( void );
unsigned short* GetVertexIndex( void );
unsigned long GetNumVertexsIndex( void );
unsigned long GetNumTriangles( void );
CVector3 GetPos( void );
CVector3 GetRot( void );
CVector3 GetScale( void );
QUICK_SIZE;
}; // end class CUltraLight_MD2_Load_Save
#endif /* UltraLight_MD2_Load_Save */
// EOF: UltraLight_MD2_Load_Save.h