MD2Loader.cpp
上传用户:hkb425
上传日期:2007-06-16
资源大小:34191k
文件大小:11k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. // MD2Loader.cpp: implementation of the CMD2Loader class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include <stdio.h>
  6. #include "MD2Loader.h"
  7. #include "Texture.h"
  8. #include "structDef.h"
  9. //////////////////////////////////////////////
  10. /////////////////////////////////////////
  11. bool CMD2Loader::LoadModel(char* filename)
  12. {
  13. FILE* file;
  14. MD2_HEADER header;
  15. if((file= fopen(filename, "rb"))==NULL)
  16. return false;
  17. fread(&header, sizeof(MD2_HEADER), 1, file);
  18. if(header.magic!= 844121161)
  19. return false;
  20. if(header.version!=8)
  21. return false;
  22. numVertices=header.numVertices;
  23. numFrames  = header.numFrames;
  24. numGlCommands= header.numGlCommands;
  25. frameSize  = header.frameSize;
  26. numTriangles = header.numTriangles;
  27. unsigned char *frames;
  28. frames= new unsigned char[header.frameSize*header.numFrames];
  29. //Check to see if it allocated correctly
  30. if(frames==NULL)
  31. return false;
  32. //Zoom to the correct spot in the file
  33. fseek(file, header.offsetFrames, SEEK_SET);
  34. fread(frames, header.frameSize*header.numFrames*sizeof(char),1, file);
  35. pVertexData=new MD2_MODELVERTEX[numVertices*numFrames];
  36. if(pVertexData ==NULL)return false;
  37.     pTempFrame =new MD2_TEMPVERTEX [numVertices];
  38. if(pTempFrame ==NULL)return false;
  39.     for(int i=0;i<numFrames;i++)
  40. {
  41. MD2_FRAME *currentFrame= (MD2_FRAME*) (frames+frameSize*i);
  42. for(int j=0;j<numVertices;j++)
  43. {
  44.             pVertexData[i*numVertices+j].x=currentFrame->vertices[j].vertex[0]* 
  45.            currentFrame->scale[0]+ 
  46.            currentFrame->translate[0];
  47.             pVertexData[i*numVertices+j].z=currentFrame->vertices[j].vertex[1]* 
  48.            currentFrame->scale[1]+ 
  49.            currentFrame->translate[1];
  50.             pVertexData[i*numVertices+j].y=currentFrame->vertices[j].vertex[2]* 
  51.                currentFrame->scale[2]+ 
  52.            currentFrame->translate[2];
  53.             pVertexData[i*numVertices+j].x=-pVertexData[i*numVertices+j].x*scale;
  54.             pVertexData[i*numVertices+j].y=(pVertexData[i*numVertices+j].y)*scale;
  55.             pVertexData[i*numVertices+j].z=pVertexData[i*numVertices+j].z*scale;
  56.             pVertexData[i*numVertices+j].normalIndex=currentFrame->vertices[j].lightNormalIndex;
  57. }
  58. }
  59. delete [] frames;
  60. //Create space for the GL command information (whether or not to use tri strips, or tri fans)
  61. glCommands= new long [header.numGlCommands];
  62. //Check to see if it allocated correctly
  63. if(glCommands==NULL)
  64. return false;
  65. //Zoom to the correct spot in the file
  66. fseek(file,   header.offsetGlCommands, SEEK_SET);
  67. fread(glCommands, header.numGlCommands, sizeof(long), file);
  68. //Move the important information from the header, to the permanent class info.
  69. //Close 'da friggin file mon
  70. fclose(file);
  71. return true;
  72. }
  73. bool CMD2Loader::LoadTexture(char *filename)
  74. {
  75.     CTexture cTexture;
  76. if(!cTexture.MakeTextureBind(filename,&textureID))return false;
  77. return true;
  78. }
  79. bool CMD2Loader::InitMd2Loader(char* Model,char* Texture,float nscale)
  80. {
  81. scale=nscale;
  82. if(Model==NULL || Texture==NULL)return false;
  83. if(!LoadModel(Model))return false;
  84. if(!LoadTexture(Texture))return false;
  85.     PreProcess();
  86. return true;
  87. }
  88. void CMD2Loader::PreProcess()
  89.     for(int i=0;i<numVertices;i++)
  90. {
  91. if(pVertexData[i].x>m_boundary.maxx)m_boundary.maxx=pVertexData[i].x;
  92. if(pVertexData[i].x<m_boundary.minx)m_boundary.minx=pVertexData[i].x;
  93. if(pVertexData[i].y>m_boundary.maxy)m_boundary.maxy=pVertexData[i].y;
  94. if(pVertexData[i].y<m_boundary.miny)m_boundary.miny=pVertexData[i].y;
  95. if(pVertexData[i].z>m_boundary.maxz)m_boundary.maxz=pVertexData[i].z;
  96. if(pVertexData[i].z<m_boundary.minz)m_boundary.minz=pVertexData[i].z;
  97. }
  98. }
  99. //------------------------------------------------------------------//
  100. //- void Render(int) -----------------------------------------------//
  101. //------------------------------------------------------------------//
  102. //- Description: This function renders an .md2 model with the given-//
  103. //-  frame of animation.    -//
  104. //------------------------------------------------------------------//
  105. //- Ok, now I really owe Justin a big one for this... His code     -//
  106. //- seems to be the only one that took advantage of the gl commands-//
  107. //- that are within the md2 file (for speed)!    -//
  108. //------------------------------------------------------------------//
  109. void CMD2Loader::RenderOneFrame(int numFrame)
  110. if(numFrame>(numFrames-1))numFrame=0;
  111.     MD2_MODELVERTEX *pCurFrame=pVertexData+numFrame*numVertices;
  112. long* command;
  113. int vertIndex;
  114. int type;
  115. int numVertex;
  116.     //Get the current frame and gl command information
  117. command = glCommands;
  118. //////////////////////////////////////////////
  119.     glBindTexture(GL_TEXTURE_2D, textureID);
  120.     glEnable(GL_TEXTURE_2D);
  121. glCullFace(GL_FRONT);
  122. //Make sure that the command doesn't equal 0, and if it doesn't lets start rendering!
  123. while((*command)!=0)
  124. {
  125. if(*command>0) //This is a triangle strip
  126. {
  127. numVertex= *command; 
  128. command++; 
  129. type= 0;
  130. }
  131. else //This is a triangle fan
  132. {
  133. numVertex= - *command; 
  134. command++; 
  135. type= 1;
  136. }
  137. if(numVertex<0)
  138. numVertex= -numVertex;
  139. //Fill the vertex list information
  140. for(int loop=0; loop<numVertex; loop++)
  141. {
  142.             pTempFrame[loop].texcoord[0]=*((float*)command); 
  143. command++;
  144.             pTempFrame[loop].texcoord[1]=*((float*)command); 
  145. command++;
  146. vertIndex= *command; 
  147. command++;
  148. pTempFrame[loop].vertex[0]=pCurFrame[vertIndex].x;
  149. pTempFrame[loop].vertex[1]=pCurFrame[vertIndex].y;
  150. pTempFrame[loop].vertex[2]=pCurFrame[vertIndex].z;
  151. pTempFrame[loop].normalIndex=pCurFrame[vertIndex].normalIndex; 
  152. }
  153. //If the .md2 was optimized for use with triangle strips...
  154. if(type==0)
  155. {
  156. glBegin(GL_TRIANGLE_STRIP);
  157. for(loop=0; loop<numVertex; loop++)
  158. {
  159. glNormal3fv(&m_MD2Normal.m_pMD2Normal[pTempFrame[loop].normalIndex]);
  160.      glTexCoord2fv(pTempFrame[loop].texcoord);
  161. glVertex3fv(pTempFrame[loop].vertex);
  162. }
  163. glEnd();
  164. }
  165. //If the .md2 was made for use with triangle fans...
  166. else
  167. {
  168. glBegin(GL_TRIANGLE_FAN);
  169. for(loop=0; loop<numVertex; loop++)
  170. {
  171. glNormal3fv(&m_MD2Normal.m_pMD2Normal[pTempFrame[loop].normalIndex]);
  172.      glTexCoord2fv(pTempFrame[loop].texcoord);
  173. glVertex3fv(pTempFrame[loop].vertex);
  174. }
  175. glEnd();
  176. }
  177. }
  178.      glCullFace(GL_BACK);
  179. }
  180. //------------------------------------------------------------------//
  181. //- void Animate(int, int, float) ----------------------------------//
  182. //------------------------------------------------------------------//
  183. //- Description: This function animates a model from the start     -//
  184. //-  frame, to the end frame, with the speed that you  -//
  185. //-  give (in percent).    -//
  186. //------------------------------------------------------------------//
  187. //- I got the idea for this one from Dave Astle and Kevin Hawkins  -//
  188. //- (two really cool guys), but I had to implement the code in it  -//
  189. //- myself!    -//
  190. //------------------------------------------------------------------//
  191. void CMD2Loader::Animate(int startFrame,int endFrame,float interpolation)
  192. {
  193.     //////////////////////////////////////////////////////
  194. long* command;
  195. int vertIndex;
  196. int type;
  197. int numVertex;
  198.     startPointer=pVertexData+startFrame*numVertices;
  199.     endPointer=pVertexData+endFrame*numVertices;
  200.     //Get the current frame and gl command information
  201. command = glCommands;
  202. //////////////////////////////////////////////
  203.     glBindTexture(GL_TEXTURE_2D, textureID);
  204. glEnable(GL_TEXTURE_2D);
  205.     glCullFace(GL_FRONT);
  206. //Make sure that the command doesn't equal 0, and if it doesn't lets start rendering!
  207. while((*command)!=0)
  208. {
  209. if(*command>0) //This is a triangle strip
  210. {
  211. numVertex= *command; 
  212. command++; 
  213. type= 0;
  214. }
  215. else //This is a triangle fan
  216. {
  217. numVertex= - *command; 
  218. command++; 
  219. type= 1;
  220. }
  221. if(numVertex<0)
  222. numVertex= -numVertex;
  223. //Fill the vertex list information
  224. for(int loop=0; loop<numVertex; loop++)
  225. {
  226.             pTempFrame[loop].texcoord[0]=*((float*)command); 
  227. command++;
  228.             pTempFrame[loop].texcoord[1]=*((float*)command); 
  229. command++;
  230. vertIndex= *command; 
  231. command++;
  232. pTempFrame[loop].vertex[0]=(1-interpolation)*startPointer[vertIndex].x+
  233.                           interpolation*endPointer[vertIndex].x;
  234. pTempFrame[loop].vertex[1]=(1-interpolation)*startPointer[vertIndex].y+
  235.                           interpolation*endPointer[vertIndex].y;
  236. pTempFrame[loop].vertex[2]=(1-interpolation)*startPointer[vertIndex].z+
  237.                           interpolation*endPointer[vertIndex].z;
  238. pTempFrame[loop].normalIndex=startPointer[vertIndex].normalIndex; 
  239. }
  240. //If the .md2 was optimized for use with triangle strips...
  241. if(type==0)
  242. {
  243. glBegin(GL_TRIANGLE_STRIP);
  244. for(loop=0; loop<numVertex; loop++)
  245. {
  246. glNormal3fv(&m_MD2Normal.m_pMD2Normal[pTempFrame[loop].normalIndex]);
  247.      glTexCoord2fv(pTempFrame[loop].texcoord);
  248. glVertex3fv(pTempFrame[loop].vertex);
  249. }
  250. glEnd();
  251. }
  252. //If the .md2 was made for use with triangle fans...
  253. else
  254. {
  255. glBegin(GL_TRIANGLE_FAN);
  256. for(loop=0; loop<numVertex; loop++)
  257. {
  258. glNormal3fv(&m_MD2Normal.m_pMD2Normal[pTempFrame[loop].normalIndex]);
  259.      glTexCoord2fv(pTempFrame[loop].texcoord);
  260. glVertex3fv(pTempFrame[loop].vertex);
  261. }
  262. glEnd();
  263. }
  264. }
  265.      glCullFace(GL_BACK);
  266. //  DrawMD2Boundary();
  267. }
  268. void CMD2Loader::DrawMD2Boundary()
  269. {
  270. glDisable(GL_TEXTURE_2D);
  271. glColor3f(1,1,1);
  272. glBegin(GL_LINE_STRIP);
  273.     glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.minz);
  274.     glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.minz);
  275.     glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.maxz);
  276.     glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.maxz);
  277.     glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.minz);
  278.     glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.minz);
  279.     glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.minz);
  280.     glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.maxz);
  281.     glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.maxz);
  282.     glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.minz);
  283. glEnd();
  284. glBegin(GL_LINES);
  285.     glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.minz);
  286.     glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.minz);
  287.     glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.maxz);
  288.     glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.maxz);
  289.     glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.maxz);
  290.     glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.maxz);
  291. glEnd();
  292. glColor3f(1,1,1);
  293. }