Archived

This topic is now archived and is closed to further replies.

Evil Bill

MD2 File Loader

Recommended Posts

I can't get my Quake2 MD2 files to load! I've tried using the GL Command List and just a plain old Triangle List, and in both cases, only about half of the triangles are drawn. I've had success with third-party models, but not with any of the original Quake2 models. Anyone know whats wrong with this code (Sorry for the length)
  
BOOL CMD2Model::Load(LPCSTR szName)
{
CFile theFile;
BYTE* pData;
CTexture* pTexture;
model_t* pHeader;
frame_t* pFrame;
triangle_t* pTriangles;
textureCoordinate_t* pTexCoords;
SRBCommand theCommand;
DWORD i, j;
WORD* pIndices;
STexCoord* pTempTexCoords;
   
   // Open and read file //

   theFile.Open(szName,TRUE);
   pData = theFile.MemoryMap();
   theFile.Close();
   
   // Check Header //

   pHeader = (model_t*)pData;
   
   // Load Skin //

   pTexture = (CTexture*)g_pRender->CreateTexture((char*)(pData+pHeader->offsetSkins));
   Log(INFO,"Loaded Skin %s.\n",(char*)(pData+pHeader->offsetSkins));
   
   // Get Pointers //

   pFrame = (frame_t*)(pData + pHeader->offsetFrames);
   pTriangles = (triangle_t*)(pData + pHeader->offsetTriangles);
   pTexCoords = (textureCoordinate_t*)(pData + pHeader->offsetTexCoords);
   m_dwNumFrames = pHeader->numFrames;
   m_dwNumVerts = pHeader->numTriangles*3;
   
   // Alloc Vertices //

   m_ppVertices = new Vertex*[m_dwNumFrames];
   for(i=0; i<m_dwNumFrames; ++i)
      m_ppVertices[ i ] = new Vertex[m_dwNumVerts];
   
   // Alloc space for vertex indices & texture coords //

   pIndices = new WORD[pHeader->numTriangles*3];
   pTempTexCoords = new STexCoord[pHeader->numTriangles*3];
   
   // Get Vertex Indices and texture coords//

   for(i=0; i<pHeader->numTriangles; ++i)
   {
      pIndices[i*3+0] = pTriangles[ i ].vertexIndices[0];
      pTempTexCoords[i*3+0].u = ((float)pTexCoords[pTriangles[ i ].textureIndices[0]].s)/((float)pTexture->GetOriginalWidth());
      pTempTexCoords[i*3+0].v = ((float)pTexCoords[pTriangles[ i ].textureIndices[0]].t)/((float)pTexture->GetOriginalHeight());
   
      pIndices[i*3+1] = pTriangles[ i ].vertexIndices[1];
      pTempTexCoords[i*3+1].u = ((float)pTexCoords[pTriangles[ i ].textureIndices[1]].s)/((float)pTexture->GetOriginalWidth());
      pTempTexCoords[i*3+1].v = ((float)pTexCoords[pTriangles[ i ].textureIndices[1]].t)/((float)pTexture->GetOriginalHeight());
   
      pIndices[i*3+2] = pTriangles[ i ].vertexIndices[2];
      pTempTexCoords[i*3+2].u = ((float)pTexCoords[pTriangles[ i ].textureIndices[2]].s)/((float)pTexture->GetOriginalWidth());
      pTempTexCoords[i*3+2].v = ((float)pTexCoords[pTriangles[ i ].textureIndices[2]].t)/((float)pTexture->GetOriginalHeight());
   }
   
   // Fill Vertices //

   for(i=0; i<m_dwNumFrames; ++i)
   {
      triangleVertex_t* pVertices = pFrame->vertices;
      for(j=0; j<m_dwNumVerts; ++j)
      {
         m_ppVertices[ i ][j].dwDiffuse = 0xFFFFFFFF;
         m_ppVertices[ i ][j].tu = pTempTexCoords[j].u;
         m_ppVertices[ i ][j].tv = pTempTexCoords[j].v;
         m_ppVertices[ i ][j].vNormal = CVector(0.0f,0.0f,-1.0f);
         m_ppVertices[ i ][j].vPos = CVector(
            pVertices[pIndices[j]].vertex[0]*pFrame->scale[0]+pFrame->translate[0],
            pVertices[pIndices[j]].vertex[2]*pFrame->scale[2]+pFrame->translate[2],
            pVertices[pIndices[j]].vertex[1]*pFrame->scale[1]+pFrame->translate[1]);
      }
      pFrame = (frame_t*)(((BYTE*)pFrame) + pHeader->frameSize);
   }
   DESTROY_A(pTempTexCoords);
   DESTROY_A(pIndices);
   
   // Setup command //

   theCommand.eType = PT_TriangleList;
   theCommand.dwNumPrimitives = pHeader->numTriangles;
   theCommand.dwStartIndex = 0;
   
   // Create Render Buffer //

   m_pBuffer = (CRenderBuffer*)g_pRender->CreateRenderBuffer(FALSE,VT_Vertex,m_ppVertices[0],NULL,&theCommand,m_dwNumVerts,0,1);
   
   // Set Texture //

   if(pTexture)
   {
      m_pBuffer->SetTexture(pTexture);
      pTexture->Release();
   }
   
   // Cleanup //

   Log(INFO,"%s loaded successfully\n",szName);
   delete[] pData;
   return TRUE;
}
  
Ive removed all the error checking since that would double the length of the code. I know my reder buffer class works fine, since ive tried it with just doing a DrawPrimitiveUP and i get the same results. Also, do you think its worth using the GL Commands? If you do, you end up sending at most 12 primitives at a time to DrawPrimitive(), and i remember reading somewhere that you should never send less than 100. Oh, and i've got culling set to D3DCULL_NONE [edit] Theres something odd going on with the code tags... [/edit] Cheers, Steve Steve
DirectX Programmer
Soon to be the new Bill Gates [edited by - Evil Bill on July 18, 2002 11:48:17 AM] [edited by - Evil Bill on July 18, 2002 11:49:26 AM]

Share this post


Link to post
Share on other sites
Hmm... it seems that the Quake 2 models don''t have their triangle information correct. All third party modles render perfectly, if i just render everything as a triangle list.
I still can''t get it workign using the GLCommands though


Steve
DirectX Programmer
Soon to be the new Bill Gates

Share this post


Link to post
Share on other sites