bool model::Load(char * objfile, char * mtlname) { char buffer[256]; strcpy(filename, objfile); FILE * file = fopen(filename, "r"); strcpy(mtllib, mtlname); if(file == NULL) { MessageBox(NULL, objfile, "Model file not found:", MB_OK); return false; } while(fscanf(file, "%s", buffer) != EOF) { if(!strcmp("#", buffer))skipComment(file); if(!strcmp("mtllib", buffer))loadMaterialLib(file); if(!strcmp("v", buffer))loadVertex(file); if(!strcmp("vt", buffer))loadTexCoord(file); if(!strcmp("vn", buffer))loadNormal(file); if(!strcmp("f", buffer))loadFace(file); if(!strcmp("s", buffer));//fscanf(file, "%s", buffer); if(!strcmp("usemtl", buffer));//useMaterial(file); } fclose(file); loaded = true; return true; }
bool cOBJModel::LoadModel(const char a_fileName[]) { //---------------------------------------------------------------------- // Load a OBJ file and render its data into a display list //---------------------------------------------------------------------- cOBJFileInfo currentIndex; // Current array index char str[CHAI_OBJ_MAX_STR_SIZE]; // Buffer string for reading the file char basePath[_MAX_PATH]; // Path were all paths in the OBJ start int nScanReturn = 0; // Return value of fscanf unsigned int curMaterial = 0; // Current material // Get base path strcpy(basePath, a_fileName); makePath(basePath); //---------------------------------------------------------------------- // Open the OBJ file //---------------------------------------------------------------------- FILE *hFile = fopen(a_fileName, "r"); // Success opening file? if (!hFile) { return (false); } //---------------------------------------------------------------------- // Allocate space for structures that hold the model data //---------------------------------------------------------------------- // Which data types are stored in the file ? How many of each type ? getFileInfo(hFile, &m_OBJInfo, basePath); // Vertices and faces if (m_pVertices) delete [] m_pVertices; if (m_pFaces) delete [] m_pFaces; m_pVertices = new cVector3d[m_OBJInfo.m_vertexCount]; m_pFaces = new cFace[m_OBJInfo.m_faceCount]; // Allocate space for optional model data only if present. if (m_pNormals) { delete [] m_pNormals; m_pNormals = NULL; } if (m_pTexCoords) { delete [] m_pTexCoords; m_pTexCoords = NULL; } if (m_pMaterials) { delete [] m_pMaterials; m_pMaterials = NULL; } if (m_OBJInfo.m_normalCount) m_pNormals = new cVector3d[m_OBJInfo.m_normalCount]; if (m_OBJInfo.m_texCoordCount) m_pTexCoords = new cVector3d[m_OBJInfo.m_texCoordCount]; if (m_OBJInfo.m_materialCount) m_pMaterials = new cMaterialInfo[m_OBJInfo.m_materialCount]; // Init structure that holds the current array index memset(¤tIndex, 0, sizeof(cOBJFileInfo)); //---------------------------------------------------------------------- // Read the file contents //---------------------------------------------------------------------- // Start reading the file from the start rewind(hFile); // Quit reading when end of file has been reached while (!feof(hFile)) { // Get next string readNextString(str, hFile); // Next three elements are floats of a vertex if (!strncmp(str, CHAI_OBJ_VERTEX_ID, sizeof(CHAI_OBJ_VERTEX_ID))) { // Read three floats out of the file float fx, fy, fz; nScanReturn = fscanf(hFile, "%f %f %f", &fx, &fy, &fz); m_pVertices[currentIndex.m_vertexCount].x = fx; m_pVertices[currentIndex.m_vertexCount].y = fy; m_pVertices[currentIndex.m_vertexCount].z = fz; // Next vertex currentIndex.m_vertexCount++; } // Next two elements are floats of a texture coordinate if (!strncmp(str, CHAI_OBJ_TEXCOORD_ID, sizeof(CHAI_OBJ_TEXCOORD_ID))) { // Read two floats out of the file float fx, fy, fz; nScanReturn = fscanf(hFile, "%f %f %f", &fx, &fy, &fz); m_pTexCoords[currentIndex.m_texCoordCount].x = fx; m_pTexCoords[currentIndex.m_texCoordCount].y = fy; m_pTexCoords[currentIndex.m_texCoordCount].z = fz; // Next texture coordinate currentIndex.m_texCoordCount++; } // Next three elements are floats of a vertex normal if (!strncmp(str, CHAI_OBJ_NORMAL_ID, sizeof(CHAI_OBJ_NORMAL_ID))) { // Read three floats out of the file float fx, fy, fz; nScanReturn = fscanf(hFile, "%f %f %f", &fx, &fy, &fz); m_pNormals[currentIndex.m_normalCount].x = fx; m_pNormals[currentIndex.m_normalCount].y = fy; m_pNormals[currentIndex.m_normalCount].z = fz; // Next normal currentIndex.m_normalCount++; } // Rest of the line contains face information if (!strncmp(str, CHAI_OBJ_FACE_ID, sizeof(CHAI_OBJ_FACE_ID))) { // Read the rest of the line (the complete face) getTokenParameter(str, sizeof(str) ,hFile); // Convert string into a face structure parseFaceString(str, &m_pFaces[currentIndex.m_faceCount], m_pVertices, m_pNormals, m_pTexCoords, curMaterial); // Next face currentIndex.m_faceCount++; } // Rest of the line contains face information if (!strncmp(str, CHAI_OBJ_NAME_ID, sizeof(CHAI_OBJ_NAME_ID))) { // Read the rest of the line (the complete face) getTokenParameter(str, sizeof(str) ,hFile); char* name = new char[strlen(str)+1]; strcpy(name,str); m_groupNames.push_back(name); } // Process material information only if needed if (m_pMaterials) { // Rest of the line contains the name of a material if (!strncmp(str, CHAI_OBJ_USE_MTL_ID, sizeof(CHAI_OBJ_USE_MTL_ID))) { // Read the rest of the line (the complete material name) getTokenParameter(str, sizeof(str), hFile); // Are any materials loaded ? if (m_pMaterials) // Find material array index for the material name for (unsigned i=0; i<m_OBJInfo.m_materialCount; i++) if (!strncmp(m_pMaterials[i].m_name, str, sizeof(str))) { curMaterial = i; break; } } // Rest of the line contains the filename of a material library if (!strncmp(str, CHAI_OBJ_MTL_LIB_ID, sizeof(CHAI_OBJ_MTL_LIB_ID))) { // Read the rest of the line (the complete filename) getTokenParameter(str, sizeof(str), hFile); // Append material library filename to the model's base path char libraryFile[_MAX_PATH]; strcpy(libraryFile, basePath); strcat(libraryFile, str); // Append .mtl //strcat(szLibraryFile, ".mtl"); // Load the material library loadMaterialLib(libraryFile, m_pMaterials, ¤tIndex.m_materialCount, basePath); } } } // Close OBJ file fclose(hFile); //---------------------------------------------------------------------- // Success //---------------------------------------------------------------------- return (true); }