📄 3ds.cpp
字号:
// This chunk holds the name of the material that the object has assigned to it. // This could either be just a color or a texture map. This chunk also holds // the faces that the texture is assigned to (In the case that there is multiple // textures assigned to one object, or it just has a texture on a part of the object. // Since most of my game objects just have the texture around the whole object, and // they aren't multitextured, I just want the material name. // We now will read the name of the material assigned to this object ReadObjectMaterial(pModel, pObject, m_CurrentChunk); break; case OBJECT_UV: // This holds the UV texture coordinates for the object // This chunk holds all of the UV coordinates for our object. Let's read them in. ReadUVCoordinates(pObject, m_CurrentChunk); break; default: // Read past the ignored or unknown chunks 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 MATERIAL CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*////////// This function handles all the information about the material (Texture)////////////////////////////////////// PROCESS NEXT MATERIAL CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void CLoad3DS::ProcessNextMaterialChunk(t3DModel *pModel, 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 in switch (m_CurrentChunk->ID) { case MATNAME: // This chunk holds the name of the material // Here we read in the material name m_CurrentChunk->bytesRead += fread(pModel->pMaterials[pModel->numOfMaterials - 1].strName, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer); break; case MATDIFFUSE: // This holds the R G B color of our object ReadColorChunk(&(pModel->pMaterials[pModel->numOfMaterials - 1]), m_CurrentChunk); break; case MATMAP: // This is the header for the texture info // Proceed to read in the material information ProcessNextMaterialChunk(pModel, m_CurrentChunk); break; case MATMAPFILE: // This stores the file name of the material // Here we read in the material's file name m_CurrentChunk->bytesRead += fread(pModel->pMaterials[pModel->numOfMaterials - 1].strFile, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer); break; default: // Read past the ignored or unknown chunks 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;}///////////////////////////////// READ CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*////////// This function reads in a chunk ID and it's length in bytes////////////////////////////////////// READ CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void CLoad3DS::ReadChunk(tChunk *pChunk){ // This reads the chunk ID which is 2 bytes. // The chunk ID is like OBJECT or MATERIAL. It tells what data is // able to be read in within the chunks section. pChunk->bytesRead = fread(&pChunk->ID, 1, 2, m_FilePointer); if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { pChunk->ID = SDL_SwapLE16(pChunk->ID); } // Then, we read the length of the chunk which is 4 bytes. // This is how we know how much to read in, or read past. pChunk->bytesRead += fread(&pChunk->length, 1, 4, m_FilePointer); if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { pChunk->length = SDL_SwapLE32(pChunk->length); }}///////////////////////////////// GET STRING \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*////////// This function reads in a string of characters////////////////////////////////////// GET STRING \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*int CLoad3DS::GetString(char *pBuffer){ int index = 0; // Read 1 byte of data which is the first letter of the string fread(pBuffer, 1, 1, m_FilePointer); // Loop until we get NULL while (*(pBuffer + index++) != 0) { // Read in a character at a time until we hit NULL. fread(pBuffer + index, 1, 1, m_FilePointer); } // Return the string length, which is how many bytes we read in (including the NULL) return strlen(pBuffer) + 1;}///////////////////////////////// READ COLOR \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*////////// This function reads in the RGB color data////////////////////////////////////// READ COLOR \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void CLoad3DS::ReadColorChunk(tMaterialInfo *pMaterial, tChunk *pChunk){ // Read the color chunk info ReadChunk(m_TempChunk); // Read in the R G B color (3 bytes - 0 through 255) m_TempChunk->bytesRead += fread(pMaterial->color, 1, m_TempChunk->length - m_TempChunk->bytesRead, m_FilePointer); // Add the bytes read to our chunk pChunk->bytesRead += m_TempChunk->bytesRead;}///////////////////////////////// READ VERTEX INDECES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*////////// This function reads in the indices for the vertex array////////////////////////////////////// READ VERTEX INDECES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void CLoad3DS::ReadVertexIndices(t3DObject *pObject, tChunk *pPreviousChunk){ unsigned short index = 0; // This is used to read in the current face index // In order to read in the vertex indices for the object, we need to first // read in the number of them, then read them in. Remember, // we only want 3 of the 4 values read in for each face. The fourth is // a visibility flag for 3D Studio Max that doesn't mean anything to us. // Read in the number of faces that are in this object (int) pPreviousChunk->bytesRead += fread(&pObject->numOfFaces, 1, 2, m_FilePointer); if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { pObject->numOfFaces = SDL_SwapLE32(pObject->numOfFaces); } // Alloc enough memory for the faces and initialize the structure pObject->pFaces = new tFace [pObject->numOfFaces]; memset(pObject->pFaces, 0, sizeof(tFace) * pObject->numOfFaces); // Go through all of the faces in this object for(int i = 0; i < pObject->numOfFaces; i++) { // Next, we read in the A then B then C index for the face, but ignore the 4th value. // The fourth value is a visibility flag for 3D Studio Max, we don't care about this. for(int j = 0; j < 4; j++) { // Read the first vertice index for the current face pPreviousChunk->bytesRead += fread(&index, 1, sizeof(index), m_FilePointer); if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { index = SDL_SwapLE16(index); } if(j < 3) { // Store the index in our face structure. pObject->pFaces[i].vertIndex[j] = index; } } }}///////////////////////////////// READ UV COORDINATES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*////////// This function reads in the UV coordinates for the object////////////////////////////////////// READ UV COORDINATES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void CLoad3DS::ReadUVCoordinates(t3DObject *pObject, tChunk *pPreviousChunk){ // In order to read in the UV indices for the object, we need to first // read in the amount there are, then read them in. // Read in the number of UV coordinates there are (int) pPreviousChunk->bytesRead += fread(&pObject->numTexVertex, 1, 2, m_FilePointer); if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { pObject->numTexVertex = SDL_SwapLE32(pObject->numTexVertex); } // Allocate memory to hold the UV coordinates pObject->pTexVerts = new CVector2 [pObject->numTexVertex]; // Read in the texture coodinates (an array 2 float) pPreviousChunk->bytesRead += fread(pObject->pTexVerts, 1, pPreviousChunk->length - pPreviousChunk->bytesRead, m_FilePointer); if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { for(int i = 0; i < pObject->numTexVertex; i++) { /* Note: byteswapping floats works on my powerbook, but I think this may cause problems in the future. Floats and doubles aren't as easy to change from LE to BE as ints. */ float f; BSWAPF(pObject->pTexVerts[i].x, f); pObject->pTexVerts[i].x = f; BSWAPF(pObject->pTexVerts[i].y, f); pObject->pTexVerts[i].y = f; } } }///////////////////////////////// READ VERTICES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*////////// This function reads in the vertices for the object////////////////////////////////////// READ VERTICES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void CLoad3DS::ReadVertices(t3DObject *pObject, tChunk *pPreviousChunk){ // Like most chunks, before we read in the actual vertices, we need // to find out how many there are to read in. Once we have that number // we then fread() them into our vertice array. // Read in the number of vertices (int) pPreviousChunk->bytesRead += fread(&(pObject->numOfVerts), 1, 2, m_FilePointer); if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { pObject->numOfVerts = SDL_SwapLE32(pObject->numOfVerts); } // Allocate the memory for the verts and initialize the structure pObject->pVerts = new CVector3 [pObject->numOfVerts]; memset(pObject->pVerts, 0, sizeof(CVector3) * pObject->numOfVerts);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -