I'm trying to make an importer for MD2 models. I can load the header correctly, and get to the correct offset to load what I want. What I'm having trouble with is getting the values from those offsets. I've downloaded and looked at a ton of tutorials on loading MD2 models but the problem with a lot of them is they are specific to the person who made them. So I'm getting confused on how do I correctly load the information from the offsets. I found file format specs that tell me the size of everything in the header, which is useful, but then how do I know what to use/read for say, the faces, or frames. I found the faces to be 12 bytes for each face (the frame size is part of the header so thats ok), but how do I know I should have X amount of elements in it. Like say short Vert[3] and short UV[3] vs something like int Vert[3] (which is 12 bytes by itself). Same goes for frames. I wish there was a detailed format spec someone could link me to that tells everything about each part that needs to be loaded. Below is what I have, and also a copied output of the header file information so I know its being read correctly.
One last question, the nTextures variable in the header is always zero on the models I've made, and downloaded even though they load textures when the example program is run, what gives?
Code:
struct MD2FILEHEADER
{
int ID; //always set to IDP2 (0x32504449)
int Version; //always set to 8 (maybe check this?)
int TexWidth; //texture width in pixels
int TexHeight; //texture height in pixels
int FrameSize; //size of each frame in bytes
int nTextures; //number of textures
int nVertices; //number of vertices from all frames
int nTexCoords; //number of texture coordinates
int nFaces; //number of faces in the model
int nGLCommands; //number of GL commands
int nFrames; //number of frames
int TexOffset; //An offset to the texture name(s)
int UVOffset; //An offset to the UV coordinates
int FaceOffset; //An offset to the face data
int FrameOffset; //An offset to the first animation frame
int GLCmdOffset; //An offset to the GLCmd list
int EOFOffset; //An offset to the end of the file
}; //end MD2FILEHEADER struct
struct MD2UVCOORD
{
short U; //Divide by TexWidth
short V; //Divide by TexHeight
};
struct MD2FACE
{
short Vertex[3];
short UV[3];
};
struct MD2VERTEX
{
byte Vtx[3];
byte Normal;
};
struct MD2FRAME
{
float Scale[3];
float Translate[3];
char Name[16];
};
//the loading function that is part of a class (only function right now)
bool MD2::LoadMD2File(string path)
{
FILE *md2file; //file pointer
MD2FILEHEADER md2header; //declare header structure
md2file = fopen(path.c_str(),"rb"); //open the file for reading
if(!md2file) return false; //could not open file
fread(&md2header,sizeof(md2header),1,md2file); //read header information
if(md2header.ID != 844121161) return false; //file is not an md2 file
//declare all the needed structures
MD2FACE md2face [md2header.nFaces];
MD2FRAME md2frame [md2header.nFrames];
fseek(md2file,md2header.FrameOffset,SEEK_SET); //move to frame
for(int i = 0; i < md2header.nFrames; i++){
fread(&md2frame[i],sizeof(MD2FRAME),1,md2file);
}
fseek(md2file,md2header.FaceOffset,SEEK_SET); //move to face
for(int i = 0; i < md2header.nFaces; i++){
fread(&md2face[i],sizeof(MD2FACE),1,md2file);
}
return true;
} //end LoadMD2File();
Code:
//the output
ID: 844121161
Version: 8
TexWidth: 256
TexHeight: 256
Frame size: 3956
nTextures: 0
nVertices: 979
nTexCoords: 931
nFaces: 1896
nGLCommands: 18961
nFrames: 400
TexOffset: 68
UVOffset: 68
FaceOffset: 3792
FrameOffset: 26544
GLCmdOffset: 1608944
EOFOffset: 1684788