-
MD2 woes
Iv'e been working on an MD2 loader, based on an implementation from a book I have. It seems to load fine, however its not rendering. I'm not getting any compiler errors or warnings, so I don't really know where the problem may reside. I'll post the loader code, and the rendering code, for those who may want to take a look at it. Thanx in advance.
Md2.cpp
Code:
int loadmd2(obj objectP, char *file)
{
FILE *fileP;
int filelen;
char *filebuffer;
//datamain *model;
header *modelheader;
texcoordindex *stP;
framedata *frame;
vector3d *pointlistP;
mesh *triindex, *bufindexP;
int i, j;
fileP = fopen(file, "rb");
if(fileP == NULL)
MessageBox(hWnd, "File Panic!: Failed to load specified MD2.", "Error", MB_OK);
fseek(fileP, 0, SEEK_END);
filelen = ftell(fileP);
fseek(fileP, 0, SEEK_SET);
filebuffer = (char*)malloc(filelen+1);
fread(filebuffer, sizeof(char), filelen, fileP);
modelheader = (header*)filebuffer;
objectP = (datamain*)malloc(sizeof(datamain));
if(objectP == NULL)
MessageBox(hWnd, "File Panic!: Memory allocation FAILED.", "Error", MB_OK);
objectP->points = (vector3d*)malloc(sizeof(vector3d)*modelheader->numxyz*modelheader->numframes);
objectP->numpoints = modelheader->numxyz;
objectP->numframes = modelheader->numframes;
objectP->framesize = modelheader->framesize;
for(j=0; j<objectP->numframes; j++)
{
frame = (framedata*)&filebuffer[modelheader->offsetframes+modelheader->framesize*j];
pointlistP = (vector3d*)&objectP->points[objectP->numpoints*j];
for(i=0; i<objectP->numpoints; i++)
{
pointlistP[i].v[0] = frame->scale[0]*frame->fp[i].v[0]+frame->translate[0];
pointlistP[i].v[1] = frame->scale[1]*frame->fp[i].v[1]+frame->translate[1];
pointlistP[i].v[2] = frame->scale[2]*frame->fp[i].v[2]+frame->translate[2];
objectP->points[i].v[0] = pointlistP[i].v[0];
objectP->points[i].v[1] = pointlistP[i].v[1];
objectP->points[i].v[2] = pointlistP[i].v[2];
}
}
objectP->st = (texcoord*)malloc(sizeof(texcoord)*modelheader->numst);
objectP->numtexcoords = modelheader->numst;
stP = (texcoordindex*)&filebuffer[modelheader->offsetst];
for(i=0; i<objectP->numtexcoords; i++)
{
objectP->st[i].s = (float)stP[i].s / 256; //temporarly using hardcoded texture size
objectP->st[i].t = (float)stP[i].t / 256;
}
objectP->numtris = modelheader->numtris;
triindex = new mesh [objectP->numtris];
objectP->triindex = triindex;
bufindexP = (mesh*)&filebuffer[modelheader->offsettris];
for(j=0; j<objectP->numframes; j++)
{
for(i=0; i<objectP->numtris; i++)
{
objectP->triindex[i].vertindices[0] = bufindexP[i].vertindices[0];
objectP->triindex[i].vertindices[1] = bufindexP[i].vertindices[1];
objectP->triindex[i].vertindices[2] = bufindexP[i].vertindices[2];
objectP->triindex[i].texcoordindices[0] = bufindexP[i].texcoordindices[0];
objectP->triindex[i].texcoordindices[1] = bufindexP[i].texcoordindices[1];
objectP->triindex[i].texcoordindices[2] = bufindexP[i].texcoordindices[2];
}
}
fclose(fileP);
free(filebuffer);
objectP->currentframe = 0;
objectP->nextframe = 1;
objectP->interpolate = 0.0;
return true;
}
Object.h (most of it, not sure if its even necessary)
Code:
struct header
{
int ident;
int version;
int skinwidth;
int skinheight;
int framesize;
int numskins;
int numxyz;
int numst;
int numtris;
int numglcmds;
int numframes;
int offsetskins;
int offsetst;
int offsettris;
int offsetframes;
int offsetglcmds;
int offsetend;
};
struct texcoord
{
float s, t;
};
struct texcoordindex
{
short s, t;
};
struct framepoint
{
unsigned char v[3];
char normalindex; //unused
};
struct framedata
{
char name[16];
float scale[3];
float translate[3];
framepoint fp[1];
};
struct mesh
{
unsigned short vertindices[3];
unsigned short texcoordindices[3];
};
typedef struct
{
int numframes;
int numpoints;
int numtris;
int numtexcoords;
int framesize;
int texwidth, texheight;
int currentframe;
int nextframe;
float interpolate;
mesh *triindex;
texcoord *st;
vector3d *points;
int id_texture1; // Number of the texture
int type;
vector3d min, max;
float fsize;
float m;
vector3d pos;
vector3d dir;
vector3d v;
matrix_4x4_type matrix; // Object matrix
}datamain, *obj;
........
extern datamain objectP[MAX_OBJECTS];
rendering code
Code:
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB");
for(i = 0; i<num_objects; i++)
{
vector3d *pointlist;
pointlist = &objectP[i].points[objectP[i].numpoints*0];
if(!_peFrustum.CubeInFrustum(objectP[i].pos.x, objectP[i].pos.y, objectP[i].pos.z, objectP[i].fsize))
{
i++; }
glPushMatrix();
glMultMatrixf(&objectP[i].matrix[0][0]);
if (objectP[i].id_texture1!=-1)
{
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, objectP[i].id_texture1); // We set the active texture
}
else {
glDisable(GL_TEXTURE_2D); } // Texture mapping OFF
glBegin(GL_TRIANGLES);
for(j=0; j<objectP[i].numtris; j++)
{
glVertex3fv(pointlist[objectP[i].triindex[j].vertindices[0]].v);
glVertex3fv(pointlist[objectP[i].triindex[j].vertindices[2]].v);
glVertex3fv(pointlist[objectP[i].triindex[j].vertindices[1]].v);
}
glEnd();
glPopMatrix();
}
Ive incorporated it into an object class, so I can load multiple files, with different array id's.
-psychopath
-
I don't see why you get the pointer to the first and second texture pass extensions in the rendering code (it should be done once).
What I'd try:
-Disable the second texture pass, and then enable the first texture pass
-Make sure you are modifying the modelview matrix by setting the matrix mode
-When you disable all texture passes, manually disable the first and second texture passes
-Make sure you have the proper cull mode set.
Code:
void R_CounterClockwiseWinding()
{
gpNTGLAPI->ntglFrontFace(GL_CCW);
}
void R_QuakeCullMode()
{
R_ClockwiseWinding();
gpNTGLAPI->ntglEnable(GL_CULL_FACE);
gpNTGLAPI->ntglCullFace(GL_BACK);
}
Also I'd check the integrity of the loader itself. Unless you're 100% sure you didn't fark up the data, I'd check it. I'd check it by writing vertex coordinates to a data file, and comparing it against known values (perhaps if you have working code you can write its data to a file and examine the proper vertexes values and manually compare the output).
Code:
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB");
for(i = 0; i<num_objects; i++)
{
vector3d *pointlist;
pointlist = &objectP[i].points[objectP[i].numpoints*0];
if(!_peFrustum.CubeInFrustum(objectP[i].pos.x, objectP[i].pos.y, objectP[i].pos.z, objectP[i].fsize))
{
i++; }
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glMultMatrixf(&objectP[i].matrix[0][0]);
if (objectP[i].id_texture1!=-1)
{
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, objectP[i].id_texture1); // We set the active texture
}
else {
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
} // Texture mapping OFF
R_QuakeCullMode()
glBegin(GL_TRIANGLES);
for(j=0; j<objectP[i].numtris; j++)
{
glVertex3fv(pointlist[objectP[i].triindex[j].vertindices[0]].v);
glVertex3fv(pointlist[objectP[i].triindex[j].vertindices[2]].v);
glVertex3fv(pointlist[objectP[i].triindex[j].vertindices[1]].v);
}
glEnd();
glPopMatrix();
}
-
Iv'e tried everything you mentioned, and still nothing. I'm going to try re-writeing the loader with a different approach, and hopefully, I'll get better results.
-psychopath
-
What's the status? I would suggest borrowing loader code from online so you *just* have to worry about getting the rendering code to work. Then, if you are stubborn about having written all code you use, just throw your own loader code back in (and if it doesn't work you know the rendering code works at that point, so you can more easily focus on fixing bugs in the loader).
If you *really* cant get this I might just write the damn thing for you, but I'll require you do some heavy duty testing on one of my own projects in return.
-
If you want you can zip up the project and I'll take a look.
-
I tried a different implementation, and it crashed the program. However, while writing that loader, I discovered what may be the problem. The MD2 is dependant on animation info, which I wasn't loading, because I don't want animation yet. I'm going to try my first implementation again, and do the animation coding as well. If it dosn't work then, I'll probably post the project. It'll probably take me a day or two to finish, because i'm lazy.
-psychopath
-
Well, I still can't get it to work. Chances are its a small problem iv'e overlooked. I've attached only the code relevent to the loader, as uploading the whole project would be pointless. If you can help, i'll be reeeealy greatful, as this has caused me nothing but a headache for the past few days.
-psychopath
-
I was hoping I would be able to build your project and debug it that way. Just looking at code it's often hard to find the bugs, that's why they have debuggers. I'll take a look but I doubt I'll be able to find anything.
If you don't feel comfortable posting your whole project that is understandable. If you want to email it to me or something that's fine or if you just don't want to send it out completely that is fine too.
-
I'm not in a position to post the project to the public, as I havn't worked out a definate license for it yet, as well as the fact that I plan on changing the name, and the last thing I need are two names floating around the internet. I'll prepare it a little (iv'e got unnecessary dlls and data files all over the projects folder, and other leftovers from previous "experiments"), and email it to you.
-psychopath
-
EDIT: nvm, just got your PM.
-psychopath