Thread: MD2 woes

  1. #1
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071

    Question 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
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  2. #2

    Join Date
    May 2005
    Posts
    1,042
    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();
    	}
    Last edited by BobMcGee123; 06-29-2005 at 03:12 PM.
    I'm not immature, I'm refined in the opposite direction.

  3. #3
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    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
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  4. #4

    Join Date
    May 2005
    Posts
    1,042
    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.
    Last edited by BobMcGee123; 07-01-2005 at 02:57 PM.
    I'm not immature, I'm refined in the opposite direction.

  5. #5
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    If you want you can zip up the project and I'll take a look.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  6. #6
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    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
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  7. #7
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    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
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  8. #8
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    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.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  9. #9
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    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
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  10. #10
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    EDIT: nvm, just got your PM.

    -psychopath
    Last edited by psychopath; 07-02-2005 at 07:48 PM.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problems with MD2 file format
    By scwizzo in forum Game Programming
    Replies: 3
    Last Post: 12-27-2008, 10:11 PM
  2. loading md2 files in opeGL
    By avgprogamerjoe in forum Game Programming
    Replies: 0
    Last Post: 10-01-2007, 08:02 PM
  3. md2 models and directx
    By confuted in forum Game Programming
    Replies: 2
    Last Post: 08-09-2003, 01:29 PM
  4. What are the differences between MD2 and MD3 format?
    By Shadow12345 in forum Game Programming
    Replies: 1
    Last Post: 10-17-2002, 01:34 PM
  5. Setting up for md2
    By Ruski in forum Game Programming
    Replies: 10
    Last Post: 08-13-2002, 01:54 AM