Sign in to follow this  

Help with an MD3 model loader?

This topic is 2584 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

Note: I say surfaces but I think most other people call them meshes

I'm trying to write a md3 model loader in c++ for a project. I've run into a problem and cannot work out what is wrong. I'm working through it step by step so have not yet implemented animation or textures. I can load in a single md3 model but only if it has a single surface. If it has multiple surfaces it does not display it correctly, I can see the rough shape there though. Oddly I can load in one model that has 5 surface the only difference I can see is that it is just one frame.

Any help will be greatly appreciated

[EDIT]

If I add all the triangles from all the surfaces to an array and all the vertices to an array and try and draw them in one go I get the working model and odd looking other ones.

I tried drawing the vertices to the screen after each surface object but this didn't work at all.

Share this post


Link to post
Share on other sites
struct md3_header_t
{
int ident;
int version;
unsigned char name[64];
int flags;
int num_frames;
int num_tags;
int num_surfaces;
int num_skins;
int offset_frames;
int offset_tags;
int offset_surfaces;
int offset_eof;
};

struct md3_frame_t
{
float min_bounds[3];
float max_bounds[3];
float local_origin[3];
float radius;
unsigned char name[16];
};

struct md3_tags_t
{
unsigned char name[64];
float origin[3];
float axis[3][3];
};

struct md3_surface_t
{
int indent;
unsigned char name[64];
int flags;
int num_frames;
int num_shaders;
int num_verts;
int num_triangles;
int offset_triangles;
int offset_shaders;
int offset_st;
int offset_xyznormal;
int offset_end;
//int thing;
};

struct md3_shader_t
{
unsigned char name[64];
int shader_index;
};

struct md3_triangle_t
{
int indexes[3];

struct md3_texcoord_t
{
float st[2];

struct md3_vertex_t
{
short coord[3];
unsigned char normal[2];
};

That's the struct part of my header file, I'm 95% sure that all works.


Here is where I get pull the header, surfaces, triangles and vertices (It should be for just the first frame)

//get header
md3_header_t * md3header = (struct md3_header_t *)
malloc(sizeof(struct md3_header_t));
md3file.read((char *) md3header, sizeof (struct md3_header_t));

runningTotal = md3header->offset_surfaces;

for( int i = 0; i < md3header->num_surfaces; i++)
{
md3_surface_t * md3surface = (struct md3_surface_t *)
malloc(sizeof(struct md3_surface_t));
md3file.seekg(runningTotal, ios::beg);
// it involves evil casting.
md3file.read((char *) md3surface, sizeof (struct md3_surface_t));

totalTriangles += md3surface->num_triangles;
totalVerts += md3surface->num_verts;
runningTotal += md3surface->offset_end;
}
this->totalTrigs = totalTriangles;
this->totalVerts = totalVerts;

runningTotal = md3header->offset_surfaces;

this->g_element_buffer_data = new GLushort[totalTriangles * 3]; // 3 vertices per triangle
this->g_vertex_buffer_data = new GLfloat[totalVerts * 3]; // 3 points per vertex

for(int j = 0; j < md3header->num_surfaces; j++)
{
md3_surface_t * md3surface = (struct md3_surface_t *)
malloc(sizeof(struct md3_surface_t));
md3file.seekg(runningTotal, ios::beg);
// it involves evil casting.
md3file.read((char *) md3surface, sizeof (struct md3_surface_t));

cout << md3surface->indent << endl;
// Get the triangle data.
this->triangles = (md3_triangle_t *)
calloc(md3surface->num_triangles, sizeof (struct md3_triangle_t));
this->num_triangles = md3surface->num_triangles;
md3file.seekg(runningTotal + md3surface->offset_triangles, ios::beg);
md3file.read((char *) triangles, sizeof (struct md3_triangle_t) * md3surface->num_triangles);

//Create index buffer

for( int x = 0; x < md3surface->num_triangles; x++)
{
this->g_element_buffer_data[(a*3)] = triangles[x].indexes[0];
this->g_element_buffer_data[(a*3) + 1] = triangles[x].indexes[1];
this->g_element_buffer_data[(a*3) + 2] = triangles[x].indexes[2];
a++;
}

md3file.seekg(runningTotal + md3surface->offset_xyznormal, ios::beg);

md3_vertex_t * c_vertices = (md3_vertex_t *)
calloc(md3surface->num_verts, sizeof (struct md3_vertex_t));
md3file.read((char *) c_vertices, (sizeof (struct md3_vertex_t)) * md3surface->num_verts);
this->num_vertices = md3surface->num_verts;

// Unpack vertices

for( int x = 0; x < md3surface->num_verts; x++)
{
this->g_vertex_buffer_data[b * 3] = (c_vertices[x].coord[0] * (0.015625));
this->g_vertex_buffer_data[(b*3)+1] = (c_vertices[x].coord[1] * (0.015625));
this->g_vertex_buffer_data[(b*3)+2] = (c_vertices[x].coord[2] * (0.015625));
b++;
}

runningTotal += md3surface->offset_end;

free(c_vertices);
free(md3surface);
free(triangles);
}

md3file.close();
free(md3header);

It's a bit old a C style because I'm modifying an md2 model loader.
I have a feeling this section is wrong not the drawing of the model as everything is supposed to work in the same way as md2.

Should I be putting the vertices for all the surfaces into the same array? How does it know the difference between the what vertex info is for each surface, or does this not matter?

Share this post


Link to post
Share on other sites

This topic is 2584 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.

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