3dsloader.cpp
上传用户:sz83729876
上传日期:2013-03-07
资源大小:4140k
文件大小:7k
源码类别:

OpenGL

开发平台:

Windows_Unix

  1. #include <iostream.h>
  2. #include <fstream>
  3. #include "3dsloader.h"
  4. CLoader3DS::CLoader3DS()
  5. {
  6.     m_pCurrentMesh = NULL;
  7.     m_pCurrentObject = NULL;
  8.     m_pCurrentMaterial = NULL;
  9.     tm = NULL;
  10. }
  11. CLoader3DS::~CLoader3DS()
  12. {
  13. }
  14. bool CLoader3DS::Load( std::string filename, CObject* pObj )
  15. {
  16.     //ifstream    file;
  17.     FILE*       file;
  18.     bool        doneloading = false;
  19.     int         filelength;
  20.     char*       memfile;        // file loaded into memory
  21.     tm = Texture::GetInstance();
  22.     m_pCurrentObject = pObj;
  23.     file = fopen( filename.c_str(), "rb" );
  24.     if (file == NULL)
  25.         return false;
  26.     fseek( file, 0, SEEK_END );
  27.     filelength = ftell( file );
  28.     memfile = new char[ filelength ];
  29.     fseek( file, 0, SEEK_SET );
  30.     fread( memfile, filelength, 1, file );
  31.     // parse it
  32.     EatChunk(memfile);
  33.     delete memfile;
  34.     fclose( file );
  35.     return true;
  36. }
  37. // EatChunk
  38. //
  39. //  This function recursively handles chunks
  40. // in a .3ds file.  When the function exits,
  41. // the return value (i) should be the length
  42. // of the current chunk.  Right now we only
  43. // create one model (the first one listed in
  44. // the file) and read in verts and polys only.
  45. // To grab other info from the file, create
  46. // a new case label in the switch statement
  47. // for the chunk type you want to react to.
  48. //
  49. long CLoader3DS::EatChunk(char* buffer)
  50. {
  51.     unsigned short   chunkid;
  52.     long    chunklength;
  53.     int     i = 0;  // index into current chunk
  54.     int     j;
  55.     char name[128];
  56.     int pos;
  57.     int temp;
  58.     chunkid = *(unsigned short*)(buffer);
  59.     chunklength = *(long*)(buffer+2);
  60.     i = 6;
  61.     switch (chunkid)
  62.     {
  63.     case 0x4D4D:    // main file
  64.         while ((*(unsigned short*)(buffer+i) != 0x3D3D) &&
  65.             (*(unsigned short*)(buffer+i) != 0xB000))
  66.             i += 2;
  67.         break;
  68.     case 0x3D3D:    // editor data
  69.         break;
  70.     case 0x4000:    // object description
  71.         m_pCurrentMesh = new CMesh();
  72.         ZeroMemory( m_pCurrentMesh, sizeof(CMesh) );
  73.         m_pCurrentMesh->m_strName = ( (char*)(buffer+i) );
  74.         m_pCurrentObject->AddMesh( m_pCurrentMesh );
  75.         while (*(buffer+(i++)) != 0); // get past string description
  76.         break;
  77.     case 0x4100:    // triangular polygon list
  78.         break;
  79.     case 0x4110:    // vertex list
  80.         if (m_pCurrentMesh == NULL)
  81.         {
  82.             i = chunklength;
  83.             break;
  84.         }
  85.         if (m_pCurrentMesh->m_dwVertexCount == 0)
  86.         {
  87.             m_pCurrentMesh->m_dwVertexCount = *(unsigned short*)(buffer+i);
  88.             i+=2;
  89.             m_pCurrentMesh->m_pVertices = new CVertex[m_pCurrentMesh->m_dwVertexCount];
  90.             ZeroMemory( m_pCurrentMesh->m_pVertices, m_pCurrentMesh->m_dwVertexCount * sizeof(CVertex) );
  91.             for (j=0;j<m_pCurrentMesh->m_dwVertexCount;j++)
  92.             {
  93.                 m_pCurrentMesh->m_pVertices[j].x = *(float*)(buffer+i);
  94.                 i+=4;
  95.                 m_pCurrentMesh->m_pVertices[j].z = *(float*)(buffer+i);
  96.                 i+=4;
  97.                 m_pCurrentMesh->m_pVertices[j].y = *(float*)(buffer+i);
  98.                 i+=4;
  99.             }
  100.         }
  101.         else
  102.             i = chunklength;
  103.         break;
  104.     case 0x4120:
  105.         if (m_pCurrentMesh == NULL)
  106.         {
  107.             i = chunklength;
  108.             break;
  109.         }
  110.         if (m_pCurrentMesh->m_dwIndexCount == 0)
  111.         {
  112.             m_pCurrentMesh->m_dwIndexCount = *(unsigned short*)(buffer+i);
  113.             m_pCurrentMesh->m_dwIndexCount *= 3;
  114.             i+=2;
  115.             m_pCurrentMesh->m_pIndices = new unsigned short[m_pCurrentMesh->m_dwIndexCount];
  116.             ZeroMemory( m_pCurrentMesh->m_pIndices, m_pCurrentMesh->m_dwIndexCount * sizeof(unsigned short) );
  117.             for (j=0;j<m_pCurrentMesh->m_dwIndexCount/3;j++)
  118.             {
  119.                 m_pCurrentMesh->m_pIndices[ j*3 + 0 ] = *(unsigned short*)(buffer+i);
  120.                 i+=2;
  121.                 m_pCurrentMesh->m_pIndices[ j*3 + 1 ] = *(unsigned short*)(buffer+i);
  122.                 i+=2;
  123.                 m_pCurrentMesh->m_pIndices[ j*3 + 2 ] = *(unsigned short*)(buffer+i);
  124.                 i+=2;
  125.                 i+=2;   // skip face info
  126.             }
  127.         }
  128.         else
  129.             i = chunklength;
  130.         break;
  131.     case 0x4130:
  132.         if (m_pCurrentMesh == NULL)
  133.         {
  134.             i = chunklength;
  135.             break;
  136.         }
  137.         m_pCurrentMesh->m_strMaterialName = (char*)(buffer+i);
  138.         while (*(buffer+(i++)) != 0); // get past string description
  139.         temp = *(short*)(buffer+i);
  140.         i += sizeof(short) * temp;
  141.         break;
  142.     case 0x4140:
  143.         if (m_pCurrentMesh == NULL)
  144.         {
  145.             i = chunklength;
  146.             break;
  147.         }
  148.         if (m_pCurrentMesh->m_dwVertexCount!=0)
  149.         {
  150.             temp = *(short*)(buffer+i);
  151.             i+=2;
  152.             for( int j=0; j<temp; j++ )
  153.             {
  154.                 m_pCurrentMesh->m_pVertices[ j ].tu = *(float*)(buffer+i);
  155.                 i+=4;
  156.                 m_pCurrentMesh->m_pVertices[ j ].tv = *(float*)(buffer+i);
  157.                 i+=4;
  158.                 m_pCurrentMesh->m_pVertices[ j ].tu *= -1.0f;
  159.             }
  160.         }
  161.         else
  162.             i = chunklength;
  163.         break;
  164.     case 0xAFFF:
  165.         m_pCurrentMaterial = new CMaterial();
  166.         m_pCurrentObject->AddMaterial( m_pCurrentMaterial );
  167.         m_pCurrentMaterial->m_fUScale = 1.0f;
  168.         m_pCurrentMaterial->m_fVScale = 1.0f;
  169.         break;
  170.     case 0xA000:
  171.         if (m_pCurrentMaterial==NULL)
  172.         {
  173.             i = chunklength;
  174.             break;
  175.         }
  176.         m_pCurrentMaterial->m_strName = (char*)(buffer+i);
  177.         while (*(buffer+(i++)) != 0); // get past string description
  178.         break;
  179.     case 0xA200:
  180.         if (m_pCurrentMaterial==NULL)
  181.         {
  182.             i = chunklength;
  183.             break;
  184.         }
  185.         m_pCurrentMaterial->m_bHasTexture = true;
  186.         break;
  187.     case 0xA300:
  188.         if (m_pCurrentMaterial==NULL)
  189.         {
  190.             i = chunklength;
  191.             break;
  192.         }
  193.         m_pCurrentMaterial->m_strTextureName = (char*)(buffer+i);
  194.         while (*(buffer+(i++)) != 0); // get past string description
  195.         break;
  196.     case 0xA354:
  197.         if (m_pCurrentMaterial==NULL)
  198.         {
  199.             i = chunklength;
  200.             break;
  201.         }
  202.         m_pCurrentMaterial->m_fVScale = *(float*)(buffer+i);
  203.         i+=4;
  204.         break;
  205.     case 0xA356:
  206.         if (m_pCurrentMaterial==NULL)
  207.         {
  208.             i = chunklength;
  209.             break;
  210.         }
  211.         m_pCurrentMaterial->m_fUScale = *(float*)(buffer+i);
  212.         i+=4;
  213.         break;
  214.     default:
  215.         i = chunklength;    // skips over rest of chunk (ignores it)
  216.         break;
  217.     }
  218.     // eat child chunks
  219.     while (i < chunklength)
  220.         i += EatChunk(buffer+i);
  221.     return chunklength;
  222. }