⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3ds.cpp

📁 S.C.O.U.R.G.E.是一款类似Rogue的游戏
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//***********************************************************************////                                                                       ////      - "Talk to me like I'm a 3 year old!" Programming Lessons -      ////                                                                       ////      $Author:        DigiBen     digiben@gametutorials.com            ////                                                                       ////      $Program:       3DS Loader                                       ////                                                                       ////      $Description:   Demonstrates how to load a .3ds file format      ////                                                                       ////      $Date:          10/6/01                                          ////                                                                       ////***********************************************************************//# include <math.h>#include "3ds.h"// This file handles all of the code needed to load a .3DS file.// Basically, how it works is, you load a chunk, then you check// the chunk ID.  Depending on the chunk ID, you load the information// that is stored in that chunk.  If you do not want to read that information,// you read past it.  You know how many bytes to read past the chunk because// every chunk stores the length in bytes of that chunk.///////////////////////////////// CLOAD3DS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*//////////   This constructor initializes the tChunk data////////////////////////////////////// CLOAD3DS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*CLoad3DS::CLoad3DS(){    m_CurrentChunk = new tChunk;                // Initialize and allocate our current chunk    m_TempChunk = new tChunk;                   // Initialize and allocate a temporary chunk}///////////////////////////////// IMPORT 3DS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*//////////   This is called by the client to open the .3ds file, read it, then clean up////////////////////////////////////// IMPORT 3DS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*bool CLoad3DS::Import3DS(t3DModel *pModel, char *strFileName){    char strMessage[255] = {0};	pModel->numOfMaterials = pModel->numOfObjects = 0;    // Open the 3DS file    m_FilePointer = fopen(strFileName, "rb");    // Make sure we have a valid file pointer (we found the file)    if(!m_FilePointer)     {        sprintf(strMessage, "Unable to find the file: %s!", strFileName);        cout << strMessage << endl;        exit(1);    }    // Once we have the file open, we need to read the very first data chunk    // to see if it's a 3DS file.  That way we don't read an invalid file.    // If it is a 3DS file, then the first chunk ID will be equal to PRIMARY (some hex num)    // Read the first chuck of the file to see if it's a 3DS file    ReadChunk(m_CurrentChunk);    // Make sure this is a 3DS file    if (m_CurrentChunk->ID != PRIMARY)    {        sprintf(strMessage, "Unable to load PRIMARY chuck from file: %s!", strFileName);        cout << strMessage << endl;        exit(1);    }    // Now we actually start reading in the data.  ProcessNextChunk() is recursive    // Begin loading objects, by calling this recursive function    ProcessNextChunk(pModel, m_CurrentChunk);    // After we have read the whole 3DS file, we want to calculate our own vertex normals.    ComputeNormals(pModel);    // Clean up after everything    CleanUp();    return true;}///////////////////////////////// CLEAN UP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*//////////   This function cleans up our allocated memory and closes the file////////////////////////////////////// CLEAN UP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void CLoad3DS::CleanUp(){    fclose(m_FilePointer);                      // Close the current file pointer    delete m_CurrentChunk;                      // Free the current chunk    delete m_TempChunk;                         // Free our temporary chunk}///////////////////////////////// PROCESS NEXT CHUNK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*//////////   This function reads the main sections of the .3DS file, then dives deeper with recursion////////////////////////////////////// PROCESS NEXT CHUNK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void CLoad3DS::ProcessNextChunk(t3DModel *pModel, tChunk *pPreviousChunk){    t3DObject newObject = {0};                  // This is used to add to our object list    tMaterialInfo newTexture = {0};             // This is used to add to our material list    unsigned int version = 0;                   // This will hold the file version    int buffer[50000] = {0};                    // This is used to read past unwanted data    m_CurrentChunk = new tChunk;                // Allocate a new chunk                 // Below we check our chunk ID each time we read a new chunk.  Then, if    // we want to extract the information from that chunk, we do so.    // If we don't want a chunk, we just read past it.      // Continue to read the sub chunks until we have reached the length.    // After we read ANYTHING we add the bytes read to the chunk and then check    // check against the length.	//int count = 0;    while (pPreviousChunk->bytesRead < pPreviousChunk->length)    {	  //	  if(count++ > 20) exit(1);        // Read next Chunk        ReadChunk(m_CurrentChunk);        // Check the chunk ID        switch (m_CurrentChunk->ID)        {        case VERSION:                           // This holds the version of the file            // This chunk has an unsigned short that holds the file version.            // Since there might be new additions to the 3DS file format in 4.0,            // we give a warning to that problem.            // Read the file version and add the bytes read to our bytesRead variable            m_CurrentChunk->bytesRead += fread(&version, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);			if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {			  version = SDL_SwapLE32(version);			}            // If the file version is over 3, give a warning that there could be a problem            if (version > 0x03)                cout << "This 3DS file is over version 3 so it may load incorrectly" << endl;            break;        case OBJECTINFO:                        // This holds the version of the mesh            // This chunk holds the version of the mesh.  It is also the head of the MATERIAL            // and OBJECT chunks.  From here on we start reading in the material and object info.            // Read the next chunk            ReadChunk(m_TempChunk);            // Get the version of the mesh            m_TempChunk->bytesRead += fread(&version, 1, m_TempChunk->length - m_TempChunk->bytesRead, m_FilePointer);			if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {			  version = SDL_SwapLE32(version);			}            // Increase the bytesRead by the bytes read from the last chunk            m_CurrentChunk->bytesRead += m_TempChunk->bytesRead;            // Go to the next chunk, which is the object has a texture, it should be MATERIAL, then OBJECT.            ProcessNextChunk(pModel, m_CurrentChunk);            break;        case MATERIAL:                          // This holds the material information            // This chunk is the header for the material info chunks            // Increase the number of materials            pModel->numOfMaterials++;            // Add a empty texture structure to our texture list.            // If you are unfamiliar with STL's "vector" class, all push_back()            // does is add a new node onto the list.  I used the vector class            // so I didn't need to write my own link list functions.              pModel->pMaterials.push_back(newTexture);            // Proceed to the material loading function            ProcessNextMaterialChunk(pModel, m_CurrentChunk);            break;        case OBJECT:                            // This holds the name of the object being read            // This chunk is the header for the object info chunks.  It also            // holds the name of the object.            // Increase the object count            pModel->numOfObjects++;            // Add a new tObject node to our list of objects (like a link list)            pModel->pObject.push_back(newObject);                        // Initialize the object and all it's data members            memset(&(pModel->pObject[pModel->numOfObjects - 1]), 0, sizeof(t3DObject));            // Get the name of the object and store it, then add the read bytes to our byte counter.            m_CurrentChunk->bytesRead += GetString(pModel->pObject[pModel->numOfObjects - 1].strName);                        // Now proceed to read in the rest of the object information            ProcessNextObjectChunk(pModel, &(pModel->pObject[pModel->numOfObjects - 1]), m_CurrentChunk);            break;        case EDITKEYFRAME:            // Because I wanted to make this a SIMPLE tutorial as possible, I did not include            // the key frame information.  This chunk is the header for all the animation info.            // In a later tutorial this will be the subject and explained thoroughly.            //ProcessNextKeyFrameChunk(pModel, m_CurrentChunk);            // Read past this chunk and add the bytes read to the byte counter            m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);            break;        default:             // If we didn't care about a chunk, then we get here.  We still need            // to read past the unknown or ignored chunk and add the bytes read to the byte counter.            m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);            break;        }        // Add the bytes read from the last chunk to the previous chunk passed in.        pPreviousChunk->bytesRead += m_CurrentChunk->bytesRead;    }    // Free the current chunk and set it back to the previous chunk (since it started that way)    delete m_CurrentChunk;    m_CurrentChunk = pPreviousChunk;}///////////////////////////////// PROCESS NEXT OBJECT CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*//////////   This function handles all the information about the objects in the file////////////////////////////////////// PROCESS NEXT OBJECT CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void CLoad3DS::ProcessNextObjectChunk(t3DModel *pModel, t3DObject *pObject, tChunk *pPreviousChunk){    int buffer[50000] = {0};                    // This is used to read past unwanted data    // Allocate a new chunk to work with    m_CurrentChunk = new tChunk;    // Continue to read these chunks until we read the end of this sub chunk    while (pPreviousChunk->bytesRead < pPreviousChunk->length)    {        // Read the next chunk        ReadChunk(m_CurrentChunk);        // Check which chunk we just read        switch (m_CurrentChunk->ID)        {        case OBJECT_MESH:                   // This lets us know that we are reading a new object                    // We found a new object, so let's read in it's info using recursion            ProcessNextObjectChunk(pModel, pObject, m_CurrentChunk);            break;        case OBJECT_VERTICES:               // This is the objects vertices            ReadVertices(pObject, m_CurrentChunk);            break;        case OBJECT_FACES:                  // This is the objects face information            ReadVertexIndices(pObject, m_CurrentChunk);            break;        case OBJECT_MATERIAL:               // This holds the material name that the object has            

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -