MD2Loader.cpp
上传用户:hkb425
上传日期:2007-06-16
资源大小:34191k
文件大小:11k
- // MD2Loader.cpp: implementation of the CMD2Loader class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include <stdio.h>
- #include "MD2Loader.h"
- #include "Texture.h"
- #include "structDef.h"
- //////////////////////////////////////////////
- /////////////////////////////////////////
- bool CMD2Loader::LoadModel(char* filename)
- {
- FILE* file;
- MD2_HEADER header;
- if((file= fopen(filename, "rb"))==NULL)
- return false;
- fread(&header, sizeof(MD2_HEADER), 1, file);
- if(header.magic!= 844121161)
- return false;
- if(header.version!=8)
- return false;
- numVertices=header.numVertices;
- numFrames = header.numFrames;
- numGlCommands= header.numGlCommands;
- frameSize = header.frameSize;
- numTriangles = header.numTriangles;
- unsigned char *frames;
- frames= new unsigned char[header.frameSize*header.numFrames];
- //Check to see if it allocated correctly
- if(frames==NULL)
- return false;
- //Zoom to the correct spot in the file
- fseek(file, header.offsetFrames, SEEK_SET);
- fread(frames, header.frameSize*header.numFrames*sizeof(char),1, file);
- pVertexData=new MD2_MODELVERTEX[numVertices*numFrames];
- if(pVertexData ==NULL)return false;
- pTempFrame =new MD2_TEMPVERTEX [numVertices];
- if(pTempFrame ==NULL)return false;
-
- for(int i=0;i<numFrames;i++)
- {
- MD2_FRAME *currentFrame= (MD2_FRAME*) (frames+frameSize*i);
- for(int j=0;j<numVertices;j++)
- {
- pVertexData[i*numVertices+j].x=currentFrame->vertices[j].vertex[0]*
- currentFrame->scale[0]+
- currentFrame->translate[0];
- pVertexData[i*numVertices+j].z=currentFrame->vertices[j].vertex[1]*
- currentFrame->scale[1]+
- currentFrame->translate[1];
- pVertexData[i*numVertices+j].y=currentFrame->vertices[j].vertex[2]*
- currentFrame->scale[2]+
- currentFrame->translate[2];
- pVertexData[i*numVertices+j].x=-pVertexData[i*numVertices+j].x*scale;
- pVertexData[i*numVertices+j].y=(pVertexData[i*numVertices+j].y)*scale;
- pVertexData[i*numVertices+j].z=pVertexData[i*numVertices+j].z*scale;
- pVertexData[i*numVertices+j].normalIndex=currentFrame->vertices[j].lightNormalIndex;
- }
- }
- delete [] frames;
- //Create space for the GL command information (whether or not to use tri strips, or tri fans)
- glCommands= new long [header.numGlCommands];
- //Check to see if it allocated correctly
- if(glCommands==NULL)
- return false;
- //Zoom to the correct spot in the file
- fseek(file, header.offsetGlCommands, SEEK_SET);
- fread(glCommands, header.numGlCommands, sizeof(long), file);
- //Move the important information from the header, to the permanent class info.
- //Close 'da friggin file mon
- fclose(file);
- return true;
- }
- bool CMD2Loader::LoadTexture(char *filename)
- {
- CTexture cTexture;
- if(!cTexture.MakeTextureBind(filename,&textureID))return false;
- return true;
- }
- bool CMD2Loader::InitMd2Loader(char* Model,char* Texture,float nscale)
- {
- scale=nscale;
- if(Model==NULL || Texture==NULL)return false;
- if(!LoadModel(Model))return false;
- if(!LoadTexture(Texture))return false;
- PreProcess();
- return true;
- }
- void CMD2Loader::PreProcess()
- {
- for(int i=0;i<numVertices;i++)
- {
- if(pVertexData[i].x>m_boundary.maxx)m_boundary.maxx=pVertexData[i].x;
- if(pVertexData[i].x<m_boundary.minx)m_boundary.minx=pVertexData[i].x;
- if(pVertexData[i].y>m_boundary.maxy)m_boundary.maxy=pVertexData[i].y;
- if(pVertexData[i].y<m_boundary.miny)m_boundary.miny=pVertexData[i].y;
- if(pVertexData[i].z>m_boundary.maxz)m_boundary.maxz=pVertexData[i].z;
- if(pVertexData[i].z<m_boundary.minz)m_boundary.minz=pVertexData[i].z;
- }
- }
- //------------------------------------------------------------------//
- //- void Render(int) -----------------------------------------------//
- //------------------------------------------------------------------//
- //- Description: This function renders an .md2 model with the given-//
- //- frame of animation. -//
- //------------------------------------------------------------------//
- //- Ok, now I really owe Justin a big one for this... His code -//
- //- seems to be the only one that took advantage of the gl commands-//
- //- that are within the md2 file (for speed)! -//
- //------------------------------------------------------------------//
- void CMD2Loader::RenderOneFrame(int numFrame)
- {
- if(numFrame>(numFrames-1))numFrame=0;
- MD2_MODELVERTEX *pCurFrame=pVertexData+numFrame*numVertices;
- long* command;
- int vertIndex;
- int type;
- int numVertex;
- //Get the current frame and gl command information
- command = glCommands;
- //////////////////////////////////////////////
- glBindTexture(GL_TEXTURE_2D, textureID);
- glEnable(GL_TEXTURE_2D);
- glCullFace(GL_FRONT);
- //Make sure that the command doesn't equal 0, and if it doesn't lets start rendering!
- while((*command)!=0)
- {
- if(*command>0) //This is a triangle strip
- {
- numVertex= *command;
- command++;
- type= 0;
- }
- else //This is a triangle fan
- {
- numVertex= - *command;
- command++;
- type= 1;
- }
- if(numVertex<0)
- numVertex= -numVertex;
- //Fill the vertex list information
- for(int loop=0; loop<numVertex; loop++)
- {
- pTempFrame[loop].texcoord[0]=*((float*)command);
- command++;
- pTempFrame[loop].texcoord[1]=*((float*)command);
- command++;
- vertIndex= *command;
- command++;
- pTempFrame[loop].vertex[0]=pCurFrame[vertIndex].x;
- pTempFrame[loop].vertex[1]=pCurFrame[vertIndex].y;
- pTempFrame[loop].vertex[2]=pCurFrame[vertIndex].z;
- pTempFrame[loop].normalIndex=pCurFrame[vertIndex].normalIndex;
- }
- //If the .md2 was optimized for use with triangle strips...
- if(type==0)
- {
- glBegin(GL_TRIANGLE_STRIP);
- for(loop=0; loop<numVertex; loop++)
- {
- glNormal3fv(&m_MD2Normal.m_pMD2Normal[pTempFrame[loop].normalIndex]);
- glTexCoord2fv(pTempFrame[loop].texcoord);
- glVertex3fv(pTempFrame[loop].vertex);
- }
- glEnd();
- }
- //If the .md2 was made for use with triangle fans...
- else
- {
- glBegin(GL_TRIANGLE_FAN);
- for(loop=0; loop<numVertex; loop++)
- {
- glNormal3fv(&m_MD2Normal.m_pMD2Normal[pTempFrame[loop].normalIndex]);
- glTexCoord2fv(pTempFrame[loop].texcoord);
- glVertex3fv(pTempFrame[loop].vertex);
- }
- glEnd();
- }
- }
- glCullFace(GL_BACK);
- }
- //------------------------------------------------------------------//
- //- void Animate(int, int, float) ----------------------------------//
- //------------------------------------------------------------------//
- //- Description: This function animates a model from the start -//
- //- frame, to the end frame, with the speed that you -//
- //- give (in percent). -//
- //------------------------------------------------------------------//
- //- I got the idea for this one from Dave Astle and Kevin Hawkins -//
- //- (two really cool guys), but I had to implement the code in it -//
- //- myself! -//
- //------------------------------------------------------------------//
- void CMD2Loader::Animate(int startFrame,int endFrame,float interpolation)
- {
- //////////////////////////////////////////////////////
- long* command;
- int vertIndex;
- int type;
- int numVertex;
- startPointer=pVertexData+startFrame*numVertices;
- endPointer=pVertexData+endFrame*numVertices;
- //Get the current frame and gl command information
- command = glCommands;
- //////////////////////////////////////////////
- glBindTexture(GL_TEXTURE_2D, textureID);
- glEnable(GL_TEXTURE_2D);
- glCullFace(GL_FRONT);
- //Make sure that the command doesn't equal 0, and if it doesn't lets start rendering!
- while((*command)!=0)
- {
- if(*command>0) //This is a triangle strip
- {
- numVertex= *command;
- command++;
- type= 0;
- }
- else //This is a triangle fan
- {
- numVertex= - *command;
- command++;
- type= 1;
- }
- if(numVertex<0)
- numVertex= -numVertex;
- //Fill the vertex list information
- for(int loop=0; loop<numVertex; loop++)
- {
- pTempFrame[loop].texcoord[0]=*((float*)command);
- command++;
- pTempFrame[loop].texcoord[1]=*((float*)command);
- command++;
- vertIndex= *command;
- command++;
- pTempFrame[loop].vertex[0]=(1-interpolation)*startPointer[vertIndex].x+
- interpolation*endPointer[vertIndex].x;
- pTempFrame[loop].vertex[1]=(1-interpolation)*startPointer[vertIndex].y+
- interpolation*endPointer[vertIndex].y;
- pTempFrame[loop].vertex[2]=(1-interpolation)*startPointer[vertIndex].z+
- interpolation*endPointer[vertIndex].z;
- pTempFrame[loop].normalIndex=startPointer[vertIndex].normalIndex;
- }
- //If the .md2 was optimized for use with triangle strips...
- if(type==0)
- {
- glBegin(GL_TRIANGLE_STRIP);
- for(loop=0; loop<numVertex; loop++)
- {
- glNormal3fv(&m_MD2Normal.m_pMD2Normal[pTempFrame[loop].normalIndex]);
- glTexCoord2fv(pTempFrame[loop].texcoord);
- glVertex3fv(pTempFrame[loop].vertex);
- }
- glEnd();
- }
- //If the .md2 was made for use with triangle fans...
- else
- {
- glBegin(GL_TRIANGLE_FAN);
- for(loop=0; loop<numVertex; loop++)
- {
- glNormal3fv(&m_MD2Normal.m_pMD2Normal[pTempFrame[loop].normalIndex]);
- glTexCoord2fv(pTempFrame[loop].texcoord);
- glVertex3fv(pTempFrame[loop].vertex);
- }
- glEnd();
- }
- }
- glCullFace(GL_BACK);
- // DrawMD2Boundary();
- }
- void CMD2Loader::DrawMD2Boundary()
- {
- glDisable(GL_TEXTURE_2D);
- glColor3f(1,1,1);
- glBegin(GL_LINE_STRIP);
- glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.minz);
- glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.minz);
- glEnd();
- glBegin(GL_LINES);
- glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.maxz);
- glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.maxz);
- glEnd();
- glColor3f(1,1,1);
- }