Original Post
I have created an obj loader for my rendering engine and I am not very satisfied with its performance. I compared it to the loader used by Blender3d and it is only slightly slower. But still, I want to use this to support real time rendering so I need it to be fast. The code is all inside a class, so I will show the functions:
I will greatly appreciate any suggestions that can be given.
Quote:
int objModel::fileLines(char* filename){ int size = 0; string* line = new string; ifstream inData; inData.open(filename); if (!inData) return 0; if (inData.is_open()) { while (!inData.eof()) { getline(inData, *line); size++; } inData.close(); } delete line; return size;}void objModel::numVertNormUVFace(char *filename, int &verts, int &norms, int &UVs, int &faces){ ifstream data; string tmp; data.open(filename); if (data.is_open()) { while (!data.eof()) { getline(data, tmp); if(tmp[0] == 'v' && tmp[1] == ' ') { verts++; } if(tmp[0] == 'v' && tmp[1] == 't') { UVs++; } if(tmp[0] == 'v' && tmp[1] == 'n') { norms++; } if(tmp[0] == 'f' && tmp[1] == ' ') { faces++; } } data.close(); } if (verts < 1) MessageBox(NULL, "Could not read obj file.", filename, MB_ICONERROR);}void objModel::getVert(string line, float &x, float &y, float &z){ string vString[3]; int c = 0; for (int i = 2; i <= line.size(); i++) { if (line == ' ') { c++; } else { vString[c].push_back(line); } } x = (float)atof(vString[0].c_str()); y = (float)atof(vString[1].c_str()); z = (float)atof(vString[2].c_str());}void objModel::getNorm(string line, float &x, float &y, float &z){ string vString[3]; int c = 0; for (int i = 3; i <= line.size(); i++) { if (line == ' ') { c++; } else { vString[c].push_back(line); } } x = (float)atof(vString[0].c_str()); y = (float)atof(vString[1].c_str()); z = (float)atof(vString[2].c_str());}void objModel::getUV(string line, float &x, float &y){ string vString[2]; int c = 0; for (int i = 3; i <= line.size(); i++) { if (line == ' ') { c++; } else { vString[c].push_back(line); } } x = (float)atof(vString[0].c_str()); y = (float)atof(vString[1].c_str());}Face objModel::getFace(string line){ string fString[4]; int c = 0; for (int i = 2; i < line.size(); i++) { if (line == ' ') { c++; } else { fString[c].push_back(line); } } string s1[3][4]; c = 0; for (int x = 0; x < 4; x++) { for (int i = 0; i < fString[x].size(); i++) { if (fString[x].at(i) == '/') { c++; } else { s1[c][x].push_back(fString[x].at(i)); } } c = 0; } Face f; f.v1 = atoi(s1[0][0].c_str()); f.v2 = atoi(s1[0][1].c_str()); f.v3 = atoi(s1[0][2].c_str()); f.v4 = atoi(s1[0][3].c_str()); f.uv1 = atoi(s1[1][0].c_str()); f.uv2 = atoi(s1[1][1].c_str()); f.uv3 = atoi(s1[1][2].c_str()); f.uv4 = atoi(s1[1][3].c_str()); f.n1 = atoi(s1[2][0].c_str()); f.n2 = atoi(s1[2][1].c_str()); f.n3 = atoi(s1[2][2].c_str()); f.n4 = atoi(s1[2][3].c_str()); return f;}bool objModel::Load(char* Filename, int meshType){ t1 = GetTickCount(); hasTexCoords = false; hasNormals = false; MeshType = meshType; filename = Filename; nVerts = nNorms = nUVs = nFaces = 0; string tmp; ifstream file(filename); if (!file) { cout << endl << "could not load " << filename << endl; return false; } numVertNormUVFace(filename, nVerts, nNorms, nUVs, nFaces); cout << "Filename: " << filename << endl; cout << "Verts: " << nVerts << endl; cout << "Norms: " << nNorms << endl; cout << "TexCoord: " << nUVs << endl; cout << "Polygons: " << nFaces<< endl; pVerts = new Vertex[nVerts]; pUVs = new texCoord[nUVs]; pNorms = new Normal[nNorms]; pfaces = new Face[nFaces]; int vLoop = 0; int nLoop = 0; int tLoop = 0; int fLoop = 0; if (file.is_open()) { while (!file.eof()) { getline(file, tmp); if (tmp[0] == 'v' && tmp[1] == ' ') { getVert(tmp, pVerts[vLoop].x, pVerts[vLoop].y, pVerts[vLoop].z); vLoop++; } if (tmp[0] == 'v' && tmp[1] == 'n') { hasNormals = true; getNorm(tmp, pNorms[nLoop].x, pNorms[nLoop].y, pNorms[nLoop].z); nLoop++; } if (tmp[0] == 'v' && tmp[1] == 't') { hasTexCoords = true; getUV(tmp, pUVs[tLoop].U, pUVs[tLoop].V); tLoop++; } if (tmp[0] == 'f' && tmp[1] == ' ') { pfaces[fLoop] = getFace(tmp); fLoop++; } } file.close(); } t2 = GetTickCount(); cout << "ObjLoad: " << (t2-t1)*.001 << "s" << endl; return true;}
I will greatly appreciate any suggestions that can be given.